Skip to main content

使用Let's Encrypt不花钱打造A+级SSL站点

· 6 min read

有这样一个组织为了推动整个互联网环境的安全,免费提供跟你网站域名匹配的并且被各大浏览器信任的 SSL 证书,这个组织的名称叫做 ISRG -- Internet Security Research Group,ISGR 提供了一个服务叫 Let's Encrypt (https://letsencrypt.org),网民们可以方便的使用该网站免费创建属于自己的 SSL 证书。并且 ISGR 允许免费创建泛域名 SSL 证书。

下面就来说说怎样使用 Let's Encrypt 提供的服务免费创建泛域名证书。

假设场景:

  • 小张注册了一个域名:example.com
  • 小张想建一个网站,域名为 www.example.com 和 example.com
  • 小张又想建一个博客,域名为 blog.example.com
  • 小张又想建一个论坛,域名为 forum.example.com
  • 以上网址都以 HTTPS 的方式访问
  • 环境: CentOS 7 + Nginx 1.13
  • 工具: openssl, https://www.sslforfree.com

一个支持多域名的证书可以满足上述需求,该证书需要绑定两个域名 example.com 和*.example.com, 下面详表过程:

一、创建 Private Key(私钥)

关系到数据安装的一个 Key, 千万不能泄漏。使用 openssl 生成 2048 位私钥,输出文件名为 example.com.key:

# openssl genrsa -out example.com.key 2048

二、为绑定多域名创建配置文件

从/etc/pki/tls/openssl.cnf 复制一个文件 example.com.cnf

# cp /etc/pki/tls/openssl.cnf example.com.cnf

修改 example.com.cnf:

1. 找到[ req ]节中被注释掉的 req_extensions = v3_req,去除行首的#使其生效,或添加对应内容:

[ req ]
...
req_extensions = v3_req # The extensions to add to a certificate request
...

2. 找到[ v3_req ]节添加 subjectAltName,内容如下:

[ v3_req ]
subjectAltName = @alt_names

3. 添加[ alt_names ]小节,并在下面添加 DNS.1 和 DNS.2 分别等天 example.com 和*.example.com:

[ alt_names ]
DNS.1 = example.com
DNS.2 = *.example.com

保存退出编辑器。

三、使用 openssl 创建 CSR (Certificate Signing Request)文件

使用前面步骤创建的 Private Key 和 cnf 文件作为输入参数,生成 CSR, 过程中需要填写证书申请的相关信息,包括国家代码,州省,城市,证书所属组织名称,证书显示名称等,按向导依次填即可:

# openssl req -new -key example.com.key -out example.com.csr -config example.com.cnf
You are about to be asked to enter information that will be incorporated
into your certificate request.
What you are about to enter is what is called a Distinguished Name or a DN.
There are quite a few fields but you can leave some blank
For some fields there will be a default value,
If you enter '.', the field will be left blank.
-----
Country Name (2 letter code) [XX]:CN
State or Province Name (full name) []:Guangdong
Locality Name (eg, city) [Default City]:Shenzhen
Organization Name (eg, company) [Default Company Ltd]:
Organizational Unit Name (eg, section) []: Thomas
Common Name (eg, your name or your server's hostname) []:example.com
Email Address []:

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

还有一种更快捷的方法是在 cnf 文件中把所有内容填好,在向导中就只需要按回车就好了:

查验 Request 文件:

# openssl req -in example.com.csr -noout -text

四、访问 sslforfree.com,生成证书:

1. 在浏览器中输入网址:https://www.sslforfree.com, 然后在 sslforfree 的网站的域名输入框中输入 example.com *.example.com,点击 Create Free SSL Certificate 按钮继续:

2. 然后 sslforfree 网站会提示你需要验证该域名是否为你所有,点击 Manually Verify Domain 按钮继续:

3. 你需要根据网站给出的值,在你的域名注册商那里添加两个 TXT 记录,添加完成等该记录生效后,勾选 I Have My Own CSR 复选框,把前面使用 openssl 创建的 CSR 文件的内容粘贴到下面的文本框里,然后点击 Download SSL Certificate 按钮

如果 TXT 记录校验通过,ssoforfree 网站就会显示出颁发的证书内容了。你可以从文本框中复制 PEM 格式的证书内容,也可以直接点击下载包含证书文件的 ZIP 包。

注意,如果 CSR 文件是你自己提供的,那么下载的 ZIP 包中是不包含你的 Private Key 的,你需要保存好你之前使用 openssl 生成的 Private Key 文件。

五、在 nginx 中配置 SSL 证书

1. 生成 dhparam 文件:

# openssl dhparam -out dhparam.pem 2048

2. 把完整证书链保存在一个文件中

sslforfree 网站提供的证书的证书路径如下:

如果要想你的网站证书能受到信任并兼容所有设备(如 Android 设备上的浏览器),必须要把你的证书和根证书所有颁发机构的证书放在一个文件中,提供给客户端下载。从 sslforfree 下载的 ZIP 包中有 ca-bundle.crt 和 certificate.crt, 把这两个文件的内容粘贴到一个文件中。把 certificate.crt 文件中的内容放前面,ca-bundle.crt 中的内容放后面。根据我们的假设的例子,文件另存为 example.com.pem。示例内容如下:

-----BEGIN CERTIFICATE-----
[example.com证书内容]
-----END CERTIFICATE-----
-----BEGIN CERTIFICATE-----
[ca_bundle.crt证书链内容]
-----END CERTIFICATE-----

2. 在 nginx.conf 中添加 ssl 配置,包括 HTTP Header: Strict-Transport-Security, 指定 ssl_certificate, ssl_certificate_key,ssl_dhparam, 支持的协议:TLSv1 TLSv1.1 TLSv1.2 等,如下所示:

server {
listen 443 ssl;
server_name example.com www.example.com blog.example.com forum.example.com;

add_header Strict-Transport-Security max-age=31536000;
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;

ssl on;
ssl_certificate /etc/ssl/example.com.pem;
ssl_certificate_key /etc/example.com.key;

ssl_prefer_server_ciphers on;
ssl_dhparam /etc/ssl/dhparam.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers "EECDH+ECDSA+AESGCM EECDH+aRSA+AESGCM EECDH+ECDSA+SHA384 EECDH+ECDSA+SHA256 EECDH+aRSA+SHA384 EECDH+aRSA+SHA256 EECDH+aRSA+RC4 EECDH EDH+aRSA !aNULL !eNULL !LOW !3DES !MD5 !EXP !PSK !SRP !DSS !RC4";
keepalive_timeout 70;
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 10m;

配置完成让 nginx reload 配置文件,访问网站就可以看到期待的锁图标及“安全”标识了。

六、安全检测

打开网站https://myssl.com/输入你的网址检测一下,看是不是达到的A+级安全标准:).

参考:

https://easyengine.io/wordpress-nginx/tutorials/ssl/multidomain-ssl-subject-alternative-names

ClustrMaps