本篇文章更新時間:2025/01/21
如有資訊過時或語誤之處,歡迎使用 Contact 功能通知。
一介資男的 LINE 社群開站囉!歡迎入群聊聊~
如果本站內容對你有幫助,歡迎使用 BFX Pay 加密貨幣 或 新台幣 贊助支持。
說到免費 SSL/TLS 憑證,應該沒人不知道 Let's Encrypt。但知道是一回事,使用這服務又是另一回事。
以前我都是直接找教學文,照工具說明套流程取得憑證。這幾天連假找素材學習的時候就來把這玩意兒給好好瞭解一遍。
- Let's Encrypt 是起頭的組織單位,但他不是唯一一個提供這服務的組織單位。(另一個是 ZeroSSL)
- 申請使用這樣的憑證服務,主要就是過一個叫 ACME 的標準協議。
- 既然是一個開放的協議,那代表大家都可以去實作這一套請求的工具,所以市面上有不少工具,但主流常見的就屬 Certbot(Python),與 ACME.sh(Shell)
- 使用這些工具選擇上最大的差異,就是「環境」。對環境最包容(跨平台)以及需求最少,整合其他服務的彈性越高,自然能受到大家喜愛。
- 承上,其次就是驗證方式。取得授權的憑證也要確保是真的是有人有意願去使用,而非造假的冒用。主要提供有兩種做法,HTTP 驗證,透過請求你網站來確定是你發起請求的,再來就是 DNS 紀錄更新,驗證你有這網域的所有或管理權,都是很合理的做法。
- Wildcard 萬用字元憑證的申請「只能」透過 DNS 方式驗證。
- 很多人不知道,如果透過 HTTP 的「公開網站驗證」其實也等於你的網站網域也是公開的,可以透過 crt.sh 工具查看。
看到最後一點,為什麼「驗證方式」是比較少人關注的細節我個人認為主要還是分成兩個重點:
- 都是使用在網站上,而網站本來就是公開,覺得沒差。
- 不一定有辦法操作或是有能力理解 DNS 驗證要做什麼,牽扯到了對 DNS 技術的認知。
如果你對 DNS 技術或設定不陌生,如果你對資安風險有概念,我會建議使用 DNS 的驗證方式。
主要是現在網站一透過 HTTP 驗證後就有紀錄,然後有心人士就能順藤摸瓜測試你的網站,對於一個剛上線甚至只是剛開站什麼防護都沒有的網站,尤其危險!
剛好寫前一篇 [VPS] 使用通道服務 frp / sish 把 localhost 本機防火墻內 WordPress 網站對外公開的方法 筆記時 sish
作者有提到這套 DNSroboCert 工具,就是主打 DNS 驗證,而且支援多家 DNS 業者的 API 串接,不輸我常用的 ACME.sh 工具。(目前也還沒看到有這套這麼完整支援度的專案)
下面筆記使用 DNSroboCert 的方法:
環境上 Host 我都是使用 Linux 為主,然後這套有支援搭配 Docker 來解決 Python 環境建立的問題。
內容目錄
使用 DNSroboCert 的前置準備
建立設定檔案的存放目錄
mkdir -p /etc/dnsrobocert
touch /etc/dnsrobocert/config.yml
建立 Let's Encrypt 設定與憑證的存放目錄
mkdir -p /etc/letsencrypt
安裝 Docker 作業環境
curl -fsSL https://get.docker.com -o get-docker.sh && sh get-docker.sh
下載 DNSroboCert 容器
docker pull adferrand/dnsrobocert:latest
編輯 DNSroboCert 設定組態檔案
專案文件其實寫得很清楚了,我這邊也不多提,就純解釋我的設定。
編輯設定檔案: vi /etc/dnsrobocert/config.yml
內容:
draft: false
acme:
email_account: [email protected] #註冊 Let's Encrypt 服務用的信箱
staging: false
certificates:
- domains:
- ssl.mxp.tw #要驗證取得憑證的網域
- '*.ssl.mxp.tw' #萬用字元 wildcard 網域字串使用單引號包起來
name: mxp.tw #在 Let's Encrypt 的 live 中資料夾名稱
profile: cloudflare #使用哪一家 DNS 業者的服務名稱
deploy_hook : /path/to/host/script > /dev/null
profiles: #定義 DNS 服務業者的資料區塊
- name: cloudflare #設定的名稱,對應上方使用
provider: cloudflare #這邊要對應文件
provider_options:
auth_token: #輸入取得的授權權杖
auth_username: emai@cloudflare #Cloudflare 帳號
zone_id: #輸入網域區域ID
使用的時候記得移除上述的
#
與後方註解內容
如果搭配的是 Cloudflare API token 方法,auth_username
參數就可以不用帶入,然後搭配下方的 curl 指令測試驗證 API 權限的設置是否正常:
curl -X GET "https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records" \
-H "Authorization: Bearer ACCESS_TOKEN" \
-H "Content-Type: application/json"
這份文件可以定義很多組網域以及很多組 DNS 服務業者,彈性很大!
確認有沒有支援你正在使用的 DNS 業者可以到這頁面查詢: Providers available
啟動 DNSroboCert 取得憑證使用
docker run -itd --name letsencrypt-dns \
-v /var/run/docker.sock:/var/run/docker.sock \
-v /etc/letsencrypt/:/etc/letsencrypt \
-v /etc/dnsrobocert/config.yml:/etc/dnsrobocert/config.yml \
--restart always \
adferrand/dnsrobocert:latest
執行指令後可以使用 docker logs letsencrypt-dns
來查看運作的紀錄。
沒意外就能看到完成驗證的紀錄,並且在 /etc/letsencrypt/live/
找到請求的網域憑證了。
這個容器預設兩天檢查一次有沒有需要續約憑證(renew),放著當常駐服務跑,有需要加入新的網域處理就是更新完設定檔案後 restart
重啟過容器就好。
直接在 Host 上安裝的方法
基礎環境安裝
apt install python3-full -y
apt install pipx -y
pipx ensurepath
pipx install dnsrobocert
source ~/.bashrc
到這邊,其實就已經可以使用下面指令測試執行狀況:
dnsrobocert -c /etc/dnsrobocert/config.yml -d /etc/letsencrypt
設定系統服務
新增服務:
sudo vi /etc/systemd/system/dnsrobocert.service
服務內容組態:
[Unit]
Description=dnsrobocert
After=network.target
[Service]
ExecStart=/root/.local/bin/dnsrobocert -c /etc/dnsrobocert/config.yml -d /etc/letsencrypt
Restart=always
User=root
[Install]
WantedBy=multi-user.target
組態檔案 與 憑證路徑 都預設為前段的設定。
啟動服務:
// 重載設定
sudo systemctl daemon-reload
// 啟用設定
sudo systemctl start dnsrobocert.service
// 啟用服務
sudo systemctl enable dnsrobocert.service
// 確保執行狀態
sudo systemctl status dnsrobocert.service
確認設定與執行正確與否:
// 查看執行紀錄
journalctl -u dnsrobocert.service
// 查看即時紀錄
journalctl -u dnsrobocert.service -f
後記
確認過 DNS 驗證不會出現公開紀錄後,也算是解決一個心頭問題。而 Docker 容器開著固定處理申請憑證與續約也是很乾淨,這點好滿意啊~ 真的是可以考慮來換掉原本的處理方式了。
不過在運作這套服務的時候要確認作業環境是否會相容,像是如果選擇運作在 Docker 容器中的話就很適合搭配 Docker 安裝方式,但如果還是在 Host 本地主機上操作的話,就比較適合使用安裝在本機上作業。
主要影響到的就是 deploy_hook
這個參數設定,會有 scope 運作範圍的問題,免得憑證更新了,但其他服務會沒有更新連動到。
同場加映另一款憑證管理工具 Lego 也很棒,完整支援 ACME 協議,也能做到 DNS 驗證部分。