作者:劉剛,叩丁狼高級講師。原創(chuàng)文章,轉(zhuǎn)載請注明出處。
Let's Encrypt 是國外一個(gè)公共的免費(fèi) SSL 項(xiàng)目,該項(xiàng)目是為了普及 HTTPS 而發(fā)起的,目前已經(jīng)被 Mozilla、Google、Microsoft 和 Apple 等主流瀏覽器支持,對 HTTPS 技術(shù)的普及有著巨大貢獻(xiàn)。隨著 HTTPS 的普及,Let's Encrypt 已經(jīng)成為全球最受歡迎的免費(fèi) SSL 證書簽發(fā)機(jī)構(gòu)。
注意事項(xiàng)
- Let's Encrypt 的基礎(chǔ)證書只提供了數(shù)據(jù)加密,不驗(yàn)證身份,從而也無法證明網(wǎng)站的所有者,雖然已經(jīng)滿足絕大部分應(yīng)用場景,但若涉及核心功能時(shí)還是需要進(jìn)行身份驗(yàn)證。
- Let's Encrypt 簽發(fā)的證書一次的有效期為 3 個(gè)月,需要定期更新證書(官方推薦兩個(gè)月左右更新一次,本文有提供自動(dòng)更新方案)。
安裝 EPEL 倉庫
Let's Encrypt 的簽發(fā)證書工具在 EPEL 倉庫中才能找到,所以如果沒有安裝 EPEL 倉庫的話要先安裝一下。
# 查詢是否已安裝 epel 倉庫
rpm -qa epel-release
# 若沒有安裝再安裝 epel 倉庫
sudo yum install -y epel-release
安裝簽發(fā)證書工具
用 Certbot 工具申請 Let's Encrypt 證書,要先安裝該工具:
sudo yum install certbot-nginx
如果報(bào)以下錯(cuò)誤:
ImportError:No module named 'requests.packages.urllib3'
執(zhí)行以下命令解決:
# 如果沒有 pip 可使用 `sudo yum install python-pip` 安裝
pip install --upgrade --force-reinstall 'requests==3.6.0' urllib3
網(wǎng)站運(yùn)行在申請 SSL 證書的服務(wù)器上
這邊將申請證書分為兩種情況,正常情況下我們使用第一種就好了,也就是網(wǎng)站運(yùn)行在申請 SSL 證書的服務(wù)器上。另外就是比如在 A 機(jī)器上申請證書,但網(wǎng)站運(yùn)行在 B 機(jī)器上,當(dāng)然如果你是用 Docker 跑的 Nginx 也得用第二種方式。
第一種方式有以下幾個(gè)條件:
i. 你要申請 SSL 證書的域名已經(jīng)指向到申請證書服務(wù)器的 ip
ii. 你的 Web 服務(wù)器需要使用 Nginx(在本例子中,可以在官網(wǎng)查看其它服務(wù)器的方式)
iii. Nginx 配置完成,并且已經(jīng)綁定了你要申請 SSL 證書的域名
具備以上條件,就可以執(zhí)行以下操作啦:
# 申請 SSL 證書,certonly 表示只生成證書,不做額外操作
sudo certbot --nginx certonly
certbot 會(huì)自動(dòng)查找當(dāng)前 Nginx 上的虛擬主機(jī),并提示:
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Which names would you like to activate HTTPS for?
-------------------------------------------------------------------------------
1: xxx.wolfcode.cn
-------------------------------------------------------------------------------
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
如果出現(xiàn)以下錯(cuò)誤:
# Saving debug log to /var/log/letsencrypt/letsencrypt.log
# The nginx plugin is not working; there may be problems with your existing configuration.
# The error was: NoInstallationError()
可能是因?yàn)檎也坏?nginx 命令,解決方案:
# 以下命令是分別將 nginx 安裝目錄的 nginx 命令與配置文件軟連接到指定文件
# 你可以根據(jù)自己的具體情況修改目錄
ln -s /usr/local/nginx/sbin/nginx /usr/bin/nginx
ln -s /usr/local/nginx/conf /etc/nginx
還有可能提示無法連接到你的服務(wù)器,主要要開放防火墻的 443 端口
看到前面正確提示,出現(xiàn)我的 Nginx 上綁定的一個(gè)域名,如果你的 Nginx 有綁定多個(gè),那么列表中也會(huì)以多個(gè)顯示,然后輸入你需要申請 SSL 證書對應(yīng)域名的序號即可,驗(yàn)證成功后 Let's Encrypt 就會(huì)立即給你簽發(fā) SSL 證書,成功后提示:
# Obtaining a new certificate
# Performing the following challenges:
# tls-sni-01 challenge for g.wangchujiang.com
# Waiting for verification...
# Cleaning up challenges
#
# IMPORTANT NOTES:
# - Congratulations! Your certificate and chain have been saved at:
# /etc/letsencrypt/live/xxx.wolfcode.cn/fullchain.pem
# Your key file has been saved at:
# /etc/letsencrypt/live/xxx.wolfcode.cn/privkey.pem
# Your cert will expire on 2018-03-29. To obtain a new or tweaked
# version of this certificate in the future, simply run certbot
# again. To non-interactively renew *all* of your certificates, run
# "certbot renew"
# - If you like Certbot, please consider supporting our work by:
#
# Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
# Donating to EFF: https://eff.org/donate-le
以上信息則表示證書生成成功了。其他信息主要是告訴你證書存放的位置、過期時(shí)間以及更新證書命令:
# 證書位置
/etc/letsencrypt/live/xxx.wolfcode.cn/fullchain.pem
/etc/letsencrypt/live/xxx.wolfcode.cn/privkey.pem
# 過期時(shí)間:Your cert will expire on 2018-06-19.
# 你的證書將在 2018-06-19 過期
# 可以使用如下命令更新證書有效期
certbot renew --dry-run
配置 Nginx,讓所有 HTTP 請求轉(zhuǎn)發(fā)到 HTTPS:
# 將 http 請求轉(zhuǎn)發(fā)到 https
server {
listen 80;
server_name xxx.wolfcode.cn;
rewrite ^(.*)$ https://$host$1 permanent;
# 禁止在 heaader 中出現(xiàn)服務(wù)器版本,防止黑客利用版本漏洞攻擊
server_tokens off;
}
# https 的配置
server {
listen 443 ssl;
server_name xxx.wolfcode.cn;
ssl_certificate /etc/letsencrypt/live/xxx.wolfcode.cn/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/xxx.wolfcode.cn/privkey.pem;
# 禁止在 heaader 中出現(xiàn)服務(wù)器版本,防止黑客利用版本漏洞攻擊
server_tokens off;
# 設(shè)置ssl/tls會(huì)話緩存的類型和大小。如果設(shè)置了這個(gè)參數(shù)一般是shared,buildin可能會(huì)參數(shù)內(nèi)存碎片,默認(rèn)是none,和off差不多,停用緩存。如shared:SSL:10m表示我所有的nginx工作進(jìn)程共享ssl會(huì)話緩存,官網(wǎng)介紹說1M可以存放約4000個(gè)sessions。
ssl_session_cache shared:SSL:1m;
# 客戶端可以重用會(huì)話緩存中ssl參數(shù)的過期時(shí)間,內(nèi)網(wǎng)系統(tǒng)默認(rèn)5分鐘太短了,可以設(shè)成30m即30分鐘甚至4h。
ssl_session_timeout 5m;
# 選擇加密套件,不同的瀏覽器所支持的套件(和順序)可能會(huì)不同。
# 這里指定的是OpenSSL庫能夠識別的寫法,你可以通過 openssl -v cipher 'RC4:HIGH:!aNULL:!MD5'(后面是你所指定的套件加密算法) 來看所支持算法。
ssl_ciphers HIGH:!aNULL:!MD5;
# 設(shè)置協(xié)商加密算法時(shí),優(yōu)先使用我們服務(wù)端的加密套件,而不是客戶端瀏覽器的加密套件。
ssl_prefer_server_ciphers on;
location / {
root /www/html/website;
index dist/index.html;
}
error_page 404 /404.html;
location = /404.html {
root html;
}
error_page 500 502 503 504 /50x.html;
location = /50x.html {
root html;
}
}
到此就配置完成啦,使用 HTTPS 訪問看看吧。
網(wǎng)站運(yùn)行在申請 SSL 證書以外的服務(wù)器上
為其他主機(jī)上的網(wǎng)站或 Docker 中的網(wǎng)站申請 SSL 證書,只需要多一步驗(yàn)證即可:
# 申請證書
# certonly 只生成證書,不做額外操作
# --manual 交互式操作,也就是追加驗(yàn)證條件
sudo certbot certonly --manual
提示讓你輸入想要申請證書的域名
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator manual, Installer None
Starting new HTTPS connection (1): acme-v01.api.letsencrypt.org
Please enter in your domain name(s) (comma and/or space separated) (Enter 'c'
to cancel): xxx.wolfcode.cn
接著會(huì)提示需要記錄你申請 SSL 證書域名對應(yīng)服務(wù)器的 IP,問你是否同意:
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for ninghao.net
-------------------------------------------------------------------------------
NOTE: The IP of this machine will be publicly logged as having requested this
certificate. If you're running certbot in manual mode on a machine that is not
your server, please ensure you're okay with that.
Are you OK with your IP being logged?
-------------------------------------------------------------------------------
(Y)es/(N)o: Y
然后會(huì)給一個(gè)字符串,讓你將字符內(nèi)容保存在一個(gè)文件內(nèi),并可以通過它所指定的 URL 進(jìn)行訪問,cretbot 會(huì)對該 URL 進(jìn)行校驗(yàn)
-------------------------------------------------------------------------------
Create a file containing just this data:
HNIVXWGNL99iXcy5zI9OwSZmugf0xnv786nw5HchlJ4.n3Pm5l0vxnRwAslvOBBkXT1rGGJ7AwbTnaSCsSiQJFc
And make it available on your web server at this URL:
http://wolfcode.cn/.well-known/acme-challenge/HNIVXWGNL99iXcy5zI9OwSZmugf0xnv786nw5HchlJ4
-------------------------------------------------------------------------------
Press Enter to Continue
比如我這個(gè),則可以在 website 根目錄創(chuàng)建:
# 創(chuàng)建驗(yàn)證文件夾
mkdir -p /yourwebsite/.well-known/acme-challenge/
# 進(jìn)入該文件夾
cd /yourwebsite/.well-known/acme-challenge/
# 創(chuàng)建文件(以下兩部內(nèi)容請修改為你自己的數(shù)據(jù))
touch HNIVXWGNL99iXcy5zI9OwSZmugf0xnv786nw5HchlJ4
# 將提示信息寫入文件
echo "HNIVXWGNL99iXcy5zI9OwSZmugf0xnv786nw5HchlJ4.n3Pm5l0vxnRwAslvOBBkXT1rGGJ7AwbTnaSCsSiQJFc" > HNIVXWGNL99iXcy5zI9OwSZmugf0xnv786nw5HchlJ4
驗(yàn)證通過之后便會(huì)簽發(fā)證書:
Waiting for verification...
Cleaning up challenges
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
/etc/letsencrypt/live/wolfcode.cn/fullchain.pem
Your key file has been saved at:
/etc/letsencrypt/live/wolfcode.cn/privkey.pem
Your cert will expire on 2018-03-29. To obtain a new or tweaked
version of this certificate in the future, simply run certbot
again. To non-interactively renew *all* of your certificates, run
"certbot renew"
- If you like Certbot, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
到此證書申請便完成了,Nginx 配置可以參考上面的配置
添加定時(shí)任務(wù)完成自動(dòng)更新
現(xiàn)在證書申請、配置都已經(jīng)完成了,并且也可以正常訪問,但還有個(gè)小問題就是 Let's Encrypt 簽發(fā)的證書只有 90 天的有效期,到期后需要再更新,此時(shí)便可以使用到 linux 上的 crontab 工具來定時(shí)幫我們完成更新操作
certbot 為我們提供了很方便的更新方式,你只需要執(zhí)行如下命令:
# 更新所有證書
sudo certbot renew --dry-run
使用以上命令便可以將所有證書更新,那么此時(shí)我們可以添加一個(gè)定時(shí)任務(wù)來完成這一操作:
# 進(jìn)入定時(shí)任務(wù)存放目錄
cd /etc/cron.d
# 將腳本寫入文件,該腳本是每 2 個(gè)月的 20 號凌晨 2:15 執(zhí)行一次
echo "15 2 20 */2 * certbot renew --dry-run" > certbot-auto-renew-cron
# 將腳本加入到 crontab
crontab certbot-auto-renew-cron
至此,SSL 證書就算徹底完成啦。
