前言
眾所周知 HTTPS 是保證 HTTP 通訊安全的協(xié)議,網(wǎng)站啟用 HTTPS 可以避免很多安全性的問題, 而且 Chrome 瀏覽器 從 68 版本開始直接將 HTTP 網(wǎng)站標記為不安全了。
所以把網(wǎng)站升級成 HTTPS 自然是大勢所趨,不過啟用 HTTPS 有個最重要的問題是 HTTPS 證書要花錢!如果每年額外花錢去購買 HTTPS 證書,那也是一筆很大的開銷。那么有沒有免費的HTTPS證書可以用呢,查了下資料有個叫Let’s Encrypt的項目就提供了免費簽發(fā) HTTPS 證書的服務,這里記錄下如何使用Let’s Encrypt來簽發(fā)證書。
certbot 介紹
certbot是用于從 Let's Encrypt 獲取證書的命令行工具,代碼開源在github上。
使用certbot命令行工具可以輕松的實現(xiàn)HTTPS證書簽發(fā),在簽發(fā)證書之前,需要證明簽發(fā)的域名是屬于你控制的,目前certbot有兩種驗證方式:
-
HTTP
HTTP 方式就是certbot會生成一個特定的文件名和文件內(nèi)容,要求放在你對應域名下對應路徑(/.well-known/acme-challenge/)下,然后certbot再通過 HTTP 請求訪問到此文件,并且文件內(nèi)容與生成時候的一致。</br></br>例如:
certbot生成文件名check和內(nèi)容!@#$%^,你需要申請的域名為baidu.com,則certbot訪問http://baidu.com/.well-known/acme-challenge/check來校驗是否與生成的內(nèi)容一致。 -
DNS
DNS 則是certbot生成一段特定的文本,要求在你對應域名中配置一條對應子域名(_acme-challenge)的TXT類型解析記錄。</br></br>例如:
certbot生成內(nèi)容!@#$%^,你需要申請的域名為baidu.com,則需要添加一條_acme-challenge.baidu.com的TXT類型解析記錄,值為之前生成的內(nèi)容。
在域名驗證通過之后,certbot就可以簽發(fā)HTTPS證書了,注意在此驗證步驟基礎上,certbot提供了很多開箱即用的自動驗證方案,但是都不符合我的需求,原因是我需要支持通配符域名的證書,但是這種證書只支持DNS驗證方式,而官方提供的DNS插件中并沒有支持我用的阿里云DNS,所以只能自己去實現(xiàn) 阿里云的 DNS 自動校驗。
使用 certbot 簽發(fā) HTTPS 證書
通過官網(wǎng)教程可以選擇對應操作系統(tǒng),并獲取安裝步驟:

這里我選擇的Debian 9,根據(jù)官網(wǎng)的提示進行安裝:
sudo apt-get install certbot -t stretch-backports
注:如果install失敗可以先執(zhí)行下 apt-get update
開始簽發(fā)證書
certbot certonly --cert-name pdown.org -d *.pdown.org,*.proxyee-down.com --manual --register-unsafely-without-email --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
這里簽發(fā)了一個支持*.pdown.org和*.proxyee-down.com通配符域名的證書,注意如果是通配符域名證書需要指定--server https://acme-v02.api.letsencrypt.org/directory
示例:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Registering without email!
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Please read the Terms of Service at
https://letsencrypt.org/documents/LE-SA-v1.2-November-15-2017.pdf. You must
agree in order to register with the ACME server at
https://acme-v02.api.letsencrypt.org/directory
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(A)gree/(C)ancel: A
Obtaining a new certificate
Performing the following challenges:
dns-01 challenge for pdown.org
dns-01 challenge for proxyee-down.com
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
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.pdown.org with the following value:
Axdqtserd184wvJc86Dxen386UXqbK2wrgb-*******
Before continuing, verify the record is deployed.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Press Enter to Continue
這里會生成一串隨機字符并阻塞住,需要去設置一條對應的 TXT 類型的 DNS 解析記錄再繼續(xù),在設置好之后可以用nslookup進行本地驗證:
nslookup -type=txt _acme-challenge.pdown.org
服務器: UnKnown
Address: 192.168.200.200
非權威應答:
_acme-challenge.pdown.org text =
"Tit0SAHaO3MVZ4S-d6CjKLv6Z-********"
本地驗證通過之后按回車鍵繼續(xù),接著 Let's Encrypt 就會校驗這個 DNS 解析記錄是否正確,校驗通過后就會進行下一個域名的驗證直到全部驗證通過。
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/pdown.org/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/pdown.org/privkey.pem
Your cert will expire on 2019-12-02. 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
當驗證通過的時候會輸出證書生成的目錄,里面會包含證書和對應的私鑰,這里目錄是/etc/letsencrypt/live/pdown.org/。
證書截圖:


這樣證書就生成好了,之后只需要把證書和私鑰配置到nginx中就可以用https訪問了。
使用 certbot hook 自動續(xù)簽
上面證書雖然是生成好了,但是證書的有效期只有三個月,意味著每過三個月就得重新簽發(fā)一個新的證書,一不注意證書就過期了,而且每次手動簽發(fā)都非常的繁瑣需要去手動設置 DNS 解析,所以certbot提供了一種自動續(xù)簽的方案:hook
在創(chuàng)建證書的時候certbot提供了兩個hook參數(shù):
- manual-auth-hook
指定用于驗證域名的腳本文件 - manual-cleanup-hook
指定用于清理的腳本文件,即驗證完成之后
通過自定義這兩個腳本就可以做到自動續(xù)簽了,文檔參考pre-and-post-validation-hooks。
在此基礎上,官方已經(jīng)提供了很多云廠商的自動續(xù)簽方案,但是我用的阿里云官方并沒有提供,于是參照官網(wǎng)文檔,寫了一個基于阿里云的自動續(xù)簽腳本,在驗證域名的腳本中通過阿里提供的 DNS API 添加一條域名解析記錄,在驗證完成之后再把剛剛那條域名解析記錄刪除,命令行調(diào)用如下:
certbot certonly --cert-name pdown.org -d *.pdown.org,*.proxyee-down.com --manual --register-unsafely-without-email --manual-auth-hook /path/to/dns/authenticator.sh --manual-cleanup-hook /path/to/dns/cleanup.sh --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
為了方便使用,提供了一個docker鏡像,通過環(huán)境變量將阿里云 API 調(diào)用的 AK 傳遞就可以生成和續(xù)簽證書了。
- 啟動容器
docker run \
--name cert \
-itd \
-v /etc/letsencrypt:/etc/letsencrypt \
-e ACCESS_KEY_ID=XXX \
-e ACCESS_KEY_SECRET=XXX \
liwei2633/certbot-aliyun
- 首次創(chuàng)建證書
docker exec -it cert ./create.sh *.pdown.org
創(chuàng)建過程中會等待一段時間,來確保 dns 記錄生效,完成之后在/etc/letsencrypt/live目錄下可以找到對應的證書文件
- 續(xù)簽證書
docker exec cert ./renew.sh
代碼開源在github,歡迎 start。
本文首發(fā)于我的博客:https://monkeywie.cn,歡迎收藏!不定期分享
JAVA、Golang、前端、docker、k8s等干貨知識。