判斷域名是否適合申請Let's Encrypt憑證的思路 / How to Judge Whether a Domain Name Is Suitable for Applying for Let's Encrypt Certificate
在真的用certbot去Let's Encrypt申請憑證之前,最好自己先檢查一下。
速率限制 / Rate limits
https://letsencrypt.org/docs/rate-limits/
我們這次要申請的是獨立網域的SSL憑證,不是帶有星號(*)的廣域域名(wildcard DNS)。前者需要完成http-01挑戰,要讓HTTP服務能夠讓Let's Encrypt連上;後者需要完成dns-01挑戰,要調整DNS伺服器的設定,讓Let's Encrypt能夠確認。後者的做法複雜很多,我之前有在bind9完成過,不過真的很不容易。有興趣詳情請看「如何使用 Certbot 命令列工具建立免費的 TLS/SSL 頂層網域憑證」。
Let's Encrypt為了避免過於頻繁的申請導致伺服器負荷過大,在一定時間內僅有一定數量的申請。這種限制叫做速率限制(Rate Limits)。在眾多限制規則中,主要限制是每週每個註冊網域最多只頒發50張憑證。而你可以在一張憑證中包含最多100個網站網域名稱。也就是說,正常狀況下,每個網域可以為5000個域名申請SSL憑證。
在設置過程中比較麻煩的是「網域驗證失敗」限制。每個帳號、每個域名、每小時最多失敗5次。在建置伺服器初期不斷調整的時候,很容易達到這個限制。特別是Kubernates跟Docker都有自動重啟restart的設置。如果伺服器因為申請憑證失敗了導致自動重啟,那一瞬間就會達到「網域驗證失敗」次數限制。
檢查域名 / Check a domain
為此,在真的去申請Let's Encrypt的憑證之前,最好先自己仔細檢查你的域名是否真的可以用。根據我的經驗總結,檢查包含了三個階段。通過所有階段才算是一個可以真的用來申請憑證的域名。
Phase 1. 檢查域名是否真的註冊 / Check a domain name is registered
只有真的在DNS伺服器上註冊的域名才能註冊。
檢查的方法可以用nslookup。nslookup在Debian中包含在「dnsutils」套件裡面。安裝方式如下:
apt-get install -y dnsutils
使用nslookup檢查blog.pulipuli.info的語法如下:
nslookup blog.pulipuli.info
如果有正常註冊,nslookup回傳的訊息如下:
Server: 127.0.0.53
Address: 127.0.0.53#53
Non-authoritative answer:
blog.pulipuli.info canonical name = ghs.google.com.
Name: ghs.google.com
Address: 142.251.42.243
Name: ghs.google.com
Address: 2404:6800:4012:2::2013
換個例子來說。我們可以改查「nslookup not-registered.pulipuli.info」。如果沒有正常註冊,nslookup回傳的訊息如下:
Server: 127.0.0.53
Address: 127.0.0.53#53
** server can't find not-registered.pulipuli.info: NXDOMAIN
另一個情況是域名對應的IP設定為本機端,此時nslookup回傳的內容如下:
Server: 127.0.0.53
Address: 127.0.0.53#53
Name: test-b222.pulipuli.info
Address: 127.0.0.1
可以注意到最後的「Address: 127.0.0.1」,這顯然也是不合格的網域。
結果判斷 / if ... else for the result
如果成功,它會回傳狀態碼0。你可以在Bash中搭配變數「$?」和if判斷式一起使用。以下程式中,如果狀態碼為0,表示nslookup有找到這個域名,可進行後續檢查流程;如果不為0,則認為此域名不能申請憑證:
if [ $? == 0 ]; then
# Domain name is registered.
exit 1
else
# Domain name is not registered yet.
fi
以下各階段都會用到這個技巧,下面就不再贅述。
Phase 2. 確認伺服器的網路是否可連線 / Check the server's network can be connected
一般來說,域名對應的IP應該是你現在要設定的伺服器,而這伺服器應該是要能夠正常地被網際網路上其他電腦連線。所以這一步我們要確認域名對應到的IP是否能夠正常連線。
檢查的方法可以用ping。ping在Debian中包含在「iputils-ping」套件裡面。安裝方式如下:
apt-get install -y iputils-ping
使用ping檢查blog.pulipuli.info的語法如下,這裡加上了連線次數(-c)跟超時限制(-t)的設定:
ping -c 1 -t 10 blog.pulipuli.info
如果能夠正常連線,ping回傳的訊息如下:
PING ghs.google.com (142.251.42.243) 56(84) bytes of data.
64 bytes from tsa01s11-in-f19.1e100.net (142.251.42.243): icmp_seq=1 ttl=115 time=9.41 ms
--- ghs.google.com ping statistics ---
1 packets transmitted, 1 received, 0% packet loss, time 0ms
rtt min/avg/max/mdev = 9.411/9.411/9.411/0.000 ms
同樣換個例子來看看。我們改查「ping -c 1 -t 10 not-registered.pulipuli.info」。如果不能連線的話,ping回傳的訊息如下:
ping: not-registered.pulipuli.info: Name or service not known
找不到的話,它一樣會回傳非0的狀態碼。可以搭配上述的「$?」變數來做進一步判斷。
Phase 3. 檢查伺服器的HTTP服務是否正在運作 / Check if the server's HTTP service is running
這個階段跟一般人的認知有很大的差別,需要特別注意一下。
狀況1: 需要網頁伺服器正常運作 / HTTP service should run
https://blog.hellojcc.tw/setup-https-with-letsencrypt-on-nginx/
很多人使用certbot申請Let's Encrypt憑證,同時搭配certbot的自動設定網頁伺服器的功能來使用。通常大家申請的語法會是如下,這是要求certbot申請兩個域名的SSL憑證,並且自動調整ngnix伺服器:
certbot --nginx -d hellojcc.tw -d www.hellojcc.tw
如果是這種狀況,在此階段需要確認域名的HTTP服務能夠正常運作。
狀況2: 需要確保網頁伺服器不能運作 / HTTP service should not run
https://openfind.zendesk.com/hc/zh-tw/articles/5337452018831-Certbot-install-setup
但我的狀況比較特殊。我需要自行控制我的網頁伺服器,設定好之後才會讓certbot去驗證。此時certbot的語法通常如下:
certbot certonly --webroot -w /webmail/mbase/htdocs -d mbtrial.openfind.com.tw -m support@openfind.com.tw --agree-tos
如果是這種狀況,在此階段需要確認域名的HTTP服務沒有在運作,以此確保網頁伺服器需要使用的80連結埠沒有被佔用,後續才能手動設定給Let's Encrypt檢查的網頁伺服器。
檢查網頁伺服器是否正常運作 / Check the HTTP service is running
檢查的方法可以用curl。curl就是套件名稱,安裝方式如下:
apt-get install -y curl
使用curl檢查http://blog.pulipuli.info的語法如下,這裡加上了超時限制(--connect-timeout)的設定:
curl --connect-timeout 5 http://blog.pulipuli.info
如果網頁伺服器正常運作,curl會回傳網頁的內容:
<HTML>
<HEAD>
<TITLE>Moved Permanently</TITLE>
</HEAD>
<BODY BGCOLOR="#FFFFFF" TEXT="#000000">
<H1>Moved Permanently</H1>
The document has moved <A HREF="https://blog.pulipuli.info/">here</A>.
</BODY>
</HTML>
同樣換個例子來看看。我們改查「curl --connect-timeout 5 http://not-registered.pulipuli.info」。如果網頁伺服器運作的話,curl回傳的訊息如下:
curl: (6) Could not resolve host: not-registered.pulipuli.info
找不到的話,它一樣會回傳非0的狀態碼。可以搭配上述的「$?」變數來做進一步判斷。接著就請針對你想要執行certbot的不同狀況來選擇即可。
小結 / In closing
(圖片來源:certbot)
如果一個域名通過了上述三階段的檢查,表示該域名基本上能夠用來申請Let's Encrypt憑證。後續就可以搭配certbot或其他網頁伺服器設定來處理即可。
你有申請過SSL憑證嗎?
你有申請過程中遇過什麼問題呢?
歡迎下面留言分享喔!