出處:https://blog.csdn.net/kikajack/article/details/80408145
Let’s Encrypt 在 18 年 1 月份推出了 ACME v2,支持通配符域名證書,對小網站、個人站長的友好度進一步增加。
常用的兩種安裝方式對比
ACME 協議支持的驗證協議一般有兩種:
- http 驗證:必須有可以正常運行的服務器和公網 IP。驗證時,需要在你的網站根目錄下放一個文件來驗證域名所有權,完成驗證後就可以生成證書了。
- dns 驗證:不需要服務器和公網 IP。只需要為域名添加一條 txt 解析記錄來驗證域名所有權。
Let’s Encrypt 通配符證書的兩種安裝方式:
- acme.sh:對於 http 驗證,會自動在網站根目錄生成驗證文件, 然後自動完成驗證,最後自動刪除驗證文件。對於 dns 驗證,如果域名解析商提供 API,則可以自動藉助這個 API 通過工具添加 txt 記錄完成驗證(如果不提供 API 則無法自動化,目前騰訊雲、阿里雲都支持)。此外,還會自動生成更新域名的定時任務。
- certbot-auto:對於域名驗證這一步,需要手工操作。且更新域名的定時任務也需要自己寫。
通過 acme.sh 獲取通配符域名
acme.sh 的所有相關文件(包括安裝文件、申請到的證書等)都在 ~/.acme.sh/ 這一個目錄中。
- 安裝 acme.sh
在線安裝
地址:https://github.com/Neilpang/get.acme.sh
curl https://get.acme.sh | sh
或者:
wget -O - https://get.acme.sh | sh
從Git安裝
git clone https://github.com/Neilpang/acme.sh.git
cd ./acme.sh
./acme.sh --install
安裝過程包含 3 個動作:
- 創建並複製 acme.sh 到你的家目錄 $HOME:~/.acme.sh/。所有的證書都會放到這個目錄中
- 創建別名: acme.sh=~/.acme.sh/acme.sh
- 創建每天的定時任務檢查證書,如果快要到期了會自動更新
定時任務示例:
0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null
- 驗證
安裝完成後,需要重新打開終端,acme.sh 命令才能生效。
root@v1:~# acme.sh -h
- 生成證書
Http方式
acme.sh 會自動在網站根目錄生成驗證文件, 然後自動完成驗證,最後自動刪除驗證文件。
需要指定域名和域名對應的網站根目錄:
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
對於 nginx 服務器,acme.sh 還可以智能的從 nginx 配置中自動完成驗證,不需要指定網站根目錄:
acme.sh --issue -d mydomain.com --nginx
域名獲取後,需要手動修改 Nginx 配置文件。
如果沒有運行任何 web 服務,80 端口是空閒的,那麼 acme.sh 可以運行為 webserver,臨時監聽 80 端口,完成驗證:
acme.sh --issue -d mydomain.com --standalone
DNS方式
如果域名解析商提供 API,則可以自動藉助這個 API 通過工具添加 txt 記錄完成驗證。
- 對於阿里雲:
# 替換成從阿里雲獲取的 API 參數
export Ali_Key="666"
export Ali_Secret="888"
# 換成自己的域名
acme.sh --issue --dns dns_ali -d kikakika.com -d *.kikakika.com
- 對於騰訊雲:
# 替換成從 DNSPod 獲取的 API 參數
export DP_Id="1234"
export DP_Key="sADDsdasdgdsf"
# 換成自己的域名
acme.sh --issue --dns dns_dp -d kikakika.com -d *.kikakika.com
- 對於其他平臺
可以參考這裡:https://github.com/Neilpang/acme.sh/tree/master/dnsapi
DNS 生效需要一段時間,acme.sh 設置的是等待兩分鐘。
acme.sh 會保存 API 參數並生成定時任務,用於每天驗證證書是否即將過期,並及時更新。下面是通過 crontab -e 看到的新增的定時任務:
16 0 * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
- 安裝證書
證書生成後,需要把證書 copy 到真正需要用它的地方。
默認生成的證書都放在安裝目錄 ~/.acme.sh/ 下,但是請不要直接使用。而是使用 --installcert 命令安裝證書。
使用 --installcert 命令安裝證書
使用 --installcert 命令安裝證書時,證書文件會被複制到相應的位置:
acme.sh --installcert -d kikakika.com \
--key-file /etc/nginx/ssl/kikakika.key \
--fullchain-file /etc/nginx/ssl/fullchain.cer \
--reloadcmd "systemctl reload nginx.service"
示例:
[root@VM_139_74_centos ~]# acme.sh --installcert -d kikakika.com \
> --key-file /etc/nginx/ssl/kikakika.key \
> --fullchain-file /etc/nginx/ssl/fullchain.cer \
> --reloadcmd "systemctl reload nginx.service"
[Tue May 22 16:35:20 CST 2018] Installing key to:/etc/nginx/ssl/kikakika.key
[Tue May 22 16:35:20 CST 2018] Installing full chain to:/etc/nginx/ssl/fullchain.cer
[Tue May 22 16:35:20 CST 2018] Run reload cmd: systemctl reload nginx.service
[Tue May 22 16:35:20 CST 2018] Reload success
當證書更新以後,reloadcmd 中的命令會被自動調用,讓服務器加載更新後的證書。
--installcert 命令可以攜帶很多參數,來指定目標文件。這裡指定的所有參數都會被自動記錄下來, 並在將來證書自動更新以後, 被再次自動調用。
注意,對於 Nginx,需要通過 systemctl reload nginx.service 來重新加載證書。
- 配置 Nginx
Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer,而非 /etc/nginx/ssl/
我將所有流量統一導入 https://www.kikakika.com,示例如下:
server {
listen 443 ssl;
server_name www.kikakika.com;
index index.html;
root /home/kikakika/www;
ssl on;
ssl_certificate /etc/nginx/ssl/fullchain.cer;
ssl_certificate_key /etc/nginx/ssl/kikakika.key;
ssl_session_timeout 5m;
}
server {
listen 80;
server_name www.kikakika.com;
return 301 https://$host$request_uri;
}
server {
listen 80;
server_name kikakika.com;
return 301 https://www.kikakika.com$request_uri;
}
server {
listen 443 ssl;
server_name kikakika.com;
return 301 https://www.kikakika.com$request_uri;
}
常見問題
遇到問題不要慌,通過 --debug 2 選項可以直接在終端上顯示詳細日誌:
acme.sh --issue --debug 2 --dns dns_dp -d kikakika.com -d *.kikakika.com
域名 API 需要登錄正確的解析平臺開啟
問題描述:獲取證書一直失敗,分析日誌發現有“The login token ID is invalid”這麼一句話:
...
[Tue May 22 14:43:48 CST 2018] Http already initialized.
[Tue May 22 14:43:48 CST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header --trace-ascii /tmp/tmp.LzYzrZRjvQ -g '
[Tue May 22 14:43:48 CST 2018] _ret='0'
[Tue May 22 14:43:48 CST 2018] response='{"status":{"code":"10002","message":"The login token ID is invalid","created_at":"2018-05-22 14:43:50"}}'
[Tue May 22 14:43:48 CST 2018] invalid domain
[Tue May 22 14:43:48 CST 2018] Error add txt for domain:_acme-challenge.kikakika.com
[Tue May 22 14:43:48 CST 2018] pid
[Tue May 22 14:43:48 CST 2018] No need to restore nginx, skip.
[Tue May 22 14:43:48 CST 2018] _clearupdns
[Tue May 22 14:43:48 CST 2018] skip dns.
[Tue May 22 14:43:48 CST 2018] _on_issue_err
[Tue May 22 14:43:48 CST 2018] Please check log file for more details: /root/.acme.sh/acme.sh.log
...
後來查找資料才發現,騰訊雲和 DNSPod 是兩個獨立的平臺。對於騰訊雲上的域名,域名解析並不在騰訊雲,仍然需要登錄 DNSPod 開啟 API:
登錄 DNSPod 添加 API 後,這次就顯示“Action completed successful”了。然後等待 120 秒,等 DNS 解析生效:
[Tue May 22 14:54:12 CST 2018] _postContentType
[Tue May 22 14:54:12 CST 2018] Http already initialized.
[Tue May 22 14:54:12 CST 2018] _CURL='curl -L --silent --dump-header /root/.acme.sh/http.header --trace-ascii /tmp/tmp.rkflZDBcOD -g '
[Tue May 22 14:54:13 CST 2018] _ret='0'
[Tue May 22 14:54:13 CST 2018] response='{"status":{"code":"1","message":"Action completed successful","created_at":"2018-05-22 14:54:15"},"record":{"id":"361406913","name":"_acme-challenge","status":"enabled","weight":null}}'
[Tue May 22 14:54:13 CST 2018] Sleep 120 seconds for the txt records to take effect
通配符域名申請的證書,不支持根域名
問題描述:對 *.kikakika.com 申請了通配符域名,但是在訪問 https://kikakika.com 是時候出問題。
解決辦法:必須在申請證書時同時指定根域名 kikakika.com 和通配符域名 *.kikakika.com 兩個域名,這樣生成的證書才是完整的通配符證書:
acme.sh --issue --debug 2 --dns dns_dp -d kikakika.com -d *.kikakika.com
下面是導致出問題的申請通配符證書的命令:
acme.sh --issue --debug 2 --dns dns_dp -d *.kikakika.com
閱讀更多 會技術的葛大爺 的文章