为什么要使用证书
安全超文本傳輸協議(HTTPS)是超文本傳輸協議(HTTP)的擴展。它用於在計算機網絡上進行安全通信,並在Internet上廣泛使用。
HTTPS 通过 SSL/TLS 的附加加密層來保護流量. 只要使用了足夠的密碼套件,並且已驗證並信任服務器證書,就可以確保對竊聽者和中間人攻擊的合理保護。
僅當以下所有條件均成立時,用戶才應信任與網站的HTTPS連接:
- 用戶相信瀏覽器軟件可以使用正確的預安裝證書頒發機構正確實施HTTPS。
- 用戶信任證書頒發機構僅擔保合法網站。
- 該網站提供了有效的證書,這意味著它是由受信任的機構簽名的。
- 證書正確標識了網站(例如,當瀏覽器訪問“ https://example.com ”時,接收到的證書適用於“ example.com”,而不是其他某些實體)。
- 用戶相信協議的加密層(SSL / TLS)足以防止竊聽。
因此, 为了保护流量的安全, 必须要使用到证书.
如何选择证书颁发机构
证书颁发机构包括 Let’s Encrypt,Digicert,Sectigo,GoDaddy 和 GlobalSign 等. 一般来说, 我们只要选择一个资历深且无黑历史的机构即可.
我选择的是 Let’s Encrypt, 以下示范也是使用这一机构的证书作为演示.
Let’s Encrypt由網際網路安全研究小組(縮寫ISRG)提供服務。主要贊助商包括電子前哨基金會、Mozilla基金會、Akamai以及思科。2015年4月9日,ISRG與Linux基金會宣布合作。
acme.sh获取Let’s Encrypt证书
准备工作
执行以下命令,acme.sh 会安装到 ~/.acme.sh 目录下。
$ curl https://get.acme.sh | sh
安装成功后执行 source ~/.bashrc
以确保脚本所设置的命令别名生效。
如果安装报错,那么可能是因为系统缺少 acme.sh 所需要的依赖项,acme.sh 的依赖项主要是 socat,我们通过以下命令来安装这些依赖项,然后重新安装一遍 acme.sh:
$ sudo apt-get install openssl cron socat curl
生成证书
证书有两种,一种是 ECC 证书(内置公钥是 ECDSA 公钥),一种是 RSA 证书(内置 RSA 公钥)。简单来说,同等长度 ECC 比 RSA 更安全,也就是说在具有同样安全性的情况下,ECC 的密钥长度比 RSA 短得多(加密解密会更快)。但问题是 ECC 的兼容性会差一些,Android 4.x 以下和 Windows XP 不支持。只要您的设备不是非常老的老古董,建议使用 ECC 证书。推荐阅读: 为什么你应该用ECDSA椭圆曲线数字签名算法生成证书
acme.sh 支持的所有验证协议. 常见的生成证书方式有 webroot, standalone, DNS, Nginx/Apache 模式. 本文针对的是有网页服务的读者, 因此选用 webroot 模式. 其他方式详见: acme.sh - How to issue a cert
webroot 模式生成证书
ECC 证书
$ acme.sh --issue -d dolorhunter.com -d www.dolorhunter.com --webroot /home/wwwroot/mydomain.com/ --keylength ec-256
RSA 证书
$ acme.sh --issue -d dolorhunter.com -d www.dolorhunter.com --webroot /home/wwwroot/mydomain.com/
注1: -d 后的域名为你的域名. 如果有很多域名, 中间使用 -d 相隔.
注2: /home/wwwroot/mydomain.com/ 对应网页根目录(即 Nginx root 参数后的内容). 如果你使用的是 Jekyll, 记得目录为 ~/_site 例: /home/dolorhunter.github.io/_site/
*注3: 默认证书为 2048 位的 RSA 证书. 可选追加参数 –keylength 表示密钥长度,后面的值可以是 ec-256 、ec-384、2048、3072、4096、8192,带有 ec 表示生成的是 ECC 证书,没有则是 RSA 证书。在安全性上 256 位的 ECC 证书等同于 3072 位的 RSA 证书。
安装证书
acme.sh签发的证书存放在~/.acme.sh/下,但是我们不能直接使用证书,在使用之前还必须安装证书。
ECC 证书
acme.sh --install-cert -d mydomain.com --ecc \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/in/nginx/cert.pem \
--ca-file /path/to/cafile/in/nginx/ca.pem \
--reloadcmd "service nginx force-reload"
RSA 证书
acme.sh --install-cert -d mydomain.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/in/nginx/cert.pem \
--ca-file /path/to/cafile/in/nginx/ca.pem \
--reloadcmd "service nginx force-reload"
注1: path/to/*/in/nginx/ 为你存放证书的目录
注2: key 和 fullchain 分别是私钥和公钥, 为 SSL/TLS 所必须的. ca 是 OCSP Stapling 的凭证, 可以增加访客的连接速度和隐私性. 参考 Scott Helme - OCSP Stapling; SSL with added speed and privacy
其他证书
上一步提到的 ca 证书(凭证) 可以作为 OCSP Stapling 的证书增加访客的连接速度和隐私性.
dhparam (迪菲·赫爾曼)证书, 可以防止 TLS 1.2 的中间人攻击. 如果你有使用 TLS 1.2 协议, 建议添加这个证书.
$ openssl dhparam -out /path/to/dhparam/in/nginx/dhparam.pem 2048
证书自动更新
目前证书在 60 天以后会自动更新, 你无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 你不用关心.
当然你也可以手动更新:
$ sudo ~/.acme.sh/acme.sh --renew -d mydomain.com -d www.mydomain.com --force
注: 如果使用的是 ECC 算法的证书, 需要添加 –ecc
修改 Nginx 配置并启用 SSL
我们参考 Mozilla - SSL config , 生成你的 SSL 配置. SSL config 可以生成支持不同框架, 不同环境, 不同版本的配置文件, 参考性强.
在这里拿使用的比较多的 Nginx 举例:
# (可选)http 强制跳转 https
#server {
# listen 80 default_server;
# listen [::]:80 default_server;
#
# return 301 https://$host$request_uri;
#}
server {
listen 443 ssl http2;
listen [::]:443 ssl http2;
ssl_certificate /path/to/signed_cert_plus_intermediates; # 对应安装证书中 fullchain-file 即 cert.pem
ssl_certificate_key /path/to/private_key; # 对应安装证书中 key-file 即 key.pem
ssl_session_timeout 1d;
ssl_session_cache shared:MozSSL:10m; # about 40000 sessions
ssl_session_tickets off;
# # (可选)迪菲·赫爾曼证书, 可以防止 TLS 1.2 的中间人攻击
# # curl https://ssl-config.mozilla.org/ffdhe2048.txt > /path/to/dhparam.pem
# ssl_dhparam /path/to/dhparam.pem; # 对应其他证书中 dhparam.pem
# intermediate configuration
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off;
# # (可选)HSTS 更好的安全性, 测试拿 A+ 必要条件
# # HSTS (ngx_http_headers_module is required) (63072000 seconds)
# add_header Strict-Transport-Security "max-age=63072000" always;
# # (可选)OCSP stapling 增加访客的连接速度和隐私性
# ssl_stapling on;
# ssl_stapling_verify on;
# # verify chain of trust of OCSP response using Root CA and Intermediate certs
# ssl_trusted_certificate /path/to/root_CA_cert_plus_intermediates; # 对应安装证书中 ca-file 即 ca.pem
# # replace with the IP address of your resolver
# resolver 8.8.8.8;
}
注: 以上注释掉的部分均为可选配置. 请依照网站实际需求配置.
验证 SSL
完成以上步骤之后, 访问 ssllabs - ssltest 检测你的域名, 看看是否一切正常.
如果你有跟着我的步骤做, 那么测试的结果至少是 A.
参考资料: