acme.sh

  • acme.sh 实现了 acme 协议, 可以从 letsencrypt 生成免费的证书.
  • github:https://github.com/acmesh-official/acme.sh
  • PS:由于 letsencrypt 证书在国内解析地址存在被污染的问题,在 苹果手机H5 场景下存在认证证书慢的情况

安装

  • 通过 git 包安装
  • PS:运行脚本不支持 sudo 调用,如 nginx 目录需 root 权限操作,则此工具需使用 root 安装
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# 下载压缩包
$ git clone https://github.com/acmesh-official/acme.sh.git

# 简易安装
$ acme.sh --install -m  my@example.com # 需改为自己邮箱

# 自定义安装
$ cd acme.sh
$ ./acme.sh --install  \
--home ~/myacme \
--config-home ~/myacme/data \
--cert-home  ~/mycerts \
--accountemail  "my@example.com" \
--accountkey  ~/myaccount.key \
--accountconf ~/myaccount.conf \
--useragent  "this is my client."

# logout 重新连接以 初始化变量
$ logout

Nginx 基于 http 通过文件验证申请证书

  • https://www.rmedgar.com/blog/using-acme-sh-with-nginx/
  • 申请流程
    • 脚本会在站点目录下的 .well-known/acme-challenge 的目录中随机生成一个证书文件
    • 要保证通过 http://域名/.well-known/acme-challenge/随机证书文件 能够正常访问文件
    • 将证书移动到指定目录,并在 nginx 中进行配置

配置 nginx 转发规则

  • 在 Nginx 要配置 ssl 证书的监听 server 下配置转发规则
1
2
3
location ~* \.well-known/ {
        root html;
}

申请证书

  • 申请成功后,证书文件会放在 .acme.sh/example.domain.com 下
1
$ acme.sh  --issue  -d example.domain.com -w /usr/local/platform/openresty/nginx/html

拷贝证书

  • 手动拷贝(不推荐)
1
2
$ sudo mv /root/.acme.sh/example.domain.com/fullchain.cer /usr/local/platform/openresty/nginx/conf/certs/example.domain.com.pem
$ sudo cp -rp /root/.acme.sh/example.domain.com/example.domain.com.key /usr/local/platform/openresty/nginx/conf/certs/example.domain.com.key
  • 脚本拷贝
1
2
3
4
acme.sh --install-cert -d example.domain.com \
--key-file       /usr/local/platform/openresty/nginx/conf/certs/example.domain.com.key  \
--fullchain-file /usr/local/platform/openresty/nginx/conf/certs/example.domain.com.pem \
--reloadcmd "systemctl force-reload openresty"
  • PS:
    • 由于手动拷贝,目录下 example.domain.com.conf 文件中并未指定路径、重启命令等,会导致续期失败.
    • nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/example.domain.com.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。
    • 如果替换完证书,推荐使用 systemctl force-reload openresty/nginx 重载配置

nginx 配置 ssl 证书

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
server {
    listen       443 ssl;
    server_name example.domain.com;
    
    ssl_certificate      certs/example.domain.com.pem;    #证书路径;
    ssl_certificate_key  certs/example.domain.com.key;  #证书私钥路径;
    
    ssl_session_timeout  5m;
    ssl_protocols TLSv1.1 TLSv1.2 TLSv1.3;
    ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4:!DH:!DHE;
    ssl_prefer_server_ciphers   on;
}

续期

  • 配置好证书后,脚本会在 crontab 下创建一个定时任务,用于自动续期
1
19 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null

其他

删除证书

  • 查看已有证书
1
2
3
$ acme.sh  --list
Main_Domain         KeyLength  SAN_Domains  CA               Created                          Renew
blog.xbash.cloud    ""         no           LetsEncrypt.org  Tue 14 Mar 2023 04:19:10 PM UTC  Sat 13 May 2023 04:19:10 PM UTC
  • 删除证书
1
acme.sh --remove -d blog.xbash.cloud