acme实现自动更新网站SSL证书

文章
林里克斯

使用 acme 协议来实现自动更新 SSl 证书


一、安装acme


1.安装 acme ,使用官网提供

Github 地址
https://github.com/acmesh-official/acme.sh
Url
$ curl  https://get.acme.sh | sh

[Wed Jul 22 10:33:35 CST 2020] Installing from online archive.
[Wed Jul 22 10:33:35 CST 2020] Downloading https://github.com/acmesh-official/acme.sh/archive/master.tar.gz
[Wed Jul 22 10:33:47 CST 2020] Extracting master.tar.gz
[Wed Jul 22 10:33:47 CST 2020] It is recommended to install socat first.
[Wed Jul 22 10:33:47 CST 2020] We use socat for standalone server if you use standalone mode.
[Wed Jul 22 10:33:47 CST 2020] If you don't use standalone mode, just ignore this warning.
[Wed Jul 22 10:33:47 CST 2020] Installing to /root/.acme.sh
[Wed Jul 22 10:33:47 CST 2020] Installed to /root/.acme.sh/acme.sh
[Wed Jul 22 10:33:47 CST 2020] Installing alias to '/root/.bashrc'
[Wed Jul 22 10:33:47 CST 2020] OK, Close and reopen your terminal to start using acme.sh
[Wed Jul 22 10:33:47 CST 2020] Installing alias to '/root/.cshrc'
[Wed Jul 22 10:33:47 CST 2020] Installing alias to '/root/.tcshrc'
[Wed Jul 22 10:33:47 CST 2020] Installing cron job
[Wed Jul 22 10:33:47 CST 2020] Good, bash is found, so change the shebang to use bash as preferred.
[Wed Jul 22 10:33:48 CST 2020] OK
[Wed Jul 22 10:33:48 CST 2020] Install success!
Markdown

2.自定义高级安装

$ git clone https://github.com/Neilpang/acme.sh.git
$ 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."
Markdown
  • --home #是要安装的自定义目录acme.sh。默认情况下,它安装到~/.acme.sh
  • --config-home #是一个可写文件夹,acme.sh将在其中写入所有文件(包括cert / keys,configs)。默认情况下--home
  • --cert-home #是自定义的目录,用于保存您颁发的证书。默认情况下,它保存在中--config-home。
  • --accountemail #是用于向Let's Encrypt注册帐户的电子邮件,您将在此处收到续订通知电子邮件。默认为空。
  • --accountkey #是保存您的帐户私钥的文件。默认情况下,它保存在中--config-home。
  • --useragent #是用于发送到“让我们加密”的用户代理标头值。

2.创建自定义命令方便使用

$ alias acme=/root/.acme.sh/acme.sh
Markdown

设置永久生效,在对应登录用户下编辑 bashrc 文件

$ vim /root/.bashrc

alias acme=/root/.acme.sh/acme.sh
Markdown

3.会自动创建 cronjob, 每天 0:00 点自动检测所有的证书, 如果快过期了, 需要更新, 则会自动更新证书.

$ crontab -l

47 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
Markdown

如果想看执行是否有报错,可以修改输出

47 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" >> /root/.acme.sh/logs/acme.log 2>&1
Markdown

安装过程不会污染已有的系统任何功能和文件, 所有的修改都限制在安装目录中: ~/.acme.sh/


二、生成证书


acme.sh 实现了 acme 协议支持的所有验证协议. 一般有两种方式验证: httpdns 验证.
1.手动 dns 方式, 手动在域名上添加一条 txt 解析记录, 验证域名所有权.

$ acme --issue --dns -d mydomain.com
Markdown

然后, acme.sh 会生成相应的解析记录显示出来, 你只需要在你的域名管理面板中添加这条 txt 记录即可
等待解析完成之后, 重新生成证书:

$ acme --renew -d mydomain.com
#注意第二次这里用的是 --renew
Markdown

这种方式的好处是, 你不需要任何服务器, 不需要任何公网 ip, 只需要 dns 的解析记录即可完成验证. 坏处是,如果不同时配置 Automatic DNS API,使用这种方式 acme.sh 将无法自动更新证书,每次都需要手动再次重新解析验证域名所有权。

使用阿里api来生成证书

$ export Ali_Key="******"
$ export Ali_Secret="******"
$ acme --register-account -m mylinux@kjarbo.com --issue --dns dns_ali -d *.kjarbo.com --nginx
Markdown

使用腾讯云api来生成证书

$ export DP_Id="******"
$ export DP_Key="******"
$ acme --register-account -m mylinux@kjarbo.com --issue --dns dns_dp -d *.jarbo.cc --nginx
Markdown

api账号密钥存入配置文件

$ vim ~/.acme/account.conf
SAVED_Ali_Key='******'
SAVED_Ali_Secret='******'

SAVED_DP_Id='******'
SAVED_DP_Key='******'
Markdown

2.http 方式需要在你的网站根目录下放置一个文件, 来验证你的域名所有权,完成验证. 然后就可以生成证书了.

$ acme --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
#一般使用这个即可
Markdown

成功的话有以下信息输出

$ acme --register-account -m mylinux@kjarbo.com --issue --dns dns_ali -d *.kjarbo.com --nginx

[Wed Jul 22 11:10:42 CST 2020] Single domain='*.kjarbo.com'
[Wed Jul 22 11:10:42 CST 2020] Getting domain auth token for each domain
[Wed Jul 22 11:10:47 CST 2020] Getting webroot for domain='*.kjarbo.com'
[Wed Jul 22 11:10:47 CST 2020] Adding txt value: hxTvSri5kYRaYdY9n4weQPifnMq9epIOrK6Vo98VzYg for domain:  _acme-challenge.kjarbo.com
[Wed Jul 22 11:10:49 CST 2020] The txt record is added: Success.
[Wed Jul 22 11:10:49 CST 2020] Let's check each DNS record now. Sleep 20 seconds first.         #这里会等待20秒
[Wed Jul 22 11:11:10 CST 2020] Checking kjarbo.com for _acme-challenge.kjarbo.com
[Wed Jul 22 11:11:13 CST 2020] Domain kjarbo.com '_acme-challenge.kjarbo.com' success.
[Wed Jul 22 11:11:13 CST 2020] All success, let's return
[Wed Jul 22 11:11:13 CST 2020] Verifying: *.kjarbo.com
[Wed Jul 22 11:11:19 CST 2020] Success
[Wed Jul 22 11:11:19 CST 2020] Removing DNS records.
[Wed Jul 22 11:11:19 CST 2020] Removing txt: hxTvSri5kYRaYdY9n4weQPifnMq9epIOrK6 for domain: _acme-challenge.kjarbo.com
[Wed Jul 22 11:11:22 CST 2020] Removed: Success
[Wed Jul 22 11:11:22 CST 2020] Verify finished, start to sign.
[Wed Jul 22 11:11:27 CST 2020] Cert success.
[Wed Jul 22 11:11:27 CST 2020] Your cert is in  /root/.acme.sh/*.kjarbo.com/*.kjarbo.com.cer 
[Wed Jul 22 11:11:27 CST 2020] Your cert key is in  /root/.acme.sh/*.kjarbo.com/*.kjarbo.com.key 
[Wed Jul 22 11:11:27 CST 2020] The intermediate CA cert is in  /root/.acme.sh/*.kjarbo.com/ca.cer 
[Wed Jul 22 11:11:27 CST 2020] And the full chain certs is there:  /root/.acme.sh/*.kjarbo.com/fullchain.cer
Markdown

只需要指定域名, 并指定域名所在的网站根目录. acme.sh 会全自动的生成验证文件, 并放到网站的根目录, 然后自动完成验证. 最后会聪明的删除验证文件. 整个过程没有任何副作用.

如果你用的 apache 服务器, acme.sh 还可以智能的从 apache 的配置中自动完成验证, 你不需要指定网站根目录:

$ acme --issue -d mydomain.com --apache
Markdown

如果你用的 nginx服务器, 或者反代, acme.sh 还可以智能的从 nginx的配置中自动完成验证, 你不需要指定网站根目录:

$ acme --issue -d mydomain.com --nginx
Markdown

注意, 无论是 apache 还是 nginx 模式, acme.sh在完成验证之后, 会恢复到之前的状态, 都不会私自更改你本身的配置. 好处是你不用担心配置被搞坏, 也有一个缺点, 你需要自己配置 ssl 的配置, 否则只能成功生成证书, 你的网站还是无法访问https. 但是为了安全, 你还是自己手动改配置吧.

如果你还没有运行任何 web 服务, 80 端口是空闲的, 那么 acme.sh 还能假装自己是一个webserver, 临时听在80 端口, 完成验证:

$ acme --issue -d mydomain.com --standalone
Markdown

三、 安装证书


前面证书生成以后, 接下来需要把证书 copy 到真正需要用它的地方.

注意, 默认生成的证书都放在安装目录下: ~/.acme.sh/, 请不要直接使用此目录下的文件, 例如: 不要直接让 nginx/apache的配置文件使用这下面的文件. 这里面的文件都是内部使用, 而且目录结构可能会变化.

正确的使用方法是使用 --install-cert 命令,并指定目标位置, 然后证书文件会被 copy 到相应的位置, 例如:

Apache example:

$ acme --install-cert -d example.com \
--cert-file      /path/to/certfile/in/apache/cert.pem  \
--key-file       /path/to/keyfile/in/apache/key.pem  \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd     "service apache2 force-reload"
Makrdown

Nginx example:

$ acme --install-cert -d example.com \
--key-file       /path/to/keyfile/in/nginx/key.pem  \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd     "service nginx force-reload"
#如果是普通用户可以使用 -s reload
--reloadcmd     "/data/nginx/sbin/nginx -s reload"
Makrdown

重启 nginx 这里用的是 service nginx force-reload, 不是 service nginx reload, 据测试, reload 并不会重新加载证书, 所以用的 force-reload

Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/<domain>.cer ,否则 SSL Labs 的测试会报 Chain issues Incomplete 错误。

--install-cert 命令可以携带很多参数, 来指定目标文件. 并且可以指定 reloadcmd, 当证书更新以后, reloadcmd 会被自动调用,让服务器生效

验证后续自动更新是否正常

$ crontab -l
15 0 * * * "/home/jarbo/.acme.sh"/acme.sh --cron --home "/home/jarbo/.acme.sh" > /dev/null

$ ./acme.sh --cron -f
[Wed Jul 22 11:18:12 CST 2020] ===Starting cron===
[Wed Jul 22 11:18:12 CST 2020] Renew: '*.kjarbo.com'
[Wed Jul 22 11:18:15 CST 2020] Using CA: https://acme.zerossl.com/v2/DV90
[Wed Jul 22 11:18:15 CST 2020] Single domain='*.kjarbo.com'
[Wed Jul 22 11:18:15 CST 2020] Getting domain auth token for each domain
[Wed Jul 22 11:18:20 CST 2020] Getting webroot for domain='*.kjarbo.com'
[Wed Jul 22 11:18:21 CST 2020] Adding txt value: aetzJM3OzR1nakDNeS2BXlF8WWceEgXBb5Iy1mSvc4Q for domain:  _acme-challenge.kjarbo.com
[Wed Jul 22 11:18:26 CST 2020] The txt record is added: Success.
[Wed Jul 22 11:18:26 CST 2020] Let's check each DNS record now. Sleep 20 seconds first.
[Wed Jul 22 11:18:47 CST 2020] You can use '--dnssleep' to disable public dns checks.
[Wed Jul 22 11:18:47 CST 2020] See: https://github.com/acmesh-official/acme.sh/wiki/dnscheck
[Wed Jul 22 11:18:48 CST 2020] Checking kjarbo.com for _acme-challenge.kjarbo.com
[Wed Jul 22 11:19:18 CST 2020] Domain kjarbo.com '_acme-challenge.kjarbo.com' success.
[Wed Jul 22 11:19:18 CST 2020] All success, let's return
[Wed Jul 22 11:19:18 CST 2020] Verifying: *.kjarbo.com
[Wed Jul 22 11:19:23 CST 2020] Success
[Wed Jul 22 11:19:23 CST 2020] Removing DNS records.
[Wed Jul 22 11:19:23 CST 2020] Removing txt: aetzJM3OzR1nakDNeS2BXlF8WWceEgXBb5Iy1mSvc4Q for domain: _acme-challenge.kjarbo.com
[Wed Jul 22 11:19:30 CST 2020] Removed: Success
[Wed Jul 22 11:19:30 CST 2020] Verify finished, start to sign.
[Wed Jul 22 11:19:30 CST 2020] Lets finalize the order.
[Wed Jul 22 11:19:30 CST 2020] Le_OrderFinalize='https://acme.zerossl.com/v2/DV90/order/xluB4E2Kpl9sUMcBhtu0Kg/finalize'
[Wed Jul 22 11:19:32 CST 2020] Order status is processing, lets sleep and retry.
[Wed Jul 22 11:19:32 CST 2020] Retry after: 15
[Wed Jul 22 11:19:48 CST 2020] Polling order status: https://acme.zerossl.com/v2/DV90/order/xluB4E2Kpl9sUMcBhtu0Kg
[Wed Jul 22 11:19:50 CST 2020] Downloading cert.
[Wed Jul 22 11:19:50 CST 2020] Le_LinkCert='https://acme.zerossl.com/v2/DV90/cert/kxGYM0-DJfCGBgoy2XWacw'
[Wed Jul 22 11:19:51 CST 2020] Cert success.
-----BEGIN CERTIFICATE-----
···
-----END CERTIFICATE-----
[Wed Jul 22 11:19:51 CST 2020] Your cert is in  /home/jarbo/.acme.sh/*.kjarbo.com/*.kjarbo.com.cer 
[Wed Jul 22 11:19:51 CST 2020] Your cert key is in  /home/jarbo/.acme.sh/*.kjarbo.com/*.kjarbo.com.key 
[Wed Jul 22 11:19:51 CST 2020] The intermediate CA cert is in  /home/jarbo/.acme.sh/*.kjarbo.com/ca.cer 
[Wed Jul 22 11:19:51 CST 2020] And the full chain certs is there:  /home/jarbo/.acme.sh/*.kjarbo.com/fullchain.cer 
[Wed Jul 22 11:19:51 CST 2020] Installing cert to:/usr/local/nginx/cert/cert
[Wed Jul 22 11:19:51 CST 2020] Installing key to:/usr/local/nginx/cert/key
[Wed Jul 22 11:19:51 CST 2020] Installing full chain to:/usr/local/nginx/cert/fullchain
[Wed Jul 22 11:21:29 CST 2020] Run reload cmd: sudo service nginx force-reload
Redirecting to /bin/systemctl force-reload nginx.service
[Wed Jul 22 11:21:29 CST 2020] Reload success
[Wed Jul 22 11:21:31 CST 2020] ===End cron===
#这个就是后续正常的自动更新证书了。
Markdown

四、 证书过期更新


目前证书在 60 天以后会自动更新, 无需任何操作. 今后有可能会缩短这个时间, 不过都是自动的, 不用关心


五、 acme 更新


目前由于 acme 协议和 letsencrypt CA 都在频繁的更新, 因此 acme.sh 也经常更新以保持同步.

升级 acme.sh 到最新版 :

$ acme --upgrade
Makrdown

如果你不想手动升级, 可以开启自动升级:

acme --upgrade --auto-upgrade
Markdown

之后, acme.sh 就会自动保持更新了.

你也可以随时关闭自动更新:

$ acme --upgrade --auto-upgrade  0
Markdown

六、后期维护


1.查看现有那些域名在更新 SSL 证书

$ ./acme.sh --cron --home /root/.acme.sh
[Thu Nov 26 15:09:14 CST 2020] ===Starting cron===
[Thu Nov 26 15:09:14 CST 2020] Renew: '*.kjarbo.com'
[Thu Nov 26 15:09:14 CST 2020] Skip, Next renewal time is: Sun Nov 29 07:23:33 UTC 2020
[Thu Nov 26 15:09:14 CST 2020] Add '--force' to force to renew.
[Thu Nov 26 15:09:14 CST 2020] Skipped *.kjarbo.com
[Thu Nov 26 15:09:14 CST 2020] Renew: 'kjarbo.com'
[Thu Nov 26 15:09:14 CST 2020] 'kjarbo.com' is not a issued domain, skip.
[Thu Nov 26 15:09:14 CST 2020] Skipped kjarbo.com
[Thu Nov 26 15:09:14 CST 2020] Renew: 'www.kjarbo.com'
[Thu Nov 26 15:09:14 CST 2020] 'www.kjarbo.com' is not a issued domain, skip.
[Thu Nov 26 15:09:14 CST 2020] Skipped www.kjarbo.com
[Thu Nov 26 15:09:14 CST 2020] ===End cron===
# 可以看到只有一个通配符域名 *.kjarbo.com 在更新
Markdown

2.删除不需要更新的 SSL 证书

$ ./acme.sh --remove -d www.kjarbo.com
$ ./acme.sh --remove -d kjarbo.com
$ cd ~/.acme.sh/
$ rm -rf kjarbo.com/ www.kjarbo.com/
#还需要删除存放证书的路径
$ ./acme.sh --cron --home /root/.acme.sh
[Thu Nov 26 15:13:53 CST 2020] ===Starting cron===
[Thu Nov 26 15:13:53 CST 2020] Renew: '*.kjarbo.com'
[Thu Nov 26 15:13:53 CST 2020] Skip, Next renewal time is: Sun Nov 29 07:23:33 UTC 2020
[Thu Nov 26 15:13:53 CST 2020] Add '--force' to force to renew.
[Thu Nov 26 15:13:53 CST 2020] Skipped *.kjarbo.com
[Thu Nov 26 15:13:53 CST 2020] ===End cron===
#只剩下一个了
Markdown

Over~

版权协议须知!

本篇文章来源于 Uambiguous ,如本文章侵犯到任何版权问题,请立即告知本站,本站将及时予与删除并致以最深的歉意

1910 0 2020-07-22


分享:
icon_mrgreen.gificon_neutral.gificon_twisted.gificon_arrow.gificon_eek.gificon_smile.gificon_confused.gificon_cool.gificon_evil.gificon_biggrin.gificon_idea.gificon_redface.gificon_razz.gificon_rolleyes.gificon_wink.gificon_cry.gificon_surprised.gificon_lol.gificon_mad.gificon_sad.gificon_exclaim.gificon_question.gif
博主卡片
林里克斯 博主大人
一个致力于Linux的运维平台
运维时间
搭建这个平台,只为分享及记载自己所遇之事和难题。

现在时间 2025-04-24

今日天气
站点统计
  • 文章总数:241篇
  • 分类总数:29个
  • 评论总数:15条
  • 本站总访问量 405631 次

@svmuvwpuqi 真棒!

@smdxydrauu 博主太厉害了!

@奥奥

@Wong arrhenius 牛比

@MakerFace 厉害了!