acme.sh 的项目,它是一个实现 ACME 协议的客户端,能够向支持 ACME 协议的 CA 申请证书(如 Letsencrypt)。 最重要的是它对接了大多数的域名服务商,能够通过域名服务商提供的 API,自动的添加 DNS 验证记录进行全自动颁发证书,还可以模拟 HTTP 服务器进行文件验证。so,不管你的证书期限是 90 天,还是更短,再也不用担心证书过期的问题了。

至于 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

打赏

Leave a Reply

Your email address will not be published. Required fields are marked *