使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书
至于 ACME 协议是什么?Automatic Certificate Management Environment 自动化证书管理环境,通过它我们可以实现证书的自动申请以及部署,可以大大的节省人员的管理及额外的配置工作。
ACME 的通信过程通过一系列的 API 进行,你可以通过类似 https://example.com/directory 获取可以请求的 API 列表,如 Letsencrypt。当然再通信过程中采取了很多的安全措施,如在 RFC 文档中你可能会看 JWT、JWS、JOSE、JWK、reply-nonce等名词,看起来就陌生。如果你不是技术人员,也大可不必去研究那些东西,知道怎么用就行。
1. 安装 acme.sh
安装很简单, 一个命令:
curl https://get.acme.sh | sh
推荐root用户安装。如普通用户,需要修改sudoer确保运行sudo无密码。
然后重新载入一下 .bashrc
source ~/.bashrc
或重新登陆
2. 生成证书
acme.sh 实现了 acme 协议支持的所有验证协议. 一般有两种方式验证: http 和 dns 验证。以下介绍nginx http验证。其他验证方式请参考acme.sh 中文说明
如果你用的 nginx 服务器, acme.sh 还可以智能的从 nginx 的配置中自动完成验证, 你不需要指定网站根目录:
acme.sh --issue -d mydomain.com --nginx
注意, 无论是 apache 还是 nginx 模式, acme.sh 在完成验证之后, 会恢复到之前的状态, 都不会私自更改你本身的配置. 好处是你不用担心配置被搞坏, 也有一个缺点, 你需要自己配置 ssl 的配置, 否则只能成功生成证书, 你的网站还是无法访问 https. 但是为了安全, 你还是自己手动改配置吧.
为多个域名同时生成证书
acme.sh --issue -d mydomain.com -d blog.mydomain.com --nginx
3. copy/安装 证书
前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.
注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache 的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.
正确的使用方法是使用 –installcert 命令,并指定目标位置, 然后证书文件会被copy到相应的位置, 例如:
acme.sh --installcert -d mydomain.com \ --key-file /etc/nginx/ssl/mydomain.com.key \ --fullchain-file /etc/nginx/ssl/mydomain.com.fullchain.cer \ --reloadcmd "nginx -s reload"
为多个域名同时安装证书
acme.sh --installcert -d mydomain.com blog.mydomain.com \ --key-file /etc/nginx/ssl/mydomain.com.key \ --fullchain-file /etc/nginx/ssl/mydomain.com.fullchain.cer \ --reloadcmd "nginx -s reload"
以上命令假定证书安装在/etc/nginx/ssl,需要先执行mkdir -p /etc/nginx/ssl确保存在该目录。
4. Nginx配置
server { server_name mydomain.com blog.mydomain.com; listen 80; rewrite ^(.*) https://mydomain.com$1 permanent; } server { server_name example.com; listen 443 http2; ssl on; include /etc/nginx/ssl_params; ssl_certificate /etc/nginx/ssl/mydomain.com.fullchain.cer; ssl_certificate_key /etc/nginx/ssl/mydomain.com.key; include /etc/nginx/hsts_headers; location / { return 204; } }
/etc/nginx/hsts_headers添加了一些 HSTS 头,内容如下
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains; preload" always;
/etc/nginx/ssl_params 这个文件是一些 SSL 相关的配置,内容如下
ssl_protocols TLSv1 TLSv1.1 TLSv1.2; ssl_dhparam /etc/nginx/dhparams.pem; # See https://weakdh.org/sysadmin.html for more details ssl_session_cache shared:SSL:1m; ssl_session_timeout 5m; ssl_prefer_server_ciphers on; ssl_ciphers "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA";
生成 /etc/nginx/dhparams.pem 文件
openssl dhparam -out /etc/nginx/dhparams.pem 2048
5. 重启Nginx生效
nginx -t nginx -s reload
6. 验证 SSL
访问 ssllabs.com 输入你的域名,检查 SSL 的配置是否都正常:
https://ssllabs.com/ssltest/analyze.html?d=mydomain.com
确保验证结果有 A 以上,否则根据提示调整问题
7. 后续维护
Let’s Encrypt 的证书有效期是 90 天的,你需要定期 renew 重新申请,这部分 acme.sh 以及帮你做了,在安装的时候往 crontab 增加了一行每天执行的命令 acme.sh –cron:
$ crontab -l 0 0 * * * "/home/ubuntu/.acme.sh"/acme.sh --cron --home "/home/ubuntu/.acme.sh" > /dev/null
最后走一下 acme.sh –cron 的流程看看能否正确执行
acme.sh --cron -f
这个过程应该会得到这样的结果,并在最后重启 Nginx
[[email protected] ~]# acme.sh --cron -f [Mon Dec 11 03:37:33 UTC 2017] ===Starting cron=== [Mon Dec 11 03:37:33 UTC 2017] Installing from online archive. [Mon Dec 11 03:37:33 UTC 2017] Downloading https://github.com/Neilpang/acme.sh/archive/master.tar.gz [Mon Dec 11 03:37:35 UTC 2017] Extracting master.tar.gz [Mon Dec 11 03:37:35 UTC 2017] Installing to /root/.acme.sh [Mon Dec 11 03:37:35 UTC 2017] Installed to /root/.acme.sh/acme.sh [Mon Dec 11 03:37:35 UTC 2017] Good, bash is found, so change the shebang to use bash as preferred. [Mon Dec 11 03:37:36 UTC 2017] OK [Mon Dec 11 03:37:36 UTC 2017] Install success! [Mon Dec 11 03:37:36 UTC 2017] Upgrade success! [Mon Dec 11 03:37:36 UTC 2017] Auto upgraded to: 2.7.6 省略... [Mon Dec 11 03:37:40 UTC 2017] Run reload cmd: nginx -s reload [Mon Dec 11 03:37:40 UTC 2017] Reload success [Mon Dec 11 03:37:40 UTC 2017] ===End cron===
acme.sh 中文说明
https://github.com/Neilpang/acme.sh/wiki/说明
使用 acme.sh 给 Nginx 安装 Let’ s Encrypt 提供的免费 SSL 证书
https://ruby-china.org/topics/31983
快速配置 HTTPS
https://blog.mynook.info/post/fast-way-to-configure-a-https-site/
acme.sh 自动更新 RSA、ECC 双证书实践
https://deepzz.com/post/acmesh-letsencrypt-cert-auto-renew.html
本博客 Nginx 配置之安全篇
https://tommyh.io/post/2
Blogs and tutorials
https://github.com/Neilpang/acme.sh/wiki/Blogs-and-tutorials
Let’s Encrypt,免费好用的 HTTPS 证书
https://imququ.com/post/letsencrypt-certificate.html