使用acme.sh申请免费 HTTPS 证书及自动续期
Aug 18, 2024 · 8 min · acme.sh
使用acme.sh申请免费 HTTPS 证书及自动续期
安装 acme
在服务器上,使用下面的命令行快速安装acme,email 配置为你自己的邮箱。
curl https://get.acme.sh | sh -s email=my@example.com然后稍等片刻,如下图,出现Install success 的提示表示安装成功了。通过安装日志,可以看到安装目录,并且还看到创建一个 cron job,这个job就是自动更新证书的定时任务。
还有一种克隆仓库的安装方式。
git clone https://github.com/acmesh-official/acme.sh.git
cd ./acme.sh
./acme.sh --install安装位置在这里,也就是当前用户home目录中。
Installing to /root/.acme.sh
Installed to /root/.acme.sh/acme.sh
Installing alias to '/root/.bashrc'acme生成证书
初次使用,可能需要注册账号,一个邮箱即可(此步可先跳过,等到执行具体命令时如果提示,再注册不迟)
acme.sh --register-account -m youemail@gmail.comacme 默认使用的是 ZeroSSL,但是 ZeroSSL 不是很稳定,如果可能的话,可以切换到letsencrypt,当然了,不切换也无所谓。
acme.sh --set-default-ca --server letsencrypt生成证书
有两种方式生成证书,一种是 HTTP 方式,另一种是 DNS 方式。
比较推荐使用 DNS 方式,域名不用备案,而且可以自动更新续期。
HTTP 方式(不推荐)
下面这个命令是 HTTP 方式,-d 后面是域名,—webroot 后面是网站根目录。这种方式会在你的服务器根目录生成一个验证文件,然后通过80端口访问
但是先别着急执行啊,这种方式在国内有个问题,就是你的域名必须要先备案,要不然 80 端口会被工信部的未备案提示页面拦截,导致没办法生成证书。
所以域名在国内或者服务器在国内,最好还是别用这种方式。
acme.sh --issue -d domain.com --webroot /data/certsDNS 方式和自动更新
这种方式是比较推荐的方式,不管你的域名在阿里云还是什么平台,你不需要任何服务器, 不需要任何公网 ip, 只需要 dns 的解析记录即可完成验证。有一些服务是不提供服务器的,只要根据他们的规则就可以运行服务,例如 GitHub Page、Vercel这些,所以,没办法进到服务器中,不能用 HTTP 方式验证,因为HTTP方式需要在服务器生成文件。
在这里 https://github.com/acmesh-official/acme.sh/wiki/dnsapi2 ,可以看到所支持的域名供应商,只要能在这里面找到的,都支持 DNS 方式验证,基本上市面上你能买到域名的地方都可以用这种方式,阿里云、华为云、腾讯云等等都在其中,里面有具体的参数说明。
以阿里云为例,因为我这个域名 domain.com是在阿里云买的。
在 https://ram.console.aliyun.com/manage/ak 这个页面中,生成一个 key 和 secret,然后将这两个值导入环境变量。
export Ali_Key="LTA***ctest"
export Ali_Secret="pIRIS***fdtest"之后再执行生成证书的命令。
acme.sh --issue --dns dns_ali -d onela.cn当看到以下结果时,表示证书生成成功了
[Sun 12 Jan 2025 09:41:25 AM GMT] Using CA: https://acme-v02.api.letsencrypt.org/directory
[Sun 12 Jan 2025 09:41:25 AM GMT] Creating domain key
[Sun 12 Jan 2025 09:41:25 AM GMT] The domain key is here: /root/.acme.sh/domain.com_ecc/domain.com.key
[Sun 12 Jan 2025 09:41:25 AM GMT] Single domain='domain.com'
[Sun 12 Jan 2025 09:41:27 AM GMT] Getting webroot for domain='domain.com'
[Sun 12 Jan 2025 09:41:27 AM GMT] Adding TXT value: HoKgatn7Ili0tX2mWUXZdTQoqTK6LV4ZpEBTbMTVTLg for domain: _acme-challenge.domain.com
[Sun 12 Jan 2025 09:41:32 AM GMT] The TXT record has been successfully added.
[Sun 12 Jan 2025 09:41:32 AM GMT] Let's check each DNS record now. Sleeping for 20 seconds first.
[Sun 12 Jan 2025 09:41:53 AM GMT] You can use '--dnssleep' to disable public dns checks.
[Sun 12 Jan 2025 09:41:53 AM GMT] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Sun 12 Jan 2025 09:41:53 AM GMT] Checking domain.com for _acme-challenge.domain.com
[Sun 12 Jan 2025 09:41:54 AM GMT] Success for domain domain.com '_acme-challenge.domain.com'.
[Sun 12 Jan 2025 09:41:54 AM GMT] All checks succeeded
[Sun 12 Jan 2025 09:41:54 AM GMT] Verifying: domain.com
[Sun 12 Jan 2025 09:41:55 AM GMT] Pending. The CA is processing your order, please wait. (1/30)
[Sun 12 Jan 2025 09:41:58 AM GMT] Success
[Sun 12 Jan 2025 09:41:58 AM GMT] Removing DNS records.
[Sun 12 Jan 2025 09:41:58 AM GMT] Removing txt: HoKgatn7Ili0tX2mWUXZdTQoqTK6LV4ZpEBTbMTVTLg for domain: _acme-challenge.domain.com
[Sun 12 Jan 2025 09:42:04 AM GMT] Successfully removed
[Sun 12 Jan 2025 09:42:04 AM GMT] Verification finished, beginning signing.
[Sun 12 Jan 2025 09:42:04 AM GMT] Let's finalize the order.
[Sun 12 Jan 2025 09:42:04 AM GMT] Le_OrderFinalize='https://acme-v02.api.letsencrypt.org/acme/finalize/1718956977/343543926785'
[Sun 12 Jan 2025 09:42:06 AM GMT] Downloading cert.
[Sun 12 Jan 2025 09:42:06 AM GMT] Le_LinkCert='https://acme-v02.api.letsencrypt.org/acme/cert/04ab6b11b62732c7eabd8a851b17c9037d67'
[Sun 12 Jan 2025 09:42:06 AM GMT] It seems the CA server is currently overloaded, let's wait and retry. Sleeping for 11 seconds.
[Sun 12 Jan 2025 09:42:19 AM GMT] Cert success.
-----BEGIN CERTIFICATE-----
MIIDeTCCAv+gAwIBAgISBKtrEbYnMsfqvYqFGxfJA31nMAoGCCqGSM49BAMDMDIx
CzAJBgNVBAYTAlVTMRYwFAYDVQQKEw1MZXQncyBFbmNyeXB0MQswCQYDVQQDEwJF
……
caky4eLk8JjZSVVPnvWhs4o8x4f0bI3HCG0LAjA9ivs+cWN2l0MKqHRIQzupCM9y
t0Jfnp84a7C2nN2zmnMUc9tzXbgENfdGjMlQR2Y=
-----END CERTIFICATE-----
[Sun 12 Jan 2025 09:42:19 AM GMT] Your cert is in: /root/.acme.sh/domain.com_ecc/domain.com.cer
[Sun 12 Jan 2025 09:42:19 AM GMT] Your cert key is in: /root/.acme.sh/domain.com_ecc/domain.com.key
[Sun 12 Jan 2025 09:42:19 AM GMT] The intermediate CA cert is in: /root/.acme.sh/domain.com_ecc/ca.cer
[Sun 12 Jan 2025 09:42:19 AM GMT] And the full-chain cert is in: /root/.acme.sh/domain.com_ecc/fullchain.cer安装和配置 SSL 证书
接下来打开 /etc/nginx/sites-enabled/default,修改前面配置的 HTTPS Server 的部分,主要就是加入了 ssl_certificate 和 ssl_certificate_key ,指定了/etc/nginx/ssl目录下,这个目录要提前创建好,acme不会自动创建的。
server {
listen 443 ssl;
listen [::]:443 ssl;
server_name domain.com;
ssl_certificate /root/.acme.sh/onela.cn_ecc/onela.cn.cer;
ssl_certificate_key /root/.acme.sh/onela.cn_ecc/onela.cn.key;
client_max_body_size 100m;
location / {
root /data/www/onela.cn;
index index.html;
}
}然后就到了最后一步,将acme生成的证书拷贝证书到指定目录。
证书生成后会在 acme 的默认目录下,但是不建议直接使用这个目录下的文件,所以,要使用下面的命令将证书拷贝到指定的位置。
然后执行下面的命令来将证书复制到前面 Nginx 配置中指定的证书目录中,注意最后 --reloadcmd 命令里是做了 Nginx 强制重载的操作。
acme.sh --installcert -d domain.com \
--key-file /etc/nginx/ssl/domain.com.key \
--fullchain-file /etc/nginx/ssl/fullchain.cer \
--reloadcmd "service nginx force-reload"这时候,再次访问 https 的地址,就能正常看到页面了。
你现在访问 https://domain.com 这个地址,就是用这个方式安装的 SSL 证书。
自动更新acme
现在证书已经可以自动更新了,但是 acme 还没有。因为各个免费 SSL 证书平台的规则不是一成不变的,随着他们的更新,acem也会相应的修改规则。
所以,你可以在服务器上执行下面的命令,设置acme 自动升级,保证可用性。
# acme.sh更新升级命令
acme.sh --upgrade --auto-upgrade
# 自动更新证书
# acme.sh --renew -d onela.cn --force --ecc && systemctl reload nginx
# acme.sh --renew -d nps.onela.cn --force --ecc
# acme.sh --renew -d pve.onela.cn --force --ecc
# crontab -e 添加自动执行任务,例如每月1日1点1分执行
1 1 */1 * * acme.sh --upgrade --auto-upgrade
10 1 */1 * * acme.sh --renew -d onela.cn --force --ecc && systemctl reload nginx
10 2 */1 * * acme.sh --renew -d nps.onela.cn --force --ecc && systemctl reload nginx
20 2 */1 * * acme.sh --renew -d pve.onela.cn --force --ecc && systemctl reload nginx
# 查看crontab配置是否生效
crontab -l