一切從劫持開始說起
在家上網(wǎng)瀏覽網(wǎng)頁足陨,第一次打開瀏覽器,輸入網(wǎng)址娇未,回車墨缘,發(fā)現(xiàn)頁面右下角會出現(xiàn)一個(gè)大概300x300(像素)左右大小的正方形小窗口。窗口內(nèi)多半是一些此時(shí)此刻非常不愿意看到的內(nèi)容零抬,比如廣告镊讼。咦,我訪問的明明是某知名搜索引擎啊平夜,按常理來說這個(gè)位置不應(yīng)該出現(xiàn)這樣一個(gè)和頁面布局極其不搭的小窗口的蝶棋,是不是我中毒了?
自己運(yùn)營了一個(gè)博客忽妒,放到公網(wǎng)分享內(nèi)容給大家玩裙,流量還不錯(cuò)兼贸,可是留言區(qū)老有用戶說我亂打小廣告。我不信献酗,打開瀏覽器訪問了下自己的博客寝受,怎么搞的?我的主頁面上下左右被嵌入各種無恥下流骯臟邪惡小廣告罕偎,而且與我發(fā)布的內(nèi)容極其不和諧很澄,有些彈窗甚至擋住了重要的內(nèi)容,可是我明明沒有接入任何廣告把占啊甩苛?
如果遇到如上兩種情況,那么恭喜你俏站,你被http劫持了Q镀选!肄扎!
在用戶的客戶端與其要訪問的服務(wù)器經(jīng)過網(wǎng)絡(luò)協(xié)議協(xié)調(diào)后墨林,二者之間建立了一條專用的數(shù)據(jù)通道,用戶端程序在系統(tǒng)中開放指定網(wǎng)絡(luò)端口用于接收數(shù)據(jù)報(bào)文犯祠,服務(wù)器端將全部數(shù)據(jù)按指定網(wǎng)絡(luò)協(xié)議規(guī)則進(jìn)行分解打包旭等,形成連續(xù)數(shù)據(jù)報(bào)文。
用戶端接收到全部報(bào)文后衡载,按照協(xié)議標(biāo)準(zhǔn)來解包組合獲得完整的網(wǎng)絡(luò)數(shù)據(jù)搔耕。其中傳輸過程中的每一個(gè)數(shù)據(jù)包都有特定的標(biāo)簽,表示其來源痰娱、攜帶的數(shù)據(jù)屬性以及要到何處弃榨,所有的數(shù)據(jù)包經(jīng)過網(wǎng)絡(luò)路徑中ISP的路由器傳輸接力后,最終到達(dá)目的地梨睁,也就是客戶端鲸睛。
HTTP劫持是在使用者與其目的網(wǎng)絡(luò)服務(wù)所建立的專用數(shù)據(jù)通道中,監(jiān)視特定數(shù)據(jù)信息坡贺,提示當(dāng)滿足設(shè)定的條件時(shí)腊凶,就會在正常的數(shù)據(jù)流中插入精心設(shè)計(jì)的網(wǎng)絡(luò)數(shù)據(jù)報(bào)文,目的是讓用戶端程序解釋“錯(cuò)誤”的數(shù)據(jù)拴念,并以彈出新窗口的形式在使用者界面展示宣傳性廣告或者直接顯示某網(wǎng)站的內(nèi)容。
以上內(nèi)容摘自百度百科:http劫持
如果你去搜索引擎查找問題和答案褐缠,通常會找到如下關(guān)鍵詞:
- 運(yùn)營商劫持廣告
- 運(yùn)營商http劫持
- http劫持
- 電信劫持廣告
- 電信劫持
- 電信網(wǎng)頁劫持
- 電信http劫持
- 內(nèi)容劫持
- ISP hijacking
有人說這是天朝特有的政鼠,那是因?yàn)槟阒换钤谔斐y道國外就沒有了嗎队魏?劫持技術(shù)是通用的公般。
看看如何防范
- 對于開篇說的第一種場景万搔,月光博客里提到了一篇從用戶的角度的解決方案
- 對于廣大網(wǎng)站主(博主)來說,全站https化是一種防止http劫持的有效方法
這里我們不具體聊https的原理了官帘,就說說如何用免費(fèi)的Let’s Encrypt來具體實(shí)踐如何將你的站點(diǎn)https化瞬雹。
Let's Encrypt
Let's Encrypt是由EFF、Mozilla刽虹、Cisco酗捌、Akamai、IdenTrust與密西根大學(xué)研究人員共同創(chuàng)立的免費(fèi)的憑證中心涌哲,目的在于推動全球所有的網(wǎng)站都使用HTTPS加密傳輸胖缤,并由非營利的網(wǎng)際網(wǎng)路安全研究組織Internet Security Research Group(ISRG)負(fù)責(zé)營運(yùn)。
這個(gè)組織的主要原則是:
- 免費(fèi):任何域名所有者都可以零費(fèi)用申請到一個(gè)針對其域名的有效證書阀圾。
- 自動:整個(gè)證書注冊過程在服務(wù)器安裝或配置過程中可以簡單實(shí)現(xiàn)哪廓,而更新過程更是可以在后臺自動執(zhí)行。
- 安全:Let’s Encrypt 將會提供業(yè)界最新的安全技術(shù)和最好的實(shí)踐初烘。
- 透明:所有關(guān)于證書發(fā)放涡真、撤銷的記錄都會向任何需要調(diào)查的人員開放。
- 開放:自動化執(zhí)行的發(fā)放和更新協(xié)議將會是開放標(biāo)準(zhǔn)肾筐,軟件也盡可能使用開源軟件哆料。
- 合作:與現(xiàn)有的互聯(lián)網(wǎng)協(xié)議本身很相似,Let’s Encrypt 是一個(gè)對整個(gè)社區(qū)都有益的聯(lián)合行動局齿,不由任何一個(gè)組織控制剧劝。
下面聊聊具體的實(shí)踐故事
首次生成證書
從Github簽出Let’s Encrypt的源代碼
git clone https://github.com/letsencrypt/letsencrypt
進(jìn)入本地源代碼目錄
cd letsencrypt
Let’s Encrypt提供多種認(rèn)證方式,因?yàn)橹霸赩PS上有了HTTP的網(wǎng)站抓歼,所以這里采用了webroot的方式讥此,其他方式請參考官方文檔
如果是主域名的認(rèn)證:
./letsencrypt-auto --debug certonly --webroot --email name@your_main_domain.com -d www.your_main_domain.com -d your_main_domain.com -w /var/www/your_main_domain.com
子域名的認(rèn)證:
./letsencrypt-auto --debug certonly --webroot --email name@your_main_domain.com -d subdomain.your_main_domain.com -w /var/www/your_main_domain.com/subdomain
然后在彈出的藍(lán)底白字提示框中一路點(diǎn)擊"OK"
注意如下問題:
- 請將命令中的name, your_main_domain.com, subdomain替換成你自己的名字,域名以及子域名
- 因?yàn)镚entoo目前是在試驗(yàn)階段谣妻,所以命令行加上--debug參數(shù)
- 參數(shù)--email如果沒有在命令行加上萄喳,會在隨后彈出的對話框里提示你填寫
- -w指定Web服務(wù)器網(wǎng)址內(nèi)容放置的目錄,請指定自己放置的目錄
生成的證書放在/etc/letsencrypt/live/[網(wǎng)站域名]下
文件名 | 內(nèi)容 |
---|---|
cert.pem | 服務(wù)端證書 |
chain.pem | 瀏覽器需要的所有證書但不包括服務(wù)端證書蹋半,比如根證書和中間證書 |
fullchain.pem | 包括了cert.pem和chain.pem的內(nèi)容 |
privkey.pem | 證書的私鑰 |
一般情況下fullchain.pem和privkey.pem就夠用了
Web服務(wù)端配置
采用的Nginx做的Web服務(wù)器他巨,所以這里貼下我的服務(wù)端配置
因?yàn)橥粋€(gè)VPS上放置了多個(gè)站點(diǎn),所以Nginx采用vhost的方式减江,將主域名以及子域名的Nginx配置文件單獨(dú)編寫染突,并放置在/etc/nginx/sites-available/下,如果哪個(gè)網(wǎng)站啟用辈灼,則在/etc/nginx/sites-enabled/下創(chuàng)建/etc/nginx/sites-available/對應(yīng)目錄的軟鏈接份企。這一套原本是Ubuntu發(fā)行版里面Nginx的默認(rèn)配置,個(gè)人覺得不錯(cuò)巡莹,所以照搬到Gentoo里使用司志。
Nginx的主配置文件/etc/nginx/nginx.conf需要加入如下配置:
http {
##
# Virtual Host Configs
##
include /etc/nginx/conf.d/*.conf;
include /etc/nginx/sites-enabled/*;
}
子域名vhost的配置甜紫,在/etc/nginx/sites-available/下創(chuàng)建文件subdomian并填入如下內(nèi)容
server {
listen 443 ssl;
server_name subdomain.your_main_domain.com;
# http://www.acunetix.com/blog/articles/configure-web-server-disclose-identity/
server_tokens off;
access_log /var/log/nginx/subdomain.your_main_domain.com.access_log;
error_log /var/log/nginx/subdomain.your_main_domain.com.error_log;
index index.html index.htm index.php;
root /var/www/your_main_domain.com/subdomain;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers EECDH+CHACHA20:EECDH+CHACHA20-draft:EECDH+AES128:RSA+AES128:EECDH+AES256:RSA+AES256:EECDH+3DES:RSA+3DES:!MD5;
ssl_session_cache builtin:1000 shared:SSL:10m;
resolver 8.8.8.8 8.8.4.4 valid=300s;
resolver_timeout 5s;
ssl_prefer_server_ciphers on;
ssl_certificate /etc/letsencrypt/live/subdomain.your_main_domain.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/subdomain.your_main_domain.com/privkey.pem;
ssl_session_timeout 5m;
ssl_session_tickets on;
ssl_stapling on;
ssl_stapling_verify on;
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";
add_header X-Frame-Options deny;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'none'; script-src 'unsafe-inline' 'unsafe-eval' blob: https:; img-src data: https: http://ip.qgy18.com; style-src 'unsafe-inline' https:; child-src https:; connect-src 'self' https://translate.googleapis.com; frame-src https://disqus.com https://www.slideshare.net";
# https://www.troyhunt.com/shhh-dont-let-your-response-headers/
proxy_hide_header Vary;
fastcgi_hide_header X-Powered-By;
fastcgi_hide_header X-Runtime;
fastcgi_hide_header X-Version;
include php-fpm.conf;
}
server {
server_name subdomain.your_main_domain.com;
listen 80;
server_tokens off;
access_log /dev/null;
location ^~ /.well-known/acme-challenge/ {
alias /home/name/.well-known/;
try_files $uri =404;
}
location / {
rewrite ^/(.*)$ https://subdomain.your_main_domain.com/$1 permanent;
}
}
}
php-fpm.conf(全路徑 /etc/nginx/php-fpm.conf)的內(nèi)容:
location ~ \.php$ {
# With php5-fpm:
#fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_pass 127.0.0.1:9000;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#fastcgi_param SCRIPT_FILENAME /var/www/$domain$subdomain$fastcgi_script_name;
include fastcgi_params;
}
注意的問題
- Gentoo的CONFIG_PROTECT問題。大家都知道骂远,對于軟件的更新,除了軟件包自身的更新外激才,還需要配置文件的更新。如果一個(gè)軟件已經(jīng)安裝并運(yùn)行吨述,它已經(jīng)在使用配置文件(這個(gè)文件有可能用戶已經(jīng)定制過),那么當(dāng)這個(gè)軟件升級后钞脂,配置文件有可能發(fā)生更新(只要和正在使用的配置文件內(nèi)容不同就會更新)揣云,這個(gè)時(shí)候冰啃,機(jī)器上正在使用的配置文件和軟件升級后的配置文件就可能發(fā)生沖突(如果內(nèi)容不一致的話)。Gentoo定義了一個(gè)變量CONFIG_PROTECT(可以在/etc/portage/make.conf中定義)來負(fù)責(zé)保護(hù)本地的正在使用的配置文件內(nèi)容阎毅,如果配置文件的路徑寫在CONFIG_PROTECT中(多個(gè)配置用空格分開焚刚,路徑為全路徑),那么當(dāng)配置文件對應(yīng)的軟件升級后扇调,這個(gè)配置文件不會被自動升級矿咕,而是在軟件升級完后系統(tǒng)會提示用戶配置文件有更新狼钮,或者用戶敲入etc-update命令后引導(dǎo)用戶解決配置文件沖突問題。參考官方文檔
- 如果CONFIG_PROTECT="-*"表示取消配置文件保護(hù)
- 如果想讓所有的配置文件都被保護(hù)莲镣,則應(yīng)該這樣寫CONFIG_PROTECT="*"
更新證書
Let’s Encrypt證書的默認(rèn)有效期只有90天涎拉,所以需要定時(shí)更新服務(wù)端的證書避免過期
一條命令更新所有服務(wù)端的證書
./letsencrypt-auto renew
添加為定時(shí)任務(wù), 編輯這個(gè)文件
sudo vi /etc/cron.monthly/letsencrypt_renew
添加如下內(nèi)容:
#!/bin/sh
/path/to/letsencrypt/letsencrypt-auto --debug renew > /var/log/letsencrypt/renew.log 2>&1
授予/etc/cron.monthly/letsencrypt_renew可執(zhí)行權(quán)限
sudo chmod a+x /etc/cron.monthly/letsencrypt_renew
撤銷證書
如果想收回(撤銷)頒發(fā)給服務(wù)端的證書,可以使用如下命令
./letsencrypt-auto revoke --cert-path /etc/letsencrypt/live/subdomain.your_main_domain.com/cert.pem
在線HTTPS配置檢查
可以使用Jerry Qu推薦的兩個(gè)在線HTTPS配置掃描服務(wù)來檢查你的網(wǎng)站HTTPS配置的問題鼓拧,并根據(jù)建議做相應(yīng)的修復(fù)。
Qualys SSL Labs's SSL Server Test
參考資料
Let’s Encrypt官網(wǎng)
Let's Encrypt慈缔,免費(fèi)好用的 HTTPS 證書
LetsEncrypt SSL 證書簽發(fā)(Nginx)
聽說DNSpod也支持Let’s Encrypt了
免費(fèi)SSL安全證書Let's Encrypt安裝使用教程(附Nginx/Apache配置)
免費(fèi)SSL證書Let’s Encrypt安裝使用教程:Apache和Nginx配置SSL
LET’S ENCRYPT免費(fèi)SSL證書申請過程
Ghost Blog啟用HTTPS使用LetsEncrypt SSL證書
Using Free SSL/TLS Certificates from Let’s Encrypt with NGINX