相關(guān)知識(shí)
HTTP/HTTPS 是什么?
簡(jiǎn)單來(lái)說(shuō)法严,HTTP 是一個(gè)傳輸網(wǎng)頁(yè)內(nèi)容的協(xié)議,比如我們?yōu)g覽一個(gè)網(wǎng)頁(yè)葫笼,網(wǎng)頁(yè)上的文字深啤、圖片、 CSS 路星、 JS 等文件都是通過(guò) HTTP 協(xié)議傳輸?shù)轿覀兊臑g覽器溯街,然后被我們看到。因?yàn)?HTTP 是明文傳輸?shù)难筘ぃㄟ^(guò) HTTP 協(xié)議傳輸?shù)膬?nèi)容很容易被偷看和篡改呈昔,為了安全(你肯定不想被人偷看或者篡改網(wǎng)頁(yè)內(nèi)容吧,比如網(wǎng)站銀行密碼什么的友绝。)就為 HTTP 協(xié)議再加上了一層 SSL/TLS 安全協(xié)議堤尾,所以就有了 HTTPS 。
SSL/TLS 是什么九榔?
SSL 是指安全套接字層(Secure Sockets Layer),內(nèi)心純潔的同學(xué)也可以理解為「帶安全套的 HTTP」,因?yàn)閹Я税踩渍懿矗援?dāng)然會(huì)比較安全剩蟀。TLS 是 傳輸層安全協(xié)議(Transport Layer Security),SSL 和 TLS 是同一個(gè)東西的不同階段切威,理解為同一個(gè)東西也行育特,都是安全協(xié)議就對(duì)了。
為什么要部署 HTTPS先朦?
說(shuō)到底缰冤,就是 HTTPS 更安全。甚至為了安全喳魏,一個(gè)專業(yè)可靠的網(wǎng)站棉浸, HTTPS 是必須的。 Firefox 和 Chrome 都計(jì)劃將沒(méi)有配置 SSL 加密的 HTTP 網(wǎng)站標(biāo)記為不安全刺彩,目前它們也正在聯(lián)合其他相關(guān)的基金會(huì)與公司推動(dòng)整個(gè)互聯(lián)網(wǎng) HTTPS 化迷郑,現(xiàn)在大家訪問(wèn)的一些主要的網(wǎng)站。如 Google 多年前就已經(jīng)全部啟用 HTTPS 创倔,國(guó)內(nèi)的淘寶嗡害、搜狗、知乎畦攘、百度等等也全面 HTTPS 了霸妹。甚至 Google 和百度的搜索結(jié)果也正在給予 HTTPS 的網(wǎng)站更高的排名和優(yōu)先收錄權(quán)。
怎么部署 HTTPS 呢知押?
你只需要有一張被信任的 CA ( Certificate Authority )也就是證書(shū)授權(quán)中心頒發(fā)的 SSL 安全證書(shū)叹螟,并且將它部署到你的網(wǎng)站服務(wù)器上。一旦部署成功后朗徊,當(dāng)用戶訪問(wèn)你的網(wǎng)站時(shí)首妖,瀏覽器會(huì)在顯示的網(wǎng)址前加一把小綠鎖,表明這個(gè)網(wǎng)站是安全的爷恳,當(dāng)然同時(shí)你也會(huì)看到網(wǎng)址前的前綴變成了 HTTPS 有缆,不再是 HTTP 了。
怎么獲得 SSL 安全證書(shū)呢温亲?
理論上棚壁,我們自己也可以簽發(fā) SSL 安全證書(shū),但是我們自己簽發(fā)的安全證書(shū)不會(huì)被主流的瀏覽器信任栈虚,所以我們需要被信任的證書(shū)授權(quán)中心( CA )簽發(fā)的安全證書(shū)袖外。而一般的 SSL 安全證書(shū)簽發(fā)服務(wù)都比較貴,比如 Godaddy 魂务、 GlobalSign 等機(jī)構(gòu)簽發(fā)的證書(shū)一般都需要20美金一年甚至更貴曼验,不過(guò)為了加快推廣 HTTPS 的普及泌射, EEF 電子前哨基金會(huì)、 Mozilla 基金會(huì)和美國(guó)密歇根大學(xué)成立了一個(gè)公益組織叫 ISRG ( Internet Security Research Group )鬓照,這個(gè)組織從 2015 年開(kāi)始推出了 Let’s Encrypt 免費(fèi)證書(shū)熔酷。這個(gè)免費(fèi)證書(shū)不僅免費(fèi),而且還相當(dāng)好用豺裆,所以我們就可以利用 Let’s Encrypt 提供的免費(fèi)證書(shū)部署 HTTPS 了拒秘。
Let’s Encrypt 簡(jiǎn)介
前面已經(jīng)介紹過(guò), Let’s Encrypt 是 一個(gè)叫 ISRG ( Internet Security Research Group 臭猜,互聯(lián)網(wǎng)安全研究小組)的組織推出的免費(fèi)安全證書(shū)計(jì)劃躺酒。參與這個(gè)計(jì)劃的組織和公司可以說(shuō)是互聯(lián)網(wǎng)頂頂重要的先驅(qū),除了前文提到的三個(gè)牛氣哄哄的發(fā)起單位外蔑歌,后來(lái)又有思科(全球網(wǎng)絡(luò)設(shè)備制造商執(zhí)牛耳者)羹应、 Akamai 加入,甚至連 Linux 基金會(huì)也加入了合作丐膝,這些大牌組織的加入保證了這個(gè)項(xiàng)目的可信度和可持續(xù)性量愧。
Certbot 簡(jiǎn)介
ISRG 的發(fā)起者 EFF (電子前哨基金會(huì))為 Let’s Encrypt 項(xiàng)目發(fā)布了一個(gè)官方的客戶端 Certbot ,利用它可以完全自動(dòng)化的獲取帅矗、部署和更新安全證書(shū)偎肃。雖然第三方工具也可以使用,但是官方工具更權(quán)威浑此,風(fēng)險(xiǎn)也更小累颂,而且遇到問(wèn)題也更容易解決,畢竟有官方的支持凛俱。
實(shí)際操作
Certbot 使用方法
Certbot 的官網(wǎng)是https://certbot.eff.org/, 我們打開(kāi)這個(gè)鏈接紊馏,選擇自己使用的 web server 和操作系統(tǒng)。選擇完之后蒲犬,官網(wǎng)就會(huì)顯示出對(duì)應(yīng)的安裝操作步驟朱监。
以目前我所使用的服務(wù)器為例,web server 使用Nginx(1.12)原叮,操作系統(tǒng)是CentOS(7.3)赫编。因?yàn)?Certbot 打包在EPEL中,所以在安裝 Certbot 之前要先安裝EPEL
yum -y install epel-release
然后按著官網(wǎng)給出的步驟提示命令安裝 Certbot
yum install python2-certbot-nginx
安裝完畢后奋隶,繼續(xù)輸入官網(wǎng)提示命令
certbot --nginx
運(yùn)行此命令會(huì)自動(dòng)獲取證書(shū)擂送,并且 Certbot 會(huì)自動(dòng)編輯Nginx配置文件配置HTTPS服務(wù)。
這邊在運(yùn)行配置命令時(shí)遇到一個(gè)坑
ImportError: No module named 'requests.packages.urllib3'
可以看出是缺少一個(gè)模塊包唯欣,看配置命令在命令臺(tái)的輸出嘹吨,Certbot 是用 python 來(lái)寫(xiě) Nginx 配置。既然是用的 python境氢,可以通過(guò) pip list 命令查看 python 的依賴包列表蟀拷。但是查看是已經(jīng)存在的碰纬,這個(gè)問(wèn)題很快通過(guò) Certbot 在 github 上的一個(gè) Issues 找到了答案(Issues鏈接)。目前看是包的版本依賴有問(wèn)題问芬,執(zhí)行以下命令進(jìn)行依賴包的重裝
pip uninstall requests
pip uninstall urllib3
yum remove python-urllib3
yum remove python-requests
yum install python-urllib3
yum install python-requests
yum install certbot
再次執(zhí)行 certbot --nginx 命令成功嘀趟。命令執(zhí)行后首先會(huì)提示輸入一個(gè)郵箱地址,主要作用是訂閱一些通知愈诚,輸入后回車。
[root@izuf6fco0zwyipdq9485s2z ~]# certbot --nginx
Saving debug log to /var/log/letsencrypt/letsencrypt.log
Plugins selected: Authenticator nginx, Installer nginx
▽
Enter email address (used for urgent renewal and security notices) (Enter 'c' to
cancel): demo@mail.com // 演示郵箱
Starting new HTTPS connection (1): acme-v02.api.letsencrypt.org
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
回車后 Certbot 就會(huì)自動(dòng)請(qǐng)求下載 Let's Encrypt 證書(shū)牛隅,并設(shè)置 Nginx 配置文件炕柔。期間會(huì)有一些同意相關(guān)協(xié)議和選擇哪個(gè)網(wǎng)站配置的交互,這個(gè)看輸出文字就能明白意思媒佣。
...
▽
server {
(A)gree/(C)ancel: a
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Would you be willing to share your email address with the Electronic Frontier
Foundation, a founding partner of the Let's Encrypt project and the non-profit
organization that develops Certbot? We'd like to send you email about our work
encrypting the web, EFF news, campaigns, and ways to support digital freedom.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
(Y)es/(N)o: y
Starting new HTTPS connection (1): supporters.eff.org
Which names would you like to activate HTTPS for?
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: kisstime.top
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate numbers separated by commas and/or spaces, or leave input
blank to select all options shown (Enter 'c' to cancel): 1
Obtaining a new certificate
Performing the following challenges:
http-01 challenge for kisstime.top
Cleaning up challenges
...
但是這邊到 Certbot 設(shè)置 Nginx 配置文件的時(shí)候遇到一個(gè)坑匕累,報(bào)如下一個(gè)錯(cuò)誤
An unexpected error occurred:
UnicodeDecodeError: 'ascii' codec can't decode byte 0xe5 in position 2: ordinal not in range(128)
Please see the logfiles in /var/log/letsencrypt for more details.
熟悉 python 的同學(xué)應(yīng)該對(duì)這個(gè)錯(cuò)誤比較了解。不過(guò)博主 python 還是用的比較少默伍,花了點(diǎn)時(shí)間了解了一下欢嘿。
在解決錯(cuò)誤之前,首先要了解unicode和utf-8的區(qū)別也糊。unicode指的是萬(wàn)國(guó)碼炼蹦,是一種“字碼表”。而utf-8是這種字碼表儲(chǔ)存的編碼方法狸剃。unicode不一定要由utf-8這種方式編成bytecode儲(chǔ)存掐隐,也可以使用utf-16,utf-7等其他方式。目前大多都以u(píng)tf-8的方式來(lái)變成bytecode钞馁。其次虑省,Python中字符串類型分為byte string 和 unicode string兩種。如果在python文件中指定編碼方式為utf-8(#coding=utf-8)僧凰,那么所有帶中文的字符串都會(huì)被認(rèn)為是utf-8編碼的byte string(例如:mystr="你好")探颈,但是在函數(shù)中所產(chǎn)生的字符串則被認(rèn)為是unicode string。問(wèn)題就出在這邊训措,unicode string 和 byte string 是不可以混合使用的伪节,一旦混合使用了,就會(huì)產(chǎn)生這樣的錯(cuò)誤隙弛。例如:
self.response.out.write("你好"+self.request.get("argu"))
其中架馋,"你好"被認(rèn)為是byte string,而self.request.get("argu")的返回值被認(rèn)為是unicode string全闷。由于預(yù)設(shè)的解碼器是ascii叉寂,所以就不能識(shí)別中文byte string。然后就報(bào)錯(cuò)了总珠。
那理解了這個(gè)錯(cuò)誤原因后屏鳍,我這邊首先想到的就是網(wǎng)站的 Nginx 配置文件中是否含有中文勘纯。打開(kāi)一看,確實(shí)存在中文注釋钓瞭。將注釋去掉驳遵,重新執(zhí)行命令成功不在報(bào)錯(cuò)
接著命令交互會(huì)提示是否將所有HTTP重定向到HTTPS,我這邊選擇全部重定向也就是「2」山涡。
Cleaning up challenges
Deploying Certificate to VirtualHost: //這邊會(huì)顯示你的網(wǎng)站配置文件目錄
Please choose whether or not to redirect HTTP traffic to HTTPS, removing HTTP access.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
1: No redirect - Make no further changes to the webserver configuration.
2: Redirect - Make all requests redirect to secure HTTPS access. Choose this for
new sites, or if you're confident your site works on HTTPS. You can undo this
change by editing your web server's configuration.
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Select the appropriate number [1-2] then [enter] (press 'c' to cancel): 2
Redirecting all traffic on port 80 to ssl in //這邊會(huì)顯示你的網(wǎng)站配置文件目錄
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
Congratulations! You have successfully enabled https://kisstime.top
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=kisstime.top
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
IMPORTANT NOTES:
- Congratulations! Your certificate and chain have been saved at:
.../fullchain.pem
Your key file has been saved at:
.../privkey.pem
Your cert will expire on 2019-02-14. To obtain a new or tweaked
version of this certificate in the future, simply run certbot again
with the "certonly" option. 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
OK堤结,當(dāng)完成上面最后一步后,輸入如上信息后就表明 HTTPS 配置成功了鸭丛!我們可以通過(guò)提示中的 SSL Server Test 網(wǎng)址來(lái)測(cè)試網(wǎng)站是否能夠 HTTPS 來(lái)進(jìn)行訪問(wèn)
You should test your configuration at:
https://www.ssllabs.com/ssltest/analyze.html?d=kisstime.top
事實(shí)證明竞穷,高興的太早了。鳞溉。瘾带。通過(guò)測(cè)試網(wǎng)站和直接訪問(wèn)域名發(fā)現(xiàn)網(wǎng)站都是訪問(wèn)不了。思考了一下熟菲,確認(rèn)下服務(wù)器的443端口是否開(kāi)啟看政,我這邊用的是阿里云的服務(wù)器,登錄控制臺(tái)查看安全組規(guī)則抄罕,發(fā)現(xiàn)確實(shí)是443端口沒(méi)有開(kāi)啟酬核,配置開(kāi)啟后逛拱,重新訪問(wèn)成功棒掠。
其他
Nginx的設(shè)置說(shuō)明
基本上 Certbot 會(huì)在對(duì)應(yīng)的 Nginx 配置文件加上下面的參數(shù):
server {
# ... other configs
# SSL 設(shè)置
listen 443 ssl;
# set crt and key
ssl_certificate .../fullchain.pem;
ssl_certificate_key .../privkey.pem;
# include 基本的 ssl 設(shè)置
include .../options-ssl-nginx.conf;
# Certbot 也會(huì)生成一把 Diffie-Hellman 密鑰
ssl_dhparam .../ssl-dhparams.pem;
# ... other configs
}
自動(dòng)更新證書(shū)
Let’s Encrypt 免費(fèi)SSL證書(shū)用起來(lái)非常方便眶痰,但每次申請(qǐng)只有三個(gè)月有效期,在每次到期之前都需要重新申請(qǐng)榨崩,Certbot 已經(jīng)提供了一鍵續(xù)訂的命令
certbot renew
我們可以通過(guò)添加此條命令的cron作業(yè)(或systemd計(jì)時(shí)器)來(lái)安排證書(shū)的自動(dòng)續(xù)訂
SHELL=/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin
0 0,12 * * * certbot renew --quiet
Certbot 的 log 路徑
Certbot 的 log 預(yù)設(shè)路徑在 /var/log/letsencrypt谴垫,有需要可以去確認(rèn)查看。
相關(guān)第三方
certbot-auto是對(duì)腳本certbot的封裝母蛛,可以設(shè)置系統(tǒng)環(huán)境或自動(dòng)升級(jí)翩剪。
參考資料
牛頓曾經(jīng)說(shuō)過(guò):如果說(shuō)我看得比別人更遠(yuǎn)些,那是因?yàn)槲艺驹诰奕说募绨蛏喜式肌#↖f I have seen further, it is by standing on the shoulders of giants.)感謝前弯。
- https://certbot.eff.org/
- https://linuxstory.org/deploy-lets-encrypt-ssl-certificate-with-certbot
- https://blog.csdn.net/use_my_heart/article/details/51303317
- https://blog.hellojcc.tw/2018/05/02/setup-https-with-letsencrypt-on-nginx/