acme.sh 實現了 acme 協議, 可以從 letsencrypt 生成免費的證書.
主要步驟:
- 安裝 acme.sh
- 生成證書
- copy 證書到 nginx/apache 或者其他服務
- 更新證書
- 更新 acme.sh
- 出錯怎么辦, 如何調試
下面詳細介紹.
1. 安裝 acme.sh
安裝很簡單, 一個命令:
curl https://get.acme.sh | sh -s email=my@example.com
啟用別名
source ~/.bashrc
普通用戶和 root 用戶都可以安裝使用. 安裝過程進行了以下幾步:
把 acme.sh 安裝到你的 home 目錄下:
~/.acme.sh/
并創建 一個 shell 的 alias, 例如 .bashrc,方便你的使用: alias acme.sh=~/.acme.sh/acme.sh
自動為你創建 cronjob, 每天 0:00 點自動檢測所有的證書, 如果快過期了, 需要更新, 則會自動更新證書.
更高級的安裝選項請參考: https://github.com/Neilpang/acme.sh/wiki/How-to-install
安裝過程不會污染已有的系統任何功能和文件, 所有的修改都限制在安裝目錄中: ~/.acme.sh/
2. 生成證書
acme.sh 實現了 acme 協議支持的所有驗證協議. 一般有兩種方式驗證: http 和 dns 驗證.
1. http 方式需要在你的網站根目錄下放置一個文件, 來驗證你的域名所有權,完成驗證. 然后就可以生成證書了.
acme.sh --issue -d mydomain.com -d www.mydomain.com --webroot /home/wwwroot/mydomain.com/
只需要指定域名, 并指定域名所在的網站根目錄. acme.sh 會全自動的生成驗證文件, 并放到網站的根目錄, 然后自動完成驗證. 最后會聰明的刪除驗證文件. 整個過程沒有任何副作用.
如果你用的 apache服務器, acme.sh 還可以智能的從 apache的配置中自動完成驗證, 你不需要指定網站根目錄:
acme.sh --issue -d mydomain.com --apache
如果你用的 nginx服務器, 或者反代, acme.sh 還可以智能的從 nginx的配置中自動完成驗證, 你不需要指定網站根目錄:
acme.sh --issue -d mydomain.com --nginx
注意, 無論是 apache 還是 nginx 模式, acme.sh在完成驗證之后, 會恢復到之前的狀態, 都不會私自更改你本身的配置. 好處是你不用擔心配置被搞壞, 也有一個缺點, 你需要自己配置 ssl 的配置, 否則只能成功生成證書, 你的網站還是無法訪問https. 但是為了安全, 你還是自己手動改配置吧.
如果你還沒有運行任何 web 服務, 80 端口是空閑的, 那么 acme.sh 還能假裝自己是一個webserver, 臨時聽在80 端口, 完成驗證:
acme.sh --issue -d mydomain.com --standalone
更高級的用法請參考: https://github.com/Neilpang/acme.sh/wiki/How-to-issue-a-cert
2. 手動 dns 方式, 手動在域名上添加一條 txt 解析記錄, 驗證域名所有權.
這種方式的好處是, 你不需要任何服務器, 不需要任何公網 ip, 只需要 dns 的解析記錄即可完成驗證. 壞處是,如果不同時配置 Automatic DNS API,使用這種方式 acme.sh 將無法自動更新證書,每次都需要手動再次重新解析驗證域名所有權。
acme.sh --issue --dns -d mydomain.com \--yes-I-know-dns-manual-mode-enough-go-ahead-please
然后, acme.sh 會生成相應的解析記錄顯示出來, 你只需要在你的域名管理面板中添加這條 txt 記錄即可.
等待解析完成之后, 重新生成證書:
acme.sh --renew -d mydomain.com \--yes-I-know-dns-manual-mode-enough-go-ahead-please
注意第二次這里用的是 --renew
dns 方式的真正強大之處在于可以使用域名解析商提供的 api 自動添加 txt 記錄完成驗證.
acme.sh 目前支持 cloudflare, dnspod, cloudxns, godaddy 以及 ovh 等數十種解析商的自動集成.
以 dnspod 為例, 你需要先登錄到 dnspod 賬號, 生成你的 api id 和 api key, 都是免費的. 然后:
export DP_Id="1234"export DP_Key="sADDsdasdgdsf"acme.sh --issue --dns dns_dp -d aa.com -d www.aa.com
證書就會自動生成了. 這里給出的 api id 和 api key 會被自動記錄下來, 將來你在使用 dnspod api 的時候, 就不需要再次指定了. 直接生成就好了:
acme.sh --issue -d mydomain2.com --dns dns_dp
更詳細的 api 用法: https://github.com/Neilpang/acme.sh/blob/master/dnsapi/README.md
3. copy/安裝 證書
前面證書生成以后, 接下來需要把證書 copy 到真正需要用它的地方.
注意, 默認生成的證書都放在安裝目錄下: ~/.acme.sh/, 請不要直接使用此目錄下的文件, 例如: 不要直接讓 nginx/apache 的配置文件使用這下面的文件. 這里面的文件都是內部使用, 而且目錄結構可能會變化.
正確的使用方法是使用 --install-cert 命令,并指定目標位置, 然后證書文件會被copy到相應的位置, 例如:
Apache example:
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 example:
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"
(一個小提醒, 這里用的是 service nginx force-reload, 不是 service nginx reload, 據測試, reload 并不會重新加載證書, 所以用的 force-reload)
Nginx 的配置 ssl_certificate 使用 /etc/nginx/ssl/fullchain.cer ,而非 /etc/nginx/ssl/.cer ,否則 SSL Labs 的測試會報 Chain issues Incomplete 錯誤。
–install-cert命令可以攜帶很多參數, 來指定目標文件. 并且可以指定 reloadcmd, 當證書更新以后, reloadcmd會被自動調用,讓服務器生效.
詳細參數請參考: https://github.com/Neilpang/acme.sh#3-install-the-issued-cert-to-apachenginx-etc
值得注意的是, 這里指定的所有參數都會被自動記錄下來, 并在將來證書自動更新以后, 被再次自動調用.
4. 查看已安裝證書信息
acme.sh --info -d example.com
# 會輸出如下內容:DOMAIN_CONF=/root/.acme.sh/example.com/example.com.conf
Le_Domain=example.com
Le_Alt=no
Le_Webroot=dns_ali
Le_PreHook=
Le_PostHook=
Le_RenewHook=
Le_API=https://acme-v02.api.letsencrypt.org/directory
Le_Keylength=
Le_OrderFinalize=https://acme-v02.api.letsencrypt.org/acme/finalize/23xxxx150/781xxxx4310
Le_LinkOrder=https://acme-v02.api.letsencrypt.org/acme/order/233xxx150/781xxxx4310
Le_LinkCert=https://acme-v02.api.letsencrypt.org/acme/cert/04cbd28xxxxxx349ecaea8d07
Le_CertCreateTime=1649358725
Le_CertCreateTimeStr=Thu Apr 7 19:12:05 UTC 2022
Le_NextRenewTimeStr=Mon Jun 6 19:12:05 UTC 2022
Le_NextRenewTime=1654456325
Le_RealCertPath=
Le_RealCACertPath=
Le_RealKeyPath=/etc/acme/example.com/privkey.pem
Le_ReloadCmd=service nginx force-reload
Le_RealFullChainPath=/etc/acme/example.com/chain.pem
5. 更新證書
目前證書在 60 天以后會自動更新, 你無需任何操作. 今后有可能會縮短這個時間, 不過都是自動的, 你不用關心.
請確保 cronjob 正確安裝, 看起來是類似這樣的:
crontab -l56 * * * * "/root/.acme.sh"/acme.sh --cron --home "/root/.acme.sh" > /dev/null
6. 關于修改ReloadCmd
目前修改ReloadCmd沒有專門的命令,可以通過重新安裝證書來實現修改reloadCmd的目的。 此外,安裝證書后,相關信息是保存在~/.acme.sh/example.com/example.conf文件下的,內容就是acme.sh --info -d example.com輸出的信息,不過ReloadCmd在文件中使用了Base64編碼。理論上可以通過直接修改該文件來修改ReloadCmd,且修改時,無需Base64編碼,直接寫命令原文acme.sh也可以識別。 不過,example.conf文件的位置和內容格式以后可能會改變!example.conf一直都是內部使用, 后面有可能會改為用 sqlite 或者mysql 格式存儲. 所以一般不建議自己修改。
7. 更新 acme.sh
目前由于 acme 協議和 letsencrypt CA 都在頻繁的更新, 因此 acme.sh 也經常更新以保持同步.
升級 acme.sh 到最新版 :
acme.sh --upgrade
如果你不想手動升級, 可以開啟自動升級:
acme.sh --upgrade --auto-upgrade
之后, acme.sh 就會自動保持更新了.
你也可以隨時關閉自動更新:
acme.sh --upgrade --auto-upgrade 0
8. 出錯怎么辦:
如果出錯, 請添加 debug log:
acme.sh --issue ..... --debug
或者:
acme.sh --issue ..... --debug 2
請參考: https://github.com/Neilpang/acme.sh/wiki/How-to-debug-acme.sh
在DNS驗證模式下如果debug中出現諸如"timed out"等字樣可能是因為GFW攔截了相應請求,需要添加http(s) proxy環境變量。(請按照自己實際設定修改)
export http_proxy="socks5h://localhost:1081" && export https_proxy="socks5h://localhost:1081"
如果是使用docker則完整示例配置如下:
docker run --rm -it \-v "/etc/acme":/acme.sh \-e "CF_Token=[填入自己的信息]" \-e "CF_Account_ID=[填入自己的信息]" \-e "CF_Zone_ID=[填入自己的信息]" \-e http_proxy="socks5h://[代理A]:1234" \-e https_proxy="socks5h://[代理A]:1234" \--network container:[代理A]\neilpang/acme.sh \--issue -d example.com --dns dns_cf --debug
上述例子中使用cloudflare的DNS來簽發證書,并通過把acme.sh鏈接到容器[代理A],來轉發curl請求(請按照自己實際設定修改)
最后, 本文并非完全的使用說明, 還有很多高級的功能, 更高級的用法請參看其他 wiki 頁面.
https://github.com/Neilpang/acme.sh/wiki