acme.sh 自動更新 RSA、ECC 雙證書實踐
acme.sh 自動更新 RSA、ECC 雙證書實踐
預覽目錄
不知不覺,一年的萬用字元證書就快到期了。作為一名技術人員,我是不準備續費了。恰巧知道一個acme.sh的專案,它是一個實現 ACME 協議的客戶端,能夠向支援 ACME 協議的 CA 申請證書(如 Letsencrypt)。最重要的是它對接了大多數的域名服務商,能夠通過域名服務商提供的 API,自動的新增 DNS 驗證記錄進行全自動頒發證書,還可以模擬 HTTP 伺服器進行檔案驗證。so,不管你的證書期限是 90 天,還是更短,再也不用擔心證書過期的問題了。
至於 ACME 協議是什麼?Automatic Certificate Management Environment 自動化證書管理環境,通過它我們可以實現證書的自動申請以及部署,可以大大的節省人員的管理及額外的配置工作。
ACME 的通訊過程通過一系列的 API 進行,你可以通過類似https://example.com/directory
獲取可以請求的 API 列表,如Letsencrypt。當然再通訊過程中採取了很多的安全措施,如在 RFC 文件中你可能會看 JWT、JWS、JOSE、JWK、reply-nonce等名詞,看起來就陌生。如果你不是技術人員,也大可不必去研究那些東西,知道怎麼用就行。
安裝 acme.sh
好了,廢話不多說。acme.sh 下載非常的簡單,官方提供了 2 中方式:
-
通過執行線上指令碼安裝:
$ 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 目錄($HOME):~/.acme.sh/。之後所有生成的證書也會放在這裡。
- 建立別名:
acme.sh=~/.acme.sh/acme.sh
。 - 建立 cron 每日任務去檢查是否有證書需要更新。 如:
0 0 * * * "/home/user/.acme.sh"/acme.sh --cron --home "/home/user/.acme.sh" > /dev/null
使用 acme.sh
如何使用?acme.sh 的功能非常的強大,使用方式確非常的簡單。提醒,該指令碼需要在你的伺服器下執行。官方地址:How-to-issue-a-cert。
關於 ECC 證書,你只需要再末尾新增--keylength ec-256
。如:
$ acme.sh --issue -w /home/wwwroot/example.com -d example.com -d www.example.com --keylength ec-256
可選長度有:
- ec-256 (prime256v1, “ECDSA P-256”)
- ec-384 (secp384r1, “ECDSA P-384”)
- ec-521 (secp521r1, “ECDSA P-521”, which is not supported by Let’s Encrypt yet.)
申請證書
單域名
$ acme.sh --issue -d example.com -w /home/wwwroot/example.com
多域名
$ acme.sh --issue -d example.com -d www.example.com -d cp.example.com -w /home/wwwroot/example.com
這裡的-w
指定的是 web 伺服器根目錄,請確保有寫入許可權。example.com就是你要簽發的域名,建議主域放在第一個。頒發好的證書會放在~/.acme.sh/example.com/
。證書將會每 60 天自動更新。
注意:這裡僅申請頒發證書,之後還有安裝步驟。當然這些步驟均可實現自動化。指定 web 根目錄是為了寫入驗證檔案,故請保證根目錄的檔案可以通過 URL 訪問到。
Standalone 模式
這個模式會自己啟動一個 HTTP/HTTPS 的伺服器,供 CA 進行域名驗證。所以,你需要確保80⁄443埠是沒有被佔用的。
# 確保你的 80 埠未被佔用
$ acme.sh --issue -d example.com --standalone
# 當然你也可以指定埠,但前提是你會通過代理或負載均衡轉發到該埠。
# 因為 letsencrypt 可只會訪問 80 埠哦。
$ acme.sh --issue -d example.com --standalone --httpport 88
當然還有--tls
模式,使用 443 埠。
Apache/Nginx 模式
這個模式會檢查 apache/nginx 現有的配置。在證書頒發成功後,自動的更改配置檔案,達到自動申請自動部署的目的,非常的方便:
$ acme.sh --issue -d example.com --apache
$ acme.sh --issue -d example.com --nginx
DNS 手動模式
$ acme.sh --issue --dns -d example.com -d www.example.com -d cp.example.com
會有類似以下資訊:
Add the following txt record:
Domain:_acme-challenge.example.com
Txt value:9ihDbjYfTExAYeDs4DBUeuTo18KBzwvTEjUnSwd32-c
Add the following txt record:
Domain:_acme-challenge.www.example.com
Txt value:9ihDbjxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
Please add those txt records to the domains. Waiting for the dns to take effect.
你需要手動新增如上域名記錄。
如果你需要更新證書,請執行:
$ acme.sh --renew -d example.com
DNS API模式
通過域名服務商提供的 API 模式,進行動態的新增 DNS 記錄,實現自動證書更新及部署。這也是本部落格採用的方式(未採用 Nginx 方式也是有原因的)。
DNS API支援列表,涵蓋了國內外主流的域名服務商。具體的使用方法你需要根據服務商進行不同設定How to use DNS API。
這裡提一下,阿里雲:
- 進入控制檯,滑鼠指向你的使用者名稱。
- 點選 accesskeys,點選繼續 AccessKey。
- 建立 accessKey。
沒有用 RAM 子賬號,因為我確實沒有找到 DNS 那塊可授予的許可權,如果你找到方法,請告訴我,非常感謝。
混合模式
該模式下,為每個域名指定不同的驗證方式,但example.com
和www.example.com
必須在同一根目錄。
$ acme.sh --issue \
-d example.com -d www.example.com -w /home/wwwroot/ \
-d bb.com --dns dns_cf \
-d cc.com --apache \
-d dd.com -w /home/wwwroot/dd.com
安裝證書
再頒發證書之後,我們可能需要將證書拷貝到指定位置。那麼我們需要使用到--install-cert
命令,請儘量避免手動拷貝證書。
# Apache
$ acme.sh --install-cert -d example.com \
--cert-file /path/to/certfile/in/apache/cert.pem \
--key-file /path/to/keyfile/in/apache/key.pem \
--fullchain-file /path/to/fullchain/certfile/apache/fullchain.pem \
--reloadcmd "service apache2 force-reload"
# Nginx
$ acme.sh --install-cert -d example.com \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd "service nginx force-reload"
這裡會將私鑰、證書、證書鏈拷貝到指定位置,成功後執行--reloadcmd
命令。請確保有執行這些命令的許可權。
當然你也不用擔心證書更新的問題,在證書 60 天之後,會自動更新,更新後就會執行--reloadcmd
的命令。
這裡還有一些 hook 功能,請檢視幫助$ acme.sh -h
,如,--renew-hook
(每次證書成功更新後執行的命令)等。
更新證書
使用該工具的應該都是衝著其強大的自動更新部署功能來的。當然,如果你想手動更新:
# RSA
$ acme.sh --renew -d example.com --force
# ECC
acme.sh --renew -d example.com --force --ecc
全自動更新
為了實現全自動更新證書,我們需要新增一個--renew-hook
的命令,它的作用就是能夠在證書成功頒發後執行命令。
如:
$ acme.sh --issue --dns dns_ali -d example.com -d www.example.com -k ec-256 \
--renew-hook "acme.sh --install-cert -d example.com --ecc \
--key-file /path/to/keyfile/in/nginx/key.pem \
--fullchain-file /path/to/fullchain/nginx/cert.pem \
--reloadcmd \"service nginx force-reload\""
解讀,這裡使用ali_dns
為example.com
和www.example.com
頒發ecc
證書。在證書到期前 30 天,acme.sh
將再次執行這條命令進行證書的更新。更新後執行--renew-hook
將證書安裝到指定地方/path/to/keyfile/in/nginx/
,安裝好之後會執行--reloadcmd
命令,讓 nginx 重新載入證書。這樣就完成了證書的自動更新,不過首次證書頒發後,需要你進行證書的安裝。
安全測試和評分
當我們證書部署好了之後,如何確定是否已經部署成功(博主部署的是雙證書),Nginx 配置是否安全呢。
推薦使用以下三個線上服務來檢測站點 HTTPS 配置情況:
ssllabs
網站地址:https://www.ssllabs.com。國外網站,檢測內容非常的詳細,包括證書、協議以及客戶端模擬和相容行。檢視測試結果 »
httpsecurityreport
網站地址:https://httpsecurityreport.com。檢測網站的一些 Header 的設定是否安全等。檢視測試結果 »
myssl
網站地址:https://myssl.com。這個是國內的檢測站點,應該是新出來的,和 ssllabs 相似。不過關於證書的功能更多,速度也是快很多。檢視測試結果 »