申請(qǐng)并部署免費(fèi)的 SSL/TLS 證書
對(duì)于囊中羞澀的我們來(lái)說(shuō),只要能白嫖,就絕不亂花錢。慣常申請(qǐng)免費(fèi) SSL/TLS 證書的途徑有:
- 各大云服務(wù)平臺(tái)限量提供。比如阿里云會(huì)給每個(gè)賬號(hào)每年 20 個(gè)證書的申請(qǐng)額度。缺點(diǎn)是不支持泛域名,且一年(目前已縮短至三個(gè)月)后須重新申請(qǐng)并部署;
- 一些網(wǎng)絡(luò)服務(wù)商如
Cloudflare會(huì)提供自動(dòng)化的證書服務(wù),只要在它們的官網(wǎng)作簡(jiǎn)單配置即可。缺點(diǎn)是流量都要經(jīng)其中轉(zhuǎn),在某些未很好覆蓋的區(qū)域網(wǎng)站性能會(huì)受限; - 直接從免費(fèi)證書頒發(fā)機(jī)構(gòu)(CA)那里申請(qǐng)。通過(guò)腳本可使得獲取、安裝和續(xù)期 SSL/TLS 證書完全自動(dòng)化。缺點(diǎn)是有一定的操作門檻。
本文介紹最后這種方式。
免費(fèi) CA 選擇
免費(fèi) CA,常考慮的有 Let’s Encrypt 和 ZeroSSL。兩者差異可自行網(wǎng)搜,基本上都能滿足我們普通用戶的需求,選擇哪一個(gè)更依賴于申請(qǐng)過(guò)程是否順利。
以 Let’s Encrypt 作一簡(jiǎn)單介紹。它是由 Internet Security Research Group (ISRG) 發(fā)起的公共利益項(xiàng)目,于2016年推出,由 Mozilla, Cisco, Akamai, Linux Foundation, Google, Microsoft, OVH 和其它一些組織支持。這個(gè)項(xiàng)目的主要目標(biāo)是促進(jìn) HTTPS 協(xié)議的普及。
Let’s Encrypt 使用 ACME 協(xié)議來(lái)驗(yàn)證您對(duì)給定域名的控制權(quán)并向您頒發(fā)證書,也就是說(shuō),要獲得 Let’s Encrypt 證書,需要選擇一個(gè) ACME 客戶端。
這里以 acme.sh 為例。acme.sh 實(shí)現(xiàn)了 ACME 協(xié)議, 默認(rèn) CA 是 ZeroSSL。然而筆者在申請(qǐng)時(shí)一直報(bào)Order status is processing, lets sleep and retry,retry 多次后報(bào) 504,不知為何。所以筆者將默認(rèn) CA 設(shè)置為 Let’s Encrypt:acme.sh --set-default-ca --server letsencrypt。
申請(qǐng)并部署證書
安裝 acme.sh
不清楚 docker 模式安裝會(huì)否自動(dòng)續(xù)期,所以直接安裝到宿主機(jī) curl https://get.acme.sh | sh -s email=xxx@xxx。直接安裝會(huì)自動(dòng)創(chuàng)建 cronjob, 每天自動(dòng)檢測(cè)所有的證書, 如果快過(guò)期了, 則會(huì)自動(dòng)更新證書。
如前所述,設(shè)置默認(rèn) CA:acme.sh --set-default-ca --server letsencrypt
申請(qǐng)
在證書申請(qǐng)過(guò)程中,acme.sh 需要確認(rèn)域名屬于你本人,有兩種驗(yàn)證方式:http 和 dns。
- http mode: 支持自動(dòng)更新證書;不支持通配符即泛域名。
- dns mode:支持泛域名;但如果不同時(shí)配置 Automatic DNS API,將無(wú)法自動(dòng)更新證書,每次都需要手動(dòng)再次重新解析驗(yàn)證域名所有權(quán)。所以,如果你有多個(gè)二級(jí)域名需要綁定證書,要么就使用下述 http mode 的指令,要么就去 dns 服務(wù)商處拿到 API Access(可能會(huì)有一些要求)。 參看acme.sh 支持的 dns 服務(wù)商列表。
這里我們以 http mode 為例。
先設(shè)置好 DNS 解析記錄,將待申請(qǐng)證書的域名 A 記錄到服務(wù)器 IP。然后如下腳本申請(qǐng)證書,acme.sh 會(huì)同時(shí)進(jìn)行域名驗(yàn)證。
acme.sh --issue -d demo.com -d www.demo.com -d admin.demo.com --webroot /srv/www/html/
只需要指定域名,并指定對(duì)應(yīng)的網(wǎng)站根目錄,acme.sh 會(huì)自動(dòng)生成驗(yàn)證文件,并放到網(wǎng)站根目錄,然后自動(dòng)完成驗(yàn)證,最后會(huì)刪除驗(yàn)證文件。
如果你用的是直接在宿主機(jī)安裝的 nginx 服務(wù)器,甚至不需要指定網(wǎng)站根目錄。acme.sh 可以智能地依據(jù) nginx 配置自動(dòng)完成驗(yàn)證:
acme.sh --issue -d demo.com ... --nginx
上述腳本的前提是 acme.sh 可以調(diào)用 nginx 指令,否則會(huì)報(bào) nginx command is not found 錯(cuò)誤。所以如果 nginx 是以 docker 方式安裝,這種方式將無(wú)法成功;還是得使用 --webroot 的方式,只要將 nginx 根目錄映射出來(lái)即可,如下:
docker run --name ngix -v /srv/www/html:/usr/share/nginx/html:ro -v /srv/www/nginx.conf:/etc/nginx/nginx.conf:ro -p 80:80 -p 443:443 --network inner_net --restart=always -d --label=sh.acme.autoload.domain=anything nginx:stable-alpine
注意腳本中的 label,用于后續(xù)部署證書時(shí) acme.sh 定位該容器。這里的 anything 可以替換為任意字符。
域名驗(yàn)證無(wú)誤的話,acme.sh 會(huì)去 CA 那里獲取證書,并下載到本地。一個(gè)主域名及其多個(gè)子域名同時(shí)申請(qǐng)的話,CA 只為它們簽發(fā)一張證書。
部署
還是以 nginx docker 容器為例。
# The label value to find the container
# 多個(gè)不同域名申請(qǐng)證書時(shí)可重復(fù)使用該容器
export DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=anything
# The target file path in the container.
# The files will be copied to the position in the container.
export DEPLOY_DOCKER_CONTAINER_KEY_FILE="/etc/nginx/ssl/demo.com/key.pem"
export DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/nginx/ssl/demo.com/cert.pem"
export DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/nginx/ssl/demo.com/ca.pem"
export DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/nginx/ssl/demo.com/full.pem"
# The command to reload the service in the container.
export DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="nginx -s reload"
# -d 指定 acme.sh --issue 時(shí)第一個(gè)[二級(jí)]域名或其執(zhí)行結(jié)果產(chǎn)生的目錄名
acme.sh --deploy --deploy-hook docker -d demo.com
筆者尚不清楚自動(dòng)更新證書時(shí)是否會(huì)將新證書自動(dòng)拷貝至容器內(nèi),推測(cè)應(yīng)該是會(huì)的,這些臨時(shí)環(huán)境變量應(yīng)該會(huì)以當(dāng)前申請(qǐng)的域名配置項(xiàng)的形式固化到磁盤中。
配置 nginx.conf
在 http 節(jié)中加入如下配置
server {
listen 443 ssl;
# 二級(jí)域名配置相同,本文略過(guò)
server_name demo.com;
root /usr/share/nginx/html;
# 上一步證書拷貝的地址
ssl_certificate /etc/nginx/ssl/demo.com/cert.pem;
ssl_certificate_key /etc/nginx/ssl/demo.com/key.pem;
ssl_session_cache shared:SSL:1m;
ssl_session_timeout 5m;
#默認(rèn)加密套件
ssl_ciphers HIGH:!aNULL:!MD5;
#表示優(yōu)先使用服務(wù)端加密套件。默認(rèn)開啟
ssl_prefer_server_ciphers on;
location / {
index index.html index.htm;
}
}
后記:按上述配置,使用證書檢測(cè)工具會(huì)提示“缺少中間證書”,雖然不影響瀏覽器請(qǐng)求,但在對(duì)證書嚴(yán)格要求的場(chǎng)景下(如微信小程序)可能會(huì)報(bào)錯(cuò)。將 ssl_certificate 配置為 full.pem 即可解決。
吊銷證書
假如因某種原因需要吊銷證書的話,可執(zhí)行如下腳本:
acme.sh --revoke -d demo.com -d www.demo.com -d admin.demo.com
筆者尚不清楚在一個(gè)主域名及其多個(gè)子域名共用一張證書的情況下,是否可只給部分域名吊銷證書。

浙公網(wǎng)安備 33010602011771號(hào)