原文地址:https://blogof33.com/post/10/
前言
Chrome 新版本已經(jīng)會自動跳轉(zhuǎn) HTTPS 了赎败,ACool 一直想著沒有 HTTPS 的博客網(wǎng)站不是很完美,但是礙于平時(shí)比較忙,難以抽出時(shí)間來折騰。今天終于有空,完成了 HTTPS 在 Django 上面的部署。網(wǎng)上關(guān)于 Django 框架下 HTTPS 部署的文章很少踱卵,故此記錄一下部署過程嘉裤。
配置環(huán)境:
- django >= 1.8
- nginx
Let's Encrypt 是一個(gè)免費(fèi)的郑临,自動的,開放的認(rèn)證機(jī)構(gòu)(CA)屑宠,為公眾的利益而運(yùn)行厢洞。它是由互聯(lián)網(wǎng)安全研究組(ISRG)提供的一項(xiàng)服務(wù)。本文使用 Let's Encrypt 提供的免費(fèi) SSL 證書典奉。
因?yàn)槭謩荧@取和維護(hù)證書特別麻煩躺翻,所以我們采用自動客戶端 Cettbot 部署 SSL 證書。下面是官方介紹:
Certbot是 EFF 為了加密整個(gè)互聯(lián)網(wǎng)而做的一部分努力卫玖。Web上的安全通信依賴于HTTPS公你,它需要使用數(shù)字證書來讓瀏覽器驗(yàn)證Web服務(wù)器的身份(例如,是否真的是 google.com 骇笔?)省店。Web 服務(wù)器從名為證書頒發(fā)機(jī)構(gòu)(CA)的可信第三方獲取證書。Certbot 是一個(gè)易于使用的客戶端笨触,可從 Let's Encrypt(由 EFF懦傍,Mozilla 和其他人啟動的開放式證書頒發(fā)機(jī)構(gòu))獲取證書,并將其部署到Web服務(wù)器芦劣。
采用以上組合 ( Let's Encrypt + Certbot )方式簡單粗俱,方便,快捷虚吟。
獲取 SSL 證書
預(yù)先工作
在創(chuàng)建證書之前寸认,我們需要確保 Web 服務(wù)器可以在根目錄下的該路徑下提供靜態(tài)文件:/.well-know
。由于django 應(yīng)用程序引入的所有路徑都通過 wsgi 提供服務(wù)串慰,因此我們需要編寫nginx 配置以便于靜態(tài)地提供這些資源:將以下內(nèi)容添加到域名的 nginx 配置文件中:
server {
location /.well-known/acme-challenge {
alias /path/to/yoursite/.well-known/acme-challenge;
}
}
請根據(jù)自己的情況修改 /path/to/yoursite/
字段偏塞,比如 改成/home/User/Blogof33.com
,這個(gè)路徑便是 Django app 的絕對路徑邦鲫,即 manage.py
文件所在目錄灸叼。
下載Certbot
從 github 上面下載源碼,可以不用管 Linux 服務(wù)器發(fā)行版的區(qū)別:
git clone https://github.com/certbot/certbot.git
生成證書
因?yàn)槲覀兪?nginx 而不是 Apache庆捺,所以使用 webroot
選項(xiàng)獲取證書:
certbot certonly --webroot -w /path/to/yoursite -d blogof33.com -d www.blogof33.com
請修改 /path/to/yoursite
字段古今,和上面預(yù)先工作的修改一樣,然后后面的 blogof33.com
和 www.blogof33.com
請修改成自己的域名滔以,如果現(xiàn)在的域名不能加 www 訪問的話(即沒有提供 WWW 的解析)捉腥,請去掉最后這條字段。
這條命令成功的輸出類似于這樣(有Congratulations):
Output:
IMPORTANT NOTES:
If you lose your account credentials, you can recover through
e-mails sent to sammy@digitalocean.comCongratulations! Your certificate and chain have been saved at
/etc/letsencrypt/live/example.com/fullchain.pem. Your
cert will expire on 2018-08-31. To obtain a new version of the
certificate in the future, simply run Let's Encrypt again.Your account credentials have been saved in your Let's Encrypt
configuration directory at /etc/letsencrypt. You should make a
secure backup of this folder now. This configuration directory will
also contain certificates and private keys obtained by Let's
Encrypt so making regular backups of this folder is ideal.If like Let's Encrypt, please consider supporting our work by:
Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
Donating to EFF: https://eff.org/donate-le
上述命令會為blogof33.com
和www.blogof33.com
生成一個(gè)單獨(dú)的證書你画。證書存儲于 /etc/letsencrypt/live/blogof33.com/fullchain.pem
.
Django配置
參考官方鏈接:
https://docs.djangoproject.com/en/1.10/topics/security/#ssl-https
修改配置文件setting.py
抵碟,將以下行加入進(jìn)去:
SESSION_COOKIE_SECURE=True
SESSION_COOKIE_HTTPONLY=True
SECURE_PROXY_SSL_HEADER = ('HTTP_X_FORWARDED_PROTOCOL', 'https')
注意:對于運(yùn)行 django <1.8 的應(yīng)用程序桃漾,您應(yīng)該安裝并配置 django-secure 。
Nginx配置
最后一步便是配置 nginx立磁,配置文件位于 /etc/nginx/sites-available/blogof33.com
呈队, 配置與說明如下:
server {
charset utf-8;
listen 80;
server_name www.blogof33.com blogof33.com;
return 301 https://blogof33.com$request_uri;
}
server {
listen 443 default ssl;
server_name blogof33.com;
ssl_certificate /etc/letsencrypt/live/blogof33.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blogof33.com/privkey.pem;
error_log /var/log/nginx/error.log;
location /.well-known/acme-challenge {
alias /home/ACool/sites/blogof33.com/DjangoBlog/.well-known/acme-challenge;
}
location /static {
alias /home/ACool/sites/blogof33.com/DjangoBlog/static;
}
location / {
proxy_set_header Host $host;
proxy_pass http://unix:/tmp/blogof33.com.socket;
}
}
其中 剥槐,第一段 Server 代碼:
server {
charset utf-8;
listen 80;
server_name www.blogof33.com blogof33.com;
return 301 https://blogof33.com$request_uri;
}
含義為將所有 HTTP 流量重定向到 HTTPS唱歧,我們只需要根據(jù)自己域名修改其中域名,其他部分不變粒竖。
這一行是用來監(jiān)聽 443 端口( HTTPS 端口號):
listen 443 default ssl;
這兩行則是指向證書和密鑰(域名替換成自己的):
ssl_certificate /etc/letsencrypt/live/blogof33.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/blogof33.com/privkey.pem;
這一行是用來創(chuàng)建證書的:
location /.well-known/acme-challenge {
alias /home/ACool/sites/blogof33.com/DjangoBlog/.well-known/acme-challenge;
}
修改 nginx 配置以后颅崩,重新加載一下:
sudo nginx -s reload
至此配置完成。記得刷新一下瀏覽器緩存哦 蕊苗。
Let’s Encrypt 自動續(xù)期
Let’s Encrypt 的證書90天就過期了沿后,所以,我們還需要設(shè)置自動化更新腳本朽砰,最容易的莫過于使用 crontab
了尖滚。使用 crontab -e
命令加入如下的定時(shí)作業(yè)(每周都強(qiáng)制更新一下,如果需要 root 權(quán)限瞧柔,需要切換到 root 下執(zhí)行):
45 2 * * 2 cd /etc/letsencrypt/ && ./certbot-auto renew --deploy-hook "service nginx reload"
crontab 六個(gè)字段含義:
minute hour day month week command
其中:
- minute: 表示分鐘漆弄,(整數(shù) 0 -59)。
- hour:表示小時(shí)造锅,可以是從0到23之間的任何整數(shù)撼唾。
- day:表示日期,可以是從1到31之間的任何整數(shù)哥蔚。
- month:表示月份倒谷,可以是從1到12之間的任何整數(shù)。
- week:表示星期幾糙箍,可以是從0到7之間的任何整數(shù)渤愁,這里的0或7代表星期日。
- command:要執(zhí)行的命令深夯,可以是系統(tǒng)命令抖格,也可以是自己編寫的腳本文件。
如果字段使用 * 號塌西,如 month 字段為 * 號他挎,則為滿足其他字段約束的每月都執(zhí)行該命令。
這里是每周 2 的 2 點(diǎn) 45 分嘗試更新證書捡需,如果證書在 30 天內(nèi)到期办桨,則會更新證書,否則不會更新站辉, --deploy-hook
選項(xiàng)表示在更新成功以后才運(yùn)行重載 nginx 的命令呢撞。
至此损姜,在 Django 框架下部署 HTTPS 全部完成。
Welcome to the https world!再也不用擔(dān)心網(wǎng)站被劫持了殊霞。