:::

判斷域名是否適合申請Let's Encrypt憑證的思路 / How to Judge Whether a Domain Name Is Suitable for Applying for Let's Encrypt Certificate

2023-0409-145542.png

在真的用certbot去Let's Encrypt申請憑證之前,最好自己先檢查一下。


速率限制 / Rate limits

https://letsencrypt.org/docs/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

bitmap.png

(圖片來源:certbot)

如果一個域名通過了上述三階段的檢查,表示該域名基本上能夠用來申請Let's Encrypt憑證。後續就可以搭配certbot或其他網頁伺服器設定來處理即可。


你有申請過SSL憑證嗎?

你有申請過程中遇過什麼問題呢?

歡迎下面留言分享喔!