先来写这篇手动更新的纪录,是因为我考思未来再写一篇自动更新。
这样才有对对照组嘛,为何要叫逆天,
就我所知道certbot命令,目前whildcard的证书是没法自动更新的。
如果我们有用过Let's encrypt申请whildcard证书,一定会发现成功申请后,有这段话.
NEXT STEPS:
- This certificate will not be renewed automatically. Autorenewal of --manual certificates requires the use of an authentication hook script (--manual-auth-hook) but one was not provided.
To renew this certificate, repeat this same certbot command before the certificate's expiry date.
开中明义讲了,此证书不会自动更新,因为还没提供--manual-auth-hook,要更新这证书在到期日前重复相同的命令。
Ok,但还要有些小技巧,就能弄出自动更新了,至少我这么搞出来的。😆
不过有几个前题,您的DNS需要是自管的DNS或是您的DNS供应商能提供API的方式让您更新DNS纪录。
很多的证书供应商的DNS更新是很慢的,都要等12-24小时,而且TTL无法调太短,这点在选择时请注意。
自架的DNS就没这个问题了😋
本篇先来看一下我手动申请的流程,我用如下命令进行我Whildcard的证书申请及更新。
certbot certonly --agree-tos --manual \
--preferred-challenges dns --server \
https://acme-v02.api.letsencrypt.org/directory -d "*.demo.ccc.tc"
全画面更新日志:
certbot certonly --agree-tos --manual \
> --preferred-challenges dns --server \
> https://acme-v02.api.letsencrypt.org/directory -d "*.demo.ccc.tc"
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Attempting to parse the version 1.22.0 renewal configuration file found at /etc/letsencrypt/renewal/ccc.tc.conf with version 0.31.0 of Certbot. This might not work.
Cert is due for renewal, auto-renewing...
Renewing an existing certificate
Performing the following challenges:
dns-01 challenge for demo.ccc.tc
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.demo.ccc.tc with the following value:
1t3WObUV768V88P5ddULFXfn9nb9_PEqSwcibXm45Ik
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/demo.ccc.tc/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/demo.ccc.tc/privkey.pem
Your cert will expire on 2023-03-25. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
在这完整申请的过程中我采用了dns验证,所以需将TXT record更新到DNS中,再压Enter。
我的DNS使用bind9,所以我把record加到了文本档后并且更新序号。
$ORIGIN .
$TTL 86400 ; 1 day
demo.ccc.tc IN SOA ns1.demo.ccc.tc. devin.ccc.tc. (
2022103128 ; serial
10800 ; refresh (3 hours)
900 ; retry (15 minutes)
604800 ; expire (1 week)
86400 ; minimum (1 day)
)
NS ns1.demo.ccc.tc.
NS ns2.demo.ccc.tc.
A 220.134.172.98
$ORIGIN demo.ccc.tc.
* A 127.0.0.1
=============== 中间省略 ============
$TTL 60 ; 1 minute
_acme-challenge TXT 1t3WObUV768V88P5ddULFXfn9nb9_PEqSwcibXm45Ik
然后我会运行更新script,将日志同步到第二台DNS,在这我列出该命令
rndc reload demo.ccc.tc
完成手动更新后,为了确保万无一失,我会再下host命令指名type为text,验证是否查的到
$host -t txt _acme-challenge.demo.ccc.tc
_acme-challenge.demo.ccc.tc descriptive text "1t3WObUV768V88P5ddULFXfn9nb9_PEqSwcibXm45Ik"
然后就压上面画面中提示的Enter (Press Enter to Continue)进行验证。
Ok,以上大至上是我wildcard证书手动更新的流程,但是老是手动更新感觉似乎有些麻烦。
自动更新的文章还没发表之前,我先提示一下我的做法,
这些东西就算不是拿来做证书自动化更新,进行其他的功能也是很方便的,因该还是有些阅读价值。
提示一:
Linux中有一个命令叫/usr/bin/expect,他可以在预期画面出现什么,然后按按键 ,达成脚本自动化,例如:
expect "(Y)es/(N)o:"
send -- "Y\r"
提示二:
我运行certbot命令时会透过另一个命令tee,把certbot的运行画面(标准输出)同步存成文件,类似这样:
certbot certonly --agree-tos --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory -d "*.demo.ccc.tc" |tee demo.ou
提示三:
也就是说在自动化的过程中,demo.out的文件会有如下的内容,那我们要如何抓到中间那串文本呢,用awk命令,超方便。
Are you OK with your IP being logged?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: Y
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please deploy a DNS TXT record under the name
_acme-challenge.demo.ccc.tc with the following value:
1t3WObUV768V88P5ddULFXfn9nb9_PEqSwcibXm45Ik
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
那来看看我的awk命令怎么下的,在下方的画面中用头尾的识别,轻松抓到中间要添加DNS验证用的文本了。
root@ptest:/usr/local/scripts# awk '/following value:/,/Before continuing/' demo.out |tail -n3|head -n1
1t3WObUV768V88P5ddULFXfn9nb9_PEqSwcibXm45Ik
root@ptest:/usr/local/scripts#
所以我有一只update的bash长这样,即是把自己抓到的txt丢给我自己写的更新API进行record的更新
#!/bin/bash
TEXT=$(awk '/following value:/,/Before continuing/' demo.out |tail -n3|head -n1)
echo ${TEXT}
curl -X 'GET' \
"http://127.0.0.1:1020/acme?txt=${TEXT}&file=demo.db"
最后你应该想到了吧,让except去压Enter验证更新。
在except中,我会有如下的方法(非完整哦)
set certbot_id $spawn_id
expect "(Y)es/(N)o:"
send -- "Y\r"
#运行另一个process
sleep 2
spawn ./update_demo.sh
expect eof
catch wait result
#反回certbot
set spawn_id $certbot_id
sleep 5
expect "Press Enter to Continue"
#interact
send -- "\r"
expect eof
我大至就是透过这些东西搞定wildcard的证书自动更新。
至於API端就另话了,留代下回分解。
我采用的工具是python FastAPI。
我下这标题感觉比较耸动,因该会吸引人来看😛
除了分享外,我也在实验会不会影响点击率。
No Comment
Post your comment