Open Bpazy opened 4 years ago
个人用的命令记录:
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
调查后发现,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
, 无法更新证书。
acme.sh --upgrade --auto-upgrade
什么意思呢?你申请 *.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
通过 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"
这里记录一些我的使用 acme.sh 的方法、内容,比如生成证书、生成多域名、多子域名证书、自动续期等等。
HTTP 方式生成证书
该方法生成的证书不支持泛域名。 还有一点,acme.sh 检测的 nginx 配置文件必须位于
/etc/nginx/sites-enabled
下。发现的问题
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
安装证书
注意这里的 reloadcmd 参数,这是 nginx 重启的命令,如果你没有使用 systemd 或者说你是直接用的 nginx 命令,那请修改对应的命令为:
因为 nginx -s reload 命令并不能重新加载证书。
怎么避免连续多次失败触发 Rate limit ?
运行 acme.sh 的时候加上参数
--test
。触发 Let's Encrpty 的 Rate limit 怎么办
可以删除
~/.acme.sh
再重新安装操作。提示 Failed to connect to dns.google port 如何解决?
使用参数
--dnssleep 300
。acme.sh
默认情况会使用 google dns 来验证是否生效,该参数可以跳过该验证,文档: dnssleep。