certbot 是用來申請 Let's Encrypt 免費 SSL 證書
一般的免費 SSL 證書,好像都是使用 Let's Encrypt 頒發的證書。官網地址:
https://letsencrypt.org/
Let's Encrypt 使用 ACME 協議來認證我們域名,並頒發證書。要獲取 Let's Encrypt 證書,我們需要選擇一個 ACME 客戶端軟件。官方推薦的是 Certbot。
Certbot 官網地址:
https://certbot.eff.org
安裝 certbot,我們可以查看官方文檔:
https://certbot.eff.org/docs/install.html
簡述下安裝步驟:
最好的方式是:
使用官方給我們提供的 Certbot 包,在官網首頁可以下載,選擇對應的 web 服務和系統。例如,我的是:
Nginx + CentOS 7
然後下方就會給出我們詳細的安裝步驟:
/*
下面主要是官網的一些翻譯
*/
安裝
Certbot 是打包在 EPEL(Extra Packages for Enterprise Linux)。要使用 Certbot,我們必須首先啓用 EPEL 倉庫。在 RHEL 或 Oracle Linux,我們還必須開啓可選的通道。
注意:
如果我們正在 EC2 上使用 EHEL,我們可以通過運行下面的命令來啓用可選通道:
$ yum -y install yum-utils
$ yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
之後,我們可以運行下面的命令來安裝 Certbot:
$ sudo yum install certbot python2-certbot-nginx
安裝 DNS 插件
Certbot 的 DNS 插件可用於我們的系統。這些插件可用於自動從 Let's Encrypt 的 ACMEv2 服務器獲取通配符證書。要使用其中一個插件,我們必須爲要獲取證書的域名配置 DNS,該證書適用於 Certbot 具有插件的 DNS 提供程序。可以在鏈接('https://certbot.eff.org/docs/using.html#dns-plugins')找到插件列表,以及關於使用它們的更多信息。要安裝插件,運行上面的安裝命令,但需要將命令中 certbot python2-certbot-nginx 替換爲 python2-certbot-dns-PLUGIN,其中 PLUGIN 是要安裝的插件的名稱。例如,對於 RFC2136 插件,命令應該是 python2-certbot-dns-rfc2136。
開始使用
Certbot 有一個 Nginx 插件, 在許多平臺上都支持, 並自動進行證書安裝。
$ sudo certbot --nginx
運行該命令,可以讓我們獲得一個證書, 而且 Certbot 會自動編輯我們的 Nginx 配置來提供服務。如果我們希望自己手動來配置 Nginx,可以使用 certonly 子命令:
$ sudo certbot --nginx certonly
如果我們想要使用 Let's Encrypt 新的 ACMEv2 服務,來獲取一個 '通配符' 證書,我們還需要安裝 Certbot 的 DNS 插件。確保我們已經通過上面的 '安裝 DNS 插件' 說明,安裝了 DNS 服務,並運行下面的命令:
$ sudo certbot -a DNS插件名 -i nginx -d "*.example.com" -d example.com --server https://acme-v02.api.letsencrypt.org/directory
自動續訂
Certbot 可以配置爲,在證書過期之前自動續訂。因爲 Let's Encrypt 證書的有效期是 90 天,因此我們需要在過期前,重新續訂。可以運行下面的命令來測試證書的自動續訂:
$ sudo certbot renew --dry-run
如果上面命令沒有報錯,我們可以通過添加一個 cron job 或 systemd timer 運行下面的命令,來支持自動續訂:
certbot renew
注意:
如果我們配置了一個 cron 或 systemd job,建議每天運行2次(在我們的證書續訂或撤銷之前,它不會執行任何操作。但定期運行,將使我們的網站有機會保持在線狀態,以防 Let's Encrypt 由於某種原因異常觸發了撤銷)。
下面是一個 cron job 示例,每天的中午和半夜運行:
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
DNS 插件
如果想要從 Let's Encrypt 上獲取通配符證書,或在目標 Web 服務器以外的計算機上運行 certbot,可以使用 Certbot 的 DNS 插件之一。
這些插件不包含在默認的 Certbot 安裝中,必須單獨安裝。雖然 DNS 插件當前不能與 certbot-auto 一起使用,但它們在許多 OS 包管理器和 Docker 鏡像中都可以使用。訪問 https://certbot.eff.org,瞭解我們系統上使用 DNS 插件的最佳方法。
安裝完成後,我們可以在下方的鏈接中,找到關於如何使用每個插件的文檔:
...
文檔列表
...
手動插件(manual)
如果想要在目標 web 服務器以外的機器上運行 certbot 來獲取證書,或者自己執行域名驗證步驟,我們可以使用 'manual' 插件。沒有圖形化界面,我們可以通過在命令行上指定 certbot 和 --manual,使用該插件來獲取證書。這要求我們複製和粘貼命令到另一個終端會話,該會話可能在另一臺機器上。
manual 插件可以使用 http 或 dns challenge(挑戰)。我們可以使用 --preferred-challenges 選項來指定我們想要的 challenge
http challenge 要求我們,將包含指定名稱和指定內容的文件,直接放到頂級目錄(web 根目錄)下的 '/.well-known/acme-challenge/' 目錄。本質上,同 webroot 插件一樣,但是不是自動的。
當使用 dns challenge 時,certbot 將要求我們在域名下,放置一條包含了指定內容的 TXT DNS 記錄。包含我們希望頒發證書的主機名,由 '_acme-challenge' 預先設置。
例如,對於 example.com 域名,文件條目如下所示:
_acme-challenge.example.com. 300 IN TXT "gfj9Xq...Rg85nM"
此外,我們可以通過使用 --manual-auth-hook 和 --manual-cleanup-hook 標誌,指定腳本,用於準備驗證&執行身份認證程序,和(/或)在其後進行清理。這在鉤子部分中有更深入的描述。
結合插件
有時候我們可能想要將不同的身份認證程序和安裝器程序結合起來。爲此,我們可以使用 --authenticator 或 -a 來指定身份認證插件,使用 --installer 或 -i 來指定安裝器插件
例如,我們可以使用,用於身份認證的 webroot 插件,和用於安裝的 apache 插件,來生成證書。
certbot run -a webroot -i apache -w /var/www/html -d example.com
或者,我們可以使用,用於身份認證的 manual 插件,和用於安裝的 nginx 插件,來生成證書。
certbot run -a manual -i nginx -d example.com
第三方插件
其他開發人員也提供了許多針對客戶端的第三方插件。許多是測試/實驗版本,但有些已經廣泛使用
...
第三方插件列表
...
certbot-auto(簡單瞭解下)
安裝 certbot-auto
https://certbot.eff.org/docs/install.html#id6
如果上面安裝 certbot 的方法不可用,才使用 certbot-auto,它會在我們的系統上自動安裝 Certbot:
系統要求:
Python 2.7 或 3.4+,運行在類 unix 系統
默認需要 root 權限,因爲要寫入到 /etc/letsencrypt, /var/log/letsencrypt, /var/lib/letsencrypt。綁定到 80 和 443 端口(如果使用 standalone 插件),讀取並修改 web 服務器配置(如果使用 apache 或 nginx 插件)。
如果避免用 root 用戶來運行 ACME 客戶端,可以選擇 letsencrypt-nosudo(https://github.com/diafygi/letsencrypt-nosudo) 或 simp_le(https://github.com/zenhack/simp_le)
Apache 插件當前需要 augeas 1.0 版本的操作系統;當前支持基於 Debian, Fedora, SUSE, Gentoo 和 Darwin 的現代操作系統.
此外,可以通過驗證 certbot-auto 腳本的數字簽名來驗證它是否完整。這需要安裝 gpg2,在許多 Linux 分發版中存在,以 gnupg 或 gnupg2 命名。
使用 certbot-auto 安裝,需要 512MB 的 RAM,來構建依賴。通過預構建的系統包來安裝,可以避免該問題。我們也可以臨時設置一個交換文件(swap file)。查看下面的 'Python 虛擬環境問題' 獲取更多信息。
安裝 certbot-auto:
wget https://dl.eff.org/certbot-auto
sudo mv certbot-auto /usr/local/bin/certbot-auto
sudo chown root /usr/local/bin/certbot-auto
chmod 0755 /usr/local/bin/certbot-auto
/usr/local/bin/certbot-auto --help
檢查腳本完整性:
wget -N https://dl.eff.org/certbot-auto.asc
gpg2 --keyserver pool.sks-keyservers.net --recv-key A2CFB51FA275A7286234E7B24D17C995CD9775F2
gpg2 --trusted-key 4D17C995CD9775F2 --verify certbot-auto.asc /usr/local/bin/certbot-auto
certbot-auto 命令自動更新到最新的客戶端版本。由於 certbot-auto 是 certbot 的包裝器,它接受與 certbot 完全一樣的標誌和參數。更多信息,查看 certbot 命令行選項(https://certbot.eff.org/docs/using.html#command-line-options)
要獲得完整的命令行幫助,可以輸入:
./certbot-auto --help all
看文檔,外加查找資料,最終配置成功。這裏記錄下每一個步驟,以後按照這個步驟安裝、配置即可:
1.安裝 certbot
訪問首頁:https://certbot.eff.org,選擇我們使用的 web 服務和操作系統,然後會給出默認的安裝命令
這裏以 'nginx' 和 'centos7' 爲例:
yum -y install yum-utils
在 RHEL 或 Oracle Linux 上,還需要執行(我們使用的 centos 不需要):
yum-config-manager --enable rhui-REGION-rhel-server-extras rhui-REGION-rhel-server-optional
yum install certbot python2-certbot-nginx
// 注意,這裏安裝的是 nginx 插件
yum install certbot python2-certbot-nginx
2.通過 certbot 生成證書
certbot --nginx certonly [-d 域名1,域名2]
1>參數解析,很重要:
--nginx - 表示我們之前選擇的 nginx 服務
certonly - 默認 certbot 會自動修改我們 nginx 的配置,添加上 ssl 配置,我們想要手動配置 ssl,就需要設置該選項
-d - 指定域名,可以同時指定多個,以 ',' 分隔
2>此外,直接運行上述命令,可能會報錯:
Error while running nginx -c /usr/local/nginx/nginx.conf -t
原因:
找不到 nginx 配置文件,默認 certbot 會找 /etc/nginx/nginx.conf 配置文件
我們配置的 nginx 位置可能不同,需要改成自己的 nginx 路徑
解決方法:
查看 certbot 幫助,應該提供了修改路徑的選項
certbot -h // certbot 命令幫助
certbot -h nginx // nginx 插件幫助
提供了2個選項:
--nginx-server-root
nginx 服務根目錄,默認是 '/etc/nginx'
/*
這裏還是個坑,因爲 certbot 好像只是找 nginx.conf,所以,當我們的配置文件,不是放在 nginx 的根目錄,仍然找不到
所以,這裏應該是 'nginx 配置文件所在的目錄'
例如,我的 nginx 配置路徑是:
/usr/local/nginx/conf/
*/
--nginx-ctl
nginx 命令二進制文件名,默認是 'nginx'
所以,我們最終的命令是:
certbot --nginx certbot --nginx-server-root /usr/local/nginx/conf/
3>執行可能還會報錯:
ImportError: No module named 'requests.packages.urllib3'
原因:
requests庫版本問題
解決方法:
sudo pip install requests urllib3 pyOpenSSL --force --upgrade
sudo pip install --upgrade --force-reinstall 'requests==2.6.0'
4>期間可能還會發生報錯:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe7 in position 1: ordinal not in range(128)
原因:
nginx.conf 出現特殊字符
解決方法:
參考:https://github.com/certbot/certbot/issues/5236
grep -r -P '[^\x00-\x7f]' /usr/local/nginx/conf/nginx.conf
或
grep -r -P '[^\x00-\x7f]' /usr/local/nginx/conf/vhosts/xxx.conf(虛擬主機配置)
上面的命令是,查看有沒有 \x00-\x7f 的特殊字符,有的話,將特殊字符刪除(中文就是一種特殊字符)
3.續訂證書
certbot renew // 續訂所有證書
certbot renew --cert-name 證書名 // 續訂 '指定證書'
// 查看 renew 子命令
certbot -h renew
4.自動續訂證書
因爲 Let's Encrypt 證書有效期爲 3 個月,我們不可能實時查看,需要配置一個計劃任務,在過期前,自動續訂:
0 0,12 * * * python -c 'import random; import time; time.sleep(random.random() * 3600)' && certbot renew
5.申請 '通配符' 證書
上面的流程,只能申請指定域名的證書。如果我們想要申請 '通配符' 證書,還需要安裝額外的 ' DNS 插件'。
插件列表在 'https://certbot.eff.org/docs/using.html#dns-plugins' 可以查看到
裏面列出的插件基本都是國外的,我們可能都不適用。
官方也提供了一個 'manual - 手動認證插件'(這個我沒自己測試)
certbot certonly --nginx -d 通配符域名(*.xxx.com) --manual --preferred-challenges dns --server https://acme-v02.api.letsencrypt.org/directory
但是手動的方式,有問題,就是自動續訂,過期了,還需要 '手動認證'...,沒法做到自動生成
但是,官方提供了 '--manual-auth-hook' 和 '--manual-cleanup-hook' 2個鉤子,我們可以寫腳本來實現自動生成(參考下方筆記 6)
6.在網上找了個文章,寫的非常好,推薦下:
https://www.cnblogs.com/redirect/p/10140248.html
它裏面提到了一個 'manual' dns 插件腳本,可以幫我們自動訂閱 '通配符' 證書,地址:
https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
裏面需要注意的是
1>文檔使用的是 certbot-auto,我們安裝的是 certbot,兩者命令是一致的。certbot-auto 是對 certbot 的封裝。
2>au.sh 腳本,我們需要配置下
1>我服務器是 '騰訊雲',需要配置 '騰訊雲' 的 APP_KEY(key) 和 APP_SECRET(token)
2>我使用的是 php 腳本,配置下 php 命令路徑
列出所有命令:
1>安裝
cd ~ && mkdir src && cd src
git clone https://github.com/ywdblog/certbot-letencrypt-wildcardcertificates-alydns-au
cd certbot-letencrypt-wildcardcertificates-alydns-au
chmod 0777 au.sh
2.配置 DNS API 祕鑰
需要在不同的雲平臺申請(見文檔)
3.配置 au.sh
key
token
php_cmd
4.測試申請證書(有 --dry-run 選項)
certbot certonly -d *.xxx.com --manual --preferred-challenges dns --dry-run --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"
5.測試無誤,正式申請證書(去除 --dry-run 選項)
certbot certonly -d *.xxx.com --manual --preferred-challenges dns --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"
6.配置自動續訂,加入命令到 crontab
# 注意只有成功renew證書,纔會重新啓動nginx
1 1 */1 * * root certbot renew --manual --preferred-challenges dns --deploy-hook "service nginx restart" --manual-auth-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy add" --manual-cleanup-hook "/root/src/certbot-letencrypt-wildcardcertificates-alydns-au/au.sh php txy clean"
參考文章:
https://www.cnblogs.com/redirect/p/10140248.html(非常不錯)
https://www.seanzhao.me/2018/06/21/certbot-manual.html#%E4%BF%AE%E6%94%B9%E6%9B%B4%E6%96%B0%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6
https://blog.csdn.net/diyiday/article/details/82791663
https://www.seanzhao.me/2018/06/21/certbot-manual.html#%E4%BF%AE%E6%94%B9%E6%9B%B4%E6%96%B0%E9%85%8D%E7%BD%AE%E6%96%87%E4%BB%B6