Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

acme.sh 使用记录 #138

Open
Bpazy opened this issue Jan 19, 2020 · 5 comments
Open

acme.sh 使用记录 #138

Bpazy opened this issue Jan 19, 2020 · 5 comments

Comments

@Bpazy
Copy link
Owner

Bpazy commented Jan 19, 2020

这里记录一些我的使用 acme.sh 的方法、内容,比如生成证书、生成多域名、多子域名证书、自动续期等等。

官方安装和使用文档:https://github.com/Neilpang/acme.sh/wiki/说明

HTTP 方式生成证书

该方法生成的证书不支持泛域名。
还有一点,acme.sh 检测的 nginx 配置文件必须位于 /etc/nginx/sites-enabled 下。

acme.sh --issue -d cdn.example.com --nginx

发现的问题

acme.sh 并不能增量的增加子域名,如现在已有 a.example.com 的证书,想要增加 b.example.com,该脚本就会替换现有的 fullchain.cer 文件,从而导致之前的证书失效。
所以想要添加子域名 b.example.com 的话,要同时创建 a.example.com 和 b.example.com,当子域名数量过多的话,就会触发 Let's Encrypt 的速率限制,比较恶心。

DNS 方式生成证书

该方法生成的证书支持泛域名,从长远角度考虑比较方便,笔者最终采用的就是这种方法。

DNS 方式简单来说就是需要你在 DNS 解析上增加一个 TXT 记录,用于表明该域名归属于你。
但这里有个问题:Let's Encrypy 的证书 3 个月后就会过期,难不成每 3 个月都重新手动操作一遍吗?这也违背了 acme.sh 脚本的初衷。所以这里需要利用 DNS 服务商的 API,这样 acme.sh 可以自动的完成这一切。每一家 DNS 的具体配置方式不一致,请自行查阅官方文档:https://github.com/Neilpang/acme.sh/wiki/dnsapi

export CF_Key="***************************"
export CF_Email="******@163.com"
acme.sh --issue --dns dns_cf -d example.com -d *.example.com

安装证书

acme.sh --installcert -d example.com \
  --key-file /etc/nginx/ssl/example.com.key \
  --fullchain-file /etc/nginx/ssl/fullchain.cer \
  --reloadcmd "systemctl restart nginx"

注意这里的 reloadcmd 参数,这是 nginx 重启的命令,如果你没有使用 systemd 或者说你是直接用的 nginx 命令,那请修改对应的命令为:

  1. 关闭 nginx
  2. 开启 nginx

因为 nginx -s reload 命令并不能重新加载证书。

怎么避免连续多次失败触发 Rate limit ?

运行 acme.sh 的时候加上参数 --test

触发 Let's Encrpty 的 Rate limit 怎么办

可以删除 ~/.acme.sh 再重新安装操作。

提示 Failed to connect to dns.google port 如何解决?

使用参数 --dnssleep 300acme.sh 默认情况会使用 google dns 来验证是否生效,该参数可以跳过该验证,文档: dnssleep

@Bpazy Bpazy added the blog label Jan 19, 2020
@Bpazy Bpazy removed the blog label Mar 22, 2020
@Bpazy
Copy link
Owner Author

Bpazy commented Sep 17, 2021

个人用的命令记录:

export Ali_Key="***"
export Ali_Secret="***"

acme.sh --issue --dns dns_ali -d example.com -d *.example.com  -d netmaker.example.com -d *.netmaker.example.com --debug --httpport socks5://127.0.0.1:1080

acme.sh --installcert -d example.com \
  --key-file /etc/nginx/ssl/example.com.key \
  --fullchain-file /etc/nginx/ssl/fullchain.cer \
  --reloadcmd "systemctl restart nginx"

这里有一个细节,申请证书时,指定了多个泛域名,但是将证书复制到 nginx 目录时,仅指定顶级目录即可。

有时候 httpport 不生效,则该行命令应该替换成:

acme.sh --issue --dns dns_ali -d example.com -d *.example.com  -d netmaker.example.com -d *.netmaker.example.com --debug --dnssleep 300

@Bpazy
Copy link
Owner Author

Bpazy commented Sep 27, 2021

acme.sh 自动续约失效

调查后发现,acme.sh 更新证书实际成功了,只是 nginx 并没有重新装载新的证书。上文中也已经提到, reload 参数是无法更新证书的,必须 停止启动

acme.sh 的文档中写的对应命令为: service force-reload nginx
而发生问题时,我的命令为: systemctl force-reload nginx

于是查看了 service 命令对应的配置文件 /etc/init.d/nginx,发现其中是有 force-reload 这个参数的:

... 省略部分无关代码
    reload|force-reload)
        log_daemon_msg "Reloading $DESC configuration" "$NAME"

        # Check configuration before stopping nginx
        #   
        # This is not entirely correct since the on-disk nginx binary
        # may differ from the in-memory one, but that's not common.
        # We prefer to check the configuration and return an error
        # to the administrator.
        if ! test_config; then
            log_end_msg 1 # Configuration error
            exit $?
        fi  

        reload_nginx
        log_end_msg $?
        ;;  
... 省略部分无关代码

reload_nginx() {
    # Function that sends a SIGHUP to the daemon/service
    start-stop-daemon --stop --signal HUP --quiet --pidfile $PID --name $NAME
    return 0
}

再查看 systemctl 对应的配置文件 /lib/systemd/system/nginx.service,其中并没有 force-reload 这种处理:

[Service]
Type=forking
PIDFile=/run/nginx.pid
ExecStartPre=/usr/sbin/nginx -t -q -g 'daemon on; master_process on;'
ExecStart=/usr/sbin/nginx -g 'daemon on; master_process on;'
ExecReload=/usr/sbin/nginx -g 'daemon on; master_process on;' -s reload
ExecStop=-/sbin/start-stop-daemon --quiet --stop --retry QUIT/5 --pidfile /run/nginx.pid
TimeoutStopSec=5
KillMode=mixed

所以只要修改为 systemctl restart nginx 即可,上文中错误的命令也已修改,所以你看到的就是正确的版本。

注意: 不要用 systemctl reload nginx, 它对应的命令为 nginx -s reload, 无法更新证书。

@Bpazy
Copy link
Owner Author

Bpazy commented Sep 27, 2021

acme.sh 开启自动更新

acme.sh  --upgrade  --auto-upgrade

@Bpazy
Copy link
Owner Author

Bpazy commented Dec 29, 2021

Let's Encrypt 泛域名不支持多级

什么意思呢?你申请 *.example.com 的证书,是无法用在 *.b.example.com 上的,所以申请的时候需要修改下脚本,比如上面我的个人脚本里有提到,同时申请泛域名,和子域名的泛域名即可:

acme.sh --issue --dns dns_ali -d example.com -d *.example.com  -d b.example.com -d *.b.example.com --debug --httpport socks://127.0.0.1:10808

@Bpazy
Copy link
Owner Author

Bpazy commented May 22, 2022

证书生成后如何修改 reloadcmd?

参考: acmesh-official/acme.sh#2029

通过 acme.sh --installcert 命令来修改。

比如我使用的是:

acme.sh --installcert -d example.com --key-file /etc/nginx/ssl/example.com.key   --fullchain-file /etc/nginx/ssl/fullchain.cer   --reloadcmd "systemctl restart nginx && docker-compose -f /home/ubuntu/derper-docker/docker-compose.yaml up -d --force-recreate"

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant