1. 程式人生 > 實用技巧 >acme.sh 自動更新 RSA、ECC 雙證書實踐

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 進行域名驗證。所以,你需要確保80443埠是沒有被佔用的。

# 確保你的 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.comwww.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_dnsexample.comwww.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 相似。不過關於證書的功能更多,速度也是快很多。檢視測試結果 »