前言
“如果能把 SSL 證書附加在域名上,那該多酷啊!” —— 凱麗
Certbot 是 Let's Encrypt 的官方工具。
本文主要介紹如何使用 Let's Encrypt 的 Certbot 工具免費生成、修改、更新和撤銷 SSL 證書。
簡略介紹一點證書的配置。
本文沒有提及泛域名證書的生成。
要求網站已經正確配置了伺服器、DNS 等,已經能夠正常訪問。
本文操作環境為 Ubuntu。
安裝
可部分參照官網。
在官網首頁,選擇伺服器和作業系統後,會給出相應的安裝以及生成證書的命令。
這裡只看安裝的部分:
sudo apt-get update
sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot
複製程式碼
檢視是否安裝成功:
certbot --version
複製程式碼
或
letsencrypt --version
複製程式碼
輸出的都是 certbot 的版本號:
certbot 0.25.0
複製程式碼
生成證書
重要:在開始之前,先看一下本文末尾關於頻率限制的說明。
在前一節裡,官網給出安裝命令後,也給出了生成證書的命令,比如:
為 Nginx 伺服器生成:
sudo certbot --nginx
複製程式碼
為 Apache 伺服器生成:
sudo certbot --apache
複製程式碼
在生成證書後,可以選擇讓 certbot 自動修改對應伺服器軟體的配置檔案,包括將 80
埠的請求重定向至 443
,啟用相應模組,啟用配置檔案等。
自動修改後配置檔案的寫法是值得參考一下的。
但是!為了更深入地瞭解 Let's Encrypt,也為了能夠更靈活地操作證書,我們不採用這種快捷方式。而是僅僅生成證書,並手動配置。
方法有 standalone
和 webroot
兩種。
standalone 與 webroot 的區別
無論哪種方式,certbot 都需要驗證域名,但是實現的方式不同,這也是兩者有區別的根本原因。
standalone
方法生成和更新證書的時候,certbot 需要使用 443 或者 80 埠來驗證域名,因此導致需要暫時停止伺服器。這種方式不需要給出網站根目錄webroot
方法沒有上述問題。不過webroot
方法配置略微複雜,並且需要給出網站根目錄
webroot
方式之所以不需要 80
或 443
埠,是因為它的實現方式是,在網站根目錄中生成一個臨時子目錄 .well-known/acme-challenge
,然後從 certbot 的伺服器向這個路徑傳送請求,如果請求成功,那麼驗證通過。
這篇文章簡單介紹了幾個 webroot 模式可能會遇到的問題。
standalone 模式
基本命令為:
sudo letsencrypt certonly --standalone
複製程式碼
需要使用 80
或 443
埠,可以通過 --preferred-challenges
指定要使用的埠,只要其中一個埠空閒就可以。
但是說實話,難道存在其中一個埠是空閒的情況嗎
使用 80
埠:
--preferred-challenges http
複製程式碼
使用 443
埠:
--preferred-challenges tls-sni
複製程式碼
使用 -d
指定要生成證書的域名。可以新增多個域名,使用逗號分隔,或者使用多個 -d
。兩種方法效果相同。
多個域名時,同一個主域名下的多個子域名是可以的,沒有試過多個不同的主域名是什麼效果。
執行生成命令:
sudo letsencrypt certonly --standalone -d example.com,www.example.com
複製程式碼
第一次使用時,會詢問郵箱、是否同意服務條款、是否接受推送內容。
推薦如實填寫郵箱,因為證書即將過期時會通過郵件通知。
推送內容不接受就好了。
證書即將過期的通知郵件:
感覺這個通知不太準,很多次收到郵件,但是登入檢視了一下並沒有。
也(很)可能是因為當時沒用
--staging
導致生成了很多證書...
2019年4月26日更新:
媽的今天面試演示專案的時候證書過期。。
回來一看有過郵件通知,但是沒在意。。這是一個狼來了的故事
如果看到以下資訊說明證書生成成功:
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for example.com
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/example.com/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/example.com/privkey.pem
Your cert will expire on 2018-09-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
複製程式碼
可以使用 certbot certificates
命令檢視當前證書的資訊:
Found the following certs:
Certificate Name: example.com
Domains: example.com, www.example.com
Expiry Date: 2018-09-26 00:42:47+00:00 (VALID: 89 days)
Certificate Path: /etc/letsencrypt/live/example.com/fullchain.pem
Private Key Path: /etc/letsencrypt/live/example.com/privkey.pem
複製程式碼
可以看到,生成了1個證書,-d
後面的第一個域名為證書名和所在目錄的目錄名,該證書包含了兩個域名 example.com
和 www.example.com
。
這些域名都可以使用該證書。
共生成了四個檔案:
- cert.pem
- chain.pem
- fullchain.pem
- privkey.pem
/etc/letsencrypt/archive/example.com
目錄儲存原件。
/etc/letsencrypt/live/example.com
目錄儲存檔案的軟連結,可以理解為快捷方式。
live/
中的檔案貌似不只是原件的軟連結那麼簡單,但是沒有仔細研究。
privkey.pem 為私鑰,務必妥善保管。
webroot 模式
這種方式需要給出網站根目錄作為引數。從這名字 webroot
應該也能看出來。
基本命令:
certbot certonly --webroot -w /path/to/webroot -d www.example.com -d example.com
複製程式碼
其中,-w
是網站的根目錄,-d
是要生成證書的域名。
注意,-d
列出的域名的根路徑必須全部與 -w
的值相同。
如果要為根路徑不同的多個域名生成證書,那麼只需要在後面再新增 -w
及其對應的 -d
即可:
certbot certonly --webroot -w /path/to/webroot1 -d www.example.com -d example.com -w /path/to/webroot2 -d other.example.net -d another.other.example.net
複製程式碼
其他內容不再贅述,參考前面 standalone
部分。
泛域名證書
從 0.22.0
版本開始,Let's Encrypt 支援生成泛域名證書。
TODO
配置伺服器
以 Apache 和 Nginx 為例。這裡只介紹一下最基本的配置。
首先,這裡是官方文件給出的上面生成的4個檔案與伺服器配置項的對應關係。
Apache 配置
# apache < 2.4.8
SSLCertificateKeyFile privkey.pem
SSLCertificateFile cert.pem
SSLCertificateChainFile chain.pem
複製程式碼
# apache >= 2.4.8
SSLCertificateKeyFile privkey.pem
SSLCertificateFile fullchain.pem
複製程式碼
官方文件是這麼寫的,但是現在最新版本才2.4.3,哪來的2.4.8?
啟用 SSL 模組:
a2enmod ssl
複製程式碼
修改配置檔案:
<VirtualHost *:443>
ServerName example.com
SSLCertificateKeyFile privkey.pem
# apache < 2.4.8
SSLCertificateFile cert.pem
SSLCertificateChainFile chain.pem
# apache >= 2.4.8
SSLCertificateFile fullchain.pem
...
</VirtualHost>
複製程式碼
重啟 Apache:
service apache2 restart
複製程式碼
Nginx 配置
ssl_certificate_key privkey.pem;
ssl_certificate fullchain.pem;
複製程式碼
修改配置檔案:
server {
listen 443 ssl;
server_name example.com;
ssl_certificate fullchain.pem;
ssl_certificate_key privkey.pem;
...
}
複製程式碼
重啟伺服器:
service nginx restart
複製程式碼
更進一步的配置:《分享一個 HTTPS A+ 的 nginx 配置》
修改證書
上面使用 standalone
方法已經生成了域名 example.com
和 www.example.com
的證書,證書名為 example.com
。
如果現在又要為 a.example.com
生成證書,那麼可以生成一張新的證書,也可以選擇新增到現有的證書 example.com
裡。
certbot 官方文件提供了簡單的示例:
certbot --expand -d existing.com -d example.com -d newdomain.com
複製程式碼
雖然示例使用了 --expand
選項,但是後面推薦使用的是 --cert-name
,因為 --expand
只能用來新增域名,而 --cert-name
更靈活,既可以新增也可以刪除。
官方文件沒有提供 --cert-name
的示例,下面介紹一下。
命令的大致結構是:
certbot certonly --cert-name certname -d a.domain.com,b.domain.com
複製程式碼
--cert-name
選項的引數是現有證書的證書名,-d
選項的引數是證書包含的域名。
注意,多個域名用逗號分隔,並且中間不能有空格。
即,不能是:
-d a.domain.com, b.domain.com
,而應該是-d a.domain.com,b.domain.com
。
新增域名
現在開始為證書名為 example.com
、包含 example.com
和 www.example.com
兩個域名的證書新增一個新的域名 a.example.com
。
certbot certonly --cert-name example.com -d example.com,www.example.com,a.example.com
複製程式碼
會出現提示:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
How would you like to authenticate with the ACME CA?
-------------------------------------------------------------------------------
1: Spin up a temporary webserver (standalone)
2: Place files in webroot directory (webroot)
-------------------------------------------------------------------------------
Select the appropriate number [1-2] then [enter] (press 'c' to cancel):
複製程式碼
選擇 1
。或者在命令中新增 --standalone
選項,可以跳過這一步。
Plugins selected: Authenticator standalone, Installer None
-------------------------------------------------------------------------------
You are updating certificate example.com to include new domain(s):
+ a.example.com
You are also removing previously included domain(s):
(None)
Did you intend to make this change?
-------------------------------------------------------------------------------
(U)pdate cert/(C)ancel:
複製程式碼
選擇 u
,執行更新即可。
刪除域名
現在證書中包含了三個域名,如果要從中刪除域名www.example.com
,執行的命令為:
certbot certonly --cert-name example.com -d example.com,a.example.com
複製程式碼
想要刪除的域名,不在 -d
後列出來即可。
其他
可以發現,上面在修改由 standalone
方式生成的證書時,仍然可以選擇 standalone
和 webroot
。
那麼看來證書的生成方式是可以改變的。
但是沒有試過,感興趣的同學可以試一下。
更新證書
從證書資訊中可以看到,證書有效期為90天。在證書到期前需要進行更新。
可以手動進行更新:
certbot renew
複製程式碼
根據 certbot 官方文件,該命令只會更新30天內即將過期的證書。對其他的證書沒有影響。
證書更新可以使用 crontab 等設定計劃任務實現自動更新,比如每天執行一次 renew
命令。
但是注意,由 standalone
方法生成的證書,更新時也需要使用 80
或 443
埠,因此可能需要(不如說一定需要)在執行 renew
前先關閉伺服器,結束後再重新開啟。
撤銷證書
使用 revoke
選項:
sudo certbot revoke --cert-path /etc/letsencrypt/live/CERTNAME/cert.pem
複製程式碼
前面說過,archive
目錄儲存了證書原件,live
目錄儲存了證書的軟連結。
這裡的路徑只能是 live
,不能是 archive
,否則會報錯。
撤銷成功後,會詢問是否刪除證書檔案和證書所在目錄:
-------------------------------------------------------------------------------
Would you like to delete the cert(s) you just revoked?
-------------------------------------------------------------------------------
(Y)es (recommended)/(N)o:
複製程式碼
推薦選擇 Yes
自動刪除。如果選擇 No
,之後需要執行 certbot delete
來刪除檔案。
根據 certbot 官方文件,無論自動還是手動,最後都需要把相關檔案刪掉。
如果沒有刪除,那麼 archive
和 live
兩個目錄及其中的檔案就仍然存在。執行 certbot certificates
仍然能顯示該證書的資訊,不過後面會註明已經失效 INVALID
。但是,在執行證書更新的時候,已經撤銷的證書還會被更新。
其他
頻率限制
Staging Environment - Let's Encrypt 官方文件
Let's Encrypt 為證書申請的頻率做了限制,每個主域名每週不超過20次。
如果達到這個 rate limits,不能夠再繼續生成了,會報錯。
所以如果只是為了學習和測試,最好使用 Let's Encrypt 提供的 Staging Environment(模擬環境),沒有頻率限制。
只要在執行命令時加上 --staging
選項就可以了。
等會用了再玩真的。
關於 HTTPS
百度 LAVAS 專案中關於 HTTPS 的介紹:使用 HTTPS,寫得挺好的。
打個廣告
我的其他文章: