阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

基于OpenSSL自建CA和颁发SSL证书

219次阅读
没有评论

共计 6137 个字符,预计需要花费 16 分钟才能阅读完成。

关于 SSL/TLS 介绍见文章 SSL/TLS 原理详解。
关于证书授权中心 CA 以及数字证书等概念,请移步 OpenSSL 与 SSL 数字证书概念贴。

openssl 是一个开源程序的套件、这个套件有三个部分组成:一是libcryto,这是一个具有通用功能的加密库,里面实现了众多的加密库;二是libssl,这个是实现 ssl 机制的,它是用于实现 TLS/SSL 的功能;三是 openssl,是个多功能命令行工具,它可以实现加密解密,甚至还可以当 CA 来用,可以让你创建证书、吊销证书。

默认情况 Ubuntu 和 CentOS 上都已安装好 openssl。CentOS 6.x 上有关 ssl 证书的目录结构:

1
2

3
4
5

6
7
8
9
10
11
/etc/pki/CA/
newcerts 存放 CA 签署(颁发)过的数字证书(证书备份目录)
private 用于存放 CA 的私钥
crl 吊销的证书

/etc/pki/tls/
cert.pem 软链接到 certs/ca-bundle.crt
certs/ 该服务器上的证书存放目录,可以房子自己的证书和内置证书
ca-bundle.crt 内置信任的证书
private 证书密钥存放目录
openssl.cnf openssl 的 CA 主配置文件

 

1. 颁发证书

1.1 修改 CA 的一些配置文件

CA 要给别人颁发证书,首先自己得有一个作为根证书,我们得在一切工作之前修改好 CA 的配置文件、序列号、索引等等。

vi /etc/pki/tls/openssl.cnf

1
2

3
4
5

6
7
8
9
10
11

12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
...
[CA_default]

dir = /etc/pki/CA # Where everything is kept
certs = $dir/certs # Where the issued certs are kept
crl_dir = $dir/crl # Where the issued crl are kept
database = $dir/index.txt # database index file.
#unique_subject = no # Set to 'no' to allow creation of
# several ctificates with same subject.
new_certs_dir = $dir/newcerts # default place for new certs.

certificate = $dir/cacert.pem # The CA certificate
serial = $dir/serial # The current serial number
crlnumber = $dir/crlnumber # the current crl number
# must be commented out to leave a V1 CRL
crl = $dir/crl.pem # The current CRL
private_key = $dir/private/cakey.pem # The private key
RANDFILE = $dir/private/.rand # private random number file
...
default_days = 3650 # how long to certify for
...
# For the CA policy
[policy_match]
countryName = match
stateOrProvinceName = optional
localityName = optional
organizationName = optional
organizationalUnitName = optional
commonName = supplied
emailAddress = optional
...
[req_distinguished_name]
countryName = Country Name (2 letter code)
countryName_default = CN
countryName_min = 2
countryName_max = 2

stateOrProvinceName = State or Province Name (full name)
stateOrProvinceName_default = GD
...
[req_distinguished_name] 部分主要是颁证时一些默认的值,可以不动

 

一定要注意 [policy_match] 中的设定的匹配规则,是有可能因为证书使用的工具不一样,导致即使设置了 csr 中看起来有相同的 countryName,stateOrProvinceName 等,但在最终生成证书时依然报错:

1
2

3
4
5
Using configuration from /usr/lib/ssl/openssl.cnf
Check that the request matches the signature
Signature ok
The stateOrProvinceName field needed to be the same in the
CA certificate (GuangDong) and the request (GuangDong)

 

touch index.txt serial
在 CA 目录下创建两个初始文件:

1
2
# touch index.txt serial
# echo 01 > serial

 

1.2 生成根密钥

1
2
# cd /etc/pki/CA/
# openssl genrsa -out private/cakey.pem 2048

为了安全起见,修改 cakey.pem 私钥文件权限为 600 或 400,也可以使用子 shell 生成(umask 077; openssl genrsa -out private/cakey.pem 2048),下面不再重复。

1.3 生成根证书

使用 req 命令生成自签证书:

1
# openssl req -new -x509 -key private/cakey.pem -out cacert.pem

 

会提示输入一些内容,因为是私有的,所以可以随便输入(之前修改的 openssl.cnf 会在这里呈现),最好记住能与后面保持一致。上面的自签证书 cacert.pem 应该生成在 /etc/pki/CA 下。

1.4 为我们的 nginx web 服务器生成 ssl 密钥

以上都是在 CA 服务器上做的操作,而且只需进行一次��现在转到 nginx 服务器上执行:

1
2
# cd /etc/nginx/ssl
# openssl genrsa -out nginx.key 2048

 

这里测试的时候 CA 中心与要申请证书的服务器是同一个。

1.5 为 nginx 生成证书签署请求

1
2

3
4
5

6
7
8
9
10
11

12
13
14
15
# openssl req -new -key nginx.key -out nginx.csr
...
Country Name (2 letter code) [AU]:CN
State or Province Name (full name) [Some-State]:GD
Locality Name (eg, city) []:SZ
Organization Name (eg, company) [Internet Widgits Pty Ltd]:COMPANY
Organizational Unit Name (eg, section) []:IT_SECTION
Common Name (e.g. server FQDN or YOUR name) []:your.domain.com
Email Address []:

Please enter the following 'extra' attributes
to be sent with your certificate request
A challenge password []:
An optional company name []:
...

同样会提示输入一些内容,其它随便,除了 Commone Name 一定要是你要授予证书的服务器域名或主机名,challenge password 不填。

1.6 私有 CA 根据请求来签署证书

接下来要把上一步生成的证书请求 csr 文件,发到 CA 服务器上,在 CA 上执行:

1
2

3
4
# openssl ca -in nginx.csr -out nginx.crt

另外在极少数情况下,上面的命令生成的证书不能识别,试试下面的命令:
# openssl x509 -req -in server.csr -CA /etc/pki/CA/cacert.pem -CAkey /etc/pki/CA/private/cakey.pem -CAcreateserial -out server.crt

 

上面签发过程其实默认使用了 -cert cacert.pem -keyfile cakey.pem,这两个文件就是前两步生成的位于/etc/pki/CA 下的根密钥和根证书。将生成的 crt 证书发回 nginx 服务器使用。

到此我们已经拥有了建立 ssl 安全连接所需要的所有文件,并且服务器的 crt 和 key 都位于配置的目录下,剩下的是如何使用证书的问题。

2. 使用 ssl 证书

2.1 一般浏览器

浏览器作为客户端去访问 https 加密的服务器,一般不用去手动做其他设置,如https://www.google.com.hk,这是因为 Chrome、FireFox、Safari、IE 等浏览器已经内置了大部分常用的 CA 的根证书,但自建 CA 的根证书就不再浏览器的信任列表中,访问时会提示如下:
IE 浏览器
基于 OpenSSL 自建 CA 和颁发 SSL 证书

谷歌浏览器
基于 OpenSSL 自建 CA 和颁发 SSL 证书

安装网站证书后(同时也有信任的根证书),地址栏一般会显示绿色小锁
基于 OpenSSL 自建 CA 和颁发 SSL 证书

证书信息
基于 OpenSSL 自建 CA 和颁发 SSL 证书

导入证书到浏览器的方法:http://cnzhx.net/blog/self-signed-certificate-as-trusted-root-ca-in-windows/

2.2 为 linux 系统添加根证书

这一步不是必须的,一般出现在开发测试环境中,而且具体的应用程序应该提供添加证书的方法。

curl工具可以在 linux 上模拟发送请求,但当它去访问 https 加密网站时就会提示如下信息:

1
2

3
4
5

6
7
8
9
10
11

12
13
# curl https://sean:sean@registry.domain.com:8000/
curl: (60) Peer certificate cannot be authenticated with known CA certificates
More details here: http://curl.haxx.se/docs/sslcerts.html
curl performs SSL certificate verification by default, using a "bundle"
of Certificate Authority (CA) public keys (CA certs). If the default
bundle file isn't adequate, you can specify an alternate file
using the --cacert option.
If this HTTPS server uses a certificate signed by a CA represented in
the bundle, the certificate verification probably failed due to a
problem with the certificate (it might be expired, or the name might
not match the domain name in the URL).
If you'd like to turn off curl's verification of the certificate, use
the -k (or --insecure) option.

 

提示上面的信息说明 curl 在 linux 的证书信任集里没有找到根证书,你可以使用 curl --insecure 来不验证证书的可靠性,这只能保证数据是加密传输的但无法保证对方是我们要访问的服务。使用 curl --cacert cacert.pem 可以手动指定根证书路径。我们也可以把根证书添加到系统(CentOS 5,6)默认的 bundle:

1
2

3
4
5
# cp /etc/pki/tls/certs/ca-bundle.crt{,.bak}    备份以防出错
# cat /etc/pki/CA/cacert.pem >> /etc/pki/tls/certs/ca-bundle.crt

# curl https://sean:sean@registry.domain.com:8000
"docker-registry server (dev) (v0.8.1)"

 

2.3 nginx

在 nginx 配置文件(可能是/etc/nginx/sites-available/default)的 server 指令下添加:

1
2

3
ssl on;
ssl_certificate /etc/nginx/ssl/nginx.crt;
ssl_certificate_key /etc/nginx/ssl/nginx.key;

同时注意 server_name 与证书申请时的 Common Name 要相同,打开 443 端口。当然关于 web 服务器加密还有其他配置内容,如只对部分 URL 加密,对 URL 重定向实现强制 https 访问,请参考其他资料。

3 关于证书申请

注意,如果对于一般的应用,管理员只需生成“证书请求”(后缀大多为.csr),它包含你的名字和公钥,然后把这份请求交给诸如 verisign 等有 CA 服务公司(当然,连同几百美金),你的证书请求经验证后,CA 用它的私钥签名,形成正式的证书发还给你。管理员再在 web server 上导入这个证书就行了。如果你不想花那笔钱,或者想了解一下原理,可以自己做 CA。从 ca 的角度讲,你需要 CA 的私钥和公钥。从想要证书的服务器角度将,需要把服务器的证书请求交给 CA。

如果你要自己做 CA,别忘了客户端需要导入 CA 的证书(CA 的证书是自签名的,导入它意味着你“信任”这个 CA 签署的证书)。而商业 CA 的一般不用,因为它们已经内置在你的浏览器中了。

更多 OpenSSL 相关内容可以查看以下的有用链接

使用 OpenSSL 命令行构建 CA 及证书  http://www.linuxidc.com/Linux/2015-10/124682.htm

Ubuntu 安装 OpenSSL  http://www.linuxidc.com/Linux/2015-10/124001.htm

通过 OpenSSL 提供 FTP+SSL/TLS 认证功能,并实现安全数据传输 http://www.linuxidc.com/Linux/2013-05/84986.htm

Linux 下使用 OpenSSL 生成证书 http://www.linuxidc.com/Linux/2015-05/117034.htm

利用 OpenSSL 签署多域名证书 http://www.linuxidc.com/Linux/2014-10/108222.htm

在 OpenSSL 中添加自定义加密算法  http://www.linuxidc.com/Linux/2015-08/121749.htm

OpenSSL 的详细介绍:请点这里
OpenSSL 的下载地址
:请点这里

本文永久更新链接地址:http://www.linuxidc.com/Linux/2016-05/131146.htm

正文完
星哥玩云-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计6137字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中