本文將介紹我是如何將一個(gè) HTTP 網(wǎng)站升級(jí)到 HTTPS。系統(tǒng)環(huán)境:CentOS 7.0 + Nginx 1.12.0
前言
先貼一個(gè)福利掐隐,也作為沒有啟用 HTTPS 的反面教材:
這是我參與開發(fā)過的一個(gè)外包網(wǎng)站韵卤,沒有啟用 HTTPS脏款,網(wǎng)站頁面被中間人劫持辐宾,并插入了一些奇怪的東西买猖。下面是正文刁笙。
預(yù)備條件
本文假定你已經(jīng)擁有一個(gè)正確解析到服務(wù)器IP的域名破花,服務(wù)器上已安裝 Nginx。Nginx 可以通過源碼編譯安裝疲吸,也可以使用系統(tǒng)提供的包管理器安裝座每,比如 RH 系的 yum 或者 Debian 系的 apt-get,具體步驟自行Google摘悴。
獲取證書
HTTPS 證書分三類:1. DV 域名驗(yàn)證證書 2. OV 組織機(jī)構(gòu)驗(yàn)證證書 3. EV 增強(qiáng)的組織機(jī)構(gòu)驗(yàn)證證書峭梳。每類證書的審核要求不同,在瀏覽器地址欄也會(huì)有區(qū)分蹂喻,對(duì)于個(gè)人網(wǎng)站而言葱椭,使用免費(fèi)的 DV 證書就足夠了。
我使用了大名鼎鼎的 Let's Encrypt 來生成證書口四。
1. 安裝 certbot
certbot 是 Let's Encrypt 提供的一套自動(dòng)化工具孵运。
yum install epel-release
yum install certbot
2. 生成證書
這里采用 webroot 作為 Let's Encrypt 的認(rèn)證方式。
certbot certonly -a webroot --webroot-path=/your/project/path -d example.com -d www.example.com
webroot-path就是你的項(xiàng)目路徑蔓彩,使用 -d 可以添加多個(gè)域名治笨。這時(shí)證書就已經(jīng)生成成功了驳概,默認(rèn)保存在 /etc/letsencrypt/live/example.com/ 下。證書文件包括:
- cert.pem: 服務(wù)端證書
- chain.pem: 瀏覽器需要的所有證書但不包括服務(wù)端證書旷赖,比如根證書和中間證書
- fullchain.pem: 包括了cert.pem和chain.pem的內(nèi)容
- privkey.pem: 證書私鑰
3. 生成迪菲-赫爾曼密鑰交換組( Strong Diffie-Hellman Group)
為了進(jìn)一步提高安全性顺又,你也可以生成一個(gè) Strong Diffie-Hellman Group。
openssl dhparam -out /etc/ssl/certs/dhparam.pem 2048
如果沒有安裝 openssl杠愧,這里要先安裝一下待榔。
yum install openssl
配置 Nginx
編輯 Nginx 配置文件,如果你不知道配置文件在哪流济,可以用 locate /nginx.conf 命令查找锐锣。添加以下內(nèi)容,具體參數(shù)以你的實(shí)際情況為準(zhǔn)绳瘟。
server {
listen 443 ssl;
# 啟用http2
# 需要安裝 Nginx Http2 Module
# listen 443 http2 ssl;
server_name example.com www.example.com;
#證書文件
ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
#私鑰文件
ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
# 優(yōu)先采取服務(wù)器算法
ssl_prefer_server_ciphers on;
# 定義算法
ssl_ciphers "EECDH+AESGCM:EDH+AESGCM:AES256+EECDH:AES256+EDH";
ssl_ecdh_curve secp384r1;
ssl_session_cache shared:SSL:10m;
ssl_session_tickets off;
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
add_header X-Frame-Options DENY;
add_header X-Content-Type-Options nosniff;
# 使用DH文件
ssl_dhparam /etc/ssl/certs/dhparam.pem;
location ~ /.well-known {
allow all;
}
root /your/project/path;
index index.html index.htm;
location / {
try_files $uri $uri/ =404;
}
}
解釋一下其中幾項(xiàng)配置:
ssl_stapling on;
開啟 OCSP Stapling雕憔,使服務(wù)端主動(dòng)獲取 OCSP 查詢結(jié)果并隨著證書一起發(fā)送給客戶端,從而讓客戶端跳過自己去驗(yàn)證的過程糖声,提高 TLS 握手效率斤彼。
add_header Strict-Transport-Security "max-age=63072000; includeSubdomains";
啟用 HSTS 策略,強(qiáng)制瀏覽器使用 HTTPS 連接蘸泻,max-age設(shè)置單位時(shí)間內(nèi)強(qiáng)制使用 HTTPS 連接琉苇;includeSubDomains 可選,設(shè)置所有子域同時(shí)生效悦施。瀏覽器在獲取該響應(yīng)頭后并扇,在 max-age 的時(shí)間內(nèi),如果遇到 HTTP 連接抡诞,就會(huì)通過 307 跳轉(zhuǎn)強(qiáng)制使用 HTTPS 進(jìn)行連接
add_header X-Frame-Options DENY;
添加 X-Frame-Options 響應(yīng)頭穷蛹,可以禁止網(wǎng)站被嵌入到 iframe 中,減少點(diǎn)擊劫持 (clickjacking)攻擊昼汗。
add_header X-Content-Type-Options nosniff;
添加 X-Content-Type-Options 響應(yīng)頭肴熏,防止 MIME 類型嗅探攻擊
解釋完畢。繼續(xù)顷窒,來測(cè)試 nginx.conf 是否有語法錯(cuò)誤
nginx -t
重啟 Nginx
nginx -s reload
重定向 HTTP 到 HTTPS
修改原來 HTTP 網(wǎng)站的 Nginx 配置蛙吏。
server {
listen 80;
server_name example.com www.example.com;
access_log /var/log/example/access.log;
error_log /var/log/example/error.log;
# 301 永久重定向
return 301 https://$host$request_uri;
location / {
root /your/project/path;
index index.html index.htm;
}
}
這時(shí)再訪問網(wǎng)站,瀏覽器地址欄就會(huì)出現(xiàn)一把小鎖鞋吉。
一旦升級(jí) HTTPS出刷,網(wǎng)站內(nèi)的所有資源文件和請(qǐng)求的協(xié)議也必須為 HTTPS,你需要在前端代碼里修改一下坯辩。
最后可以使用 ssllabs 測(cè)試一下網(wǎng)站的安全性,我的網(wǎng)站得了 A+??
參考鏈接:
Nginx 配置 HTTPS 服務(wù)器
How To Secure Nginx with Let's Encrypt on CentOS 7