先來寫這篇手動更新的紀錄,是因為我考思未來再寫一篇自動更新。
這樣才有對對照組嘛,為何要叫逆天,
就我所知道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