本部落格 Nginx 配置之安全篇
提醒:本文最後更新於 1326 天前,文中所描述的資訊可能已發生改變,請謹慎使用。
之前有細心的朋友問我,為什麼你的部落格副標題是「專注 WEB 端開發」,是不是少了「前端」的「前」。我想說的是,儘管我從畢業到現在七年左右的時間一直都在專業前端團隊從事前端相關工作,但這並不意味著我的知識體系就必須侷限於前端這個範疇內。現在比較流行「全棧工程師」的概念,我覺得全棧意味著一個專案中,各個崗位所需要的技能你都具備,但並不一定意味著你什麼都需要做。你需要做什麼,更多是由能力、人員配比以及成本等各個因素所決定。儘管我現在的工作職責是在 WEB 前端領域,但是我的關注點在整個 WEB 端。
我接觸過的有些前端朋友,從一開始就把自己侷限在一個很小的範圍之中,這在大公司到也無所謂,大公司分工明確,基礎設施齊全,你只要做好自己擅長的那部分就可以了。但是當他們進入創業公司之後,會發現一下子來了好多之前完全沒有接觸過的東西,十分被動。
去年我用 Lua + OpenResty 替換了線上千萬級的 PHP + Nginx 服務,至今穩定執行,算是前端之外的一點嘗試。我一直認為學習任何知識很重要的一點是實踐,所以我一直都在折騰我的 VPS,進行各種 WEB 安全、優化相關的嘗試。我打算從安全和效能兩方面介紹一下本部落格所用 Nginx 的相關配置,今天先寫安全相關的。
隱藏不必要的資訊
大家可以看一下我的部落格請求響應頭,有這麼一行 server: nginx
,說明我用的是 Nginx 伺服器,但並沒有具體的版本號。由於某些 Nginx 漏洞只存在於特定的版本,隱藏版本號可以提高安全性。這隻需要在配置里加上這個就可以了:
server_tokens off;
如果想要更徹底隱藏所用 Web Server,可以修改 Nginx 原始碼,把 Server Name 改掉再編譯,具體步驟可以自己搜尋。需要提醒的是:如果你的網站支援 SPDY,只改動網上那些文章寫到的地方還不夠,跟 SPDY 有關的程式碼也要改。更簡單的做法是改用 Tengine 這個 Nginx 的增強版,並指定 server_tag
為 off 或者任何想要的值就可以了。另外,既然想要徹底隱藏 Nginx,404、500 等各種出錯頁也需要自定義。
同樣,一些 WEB 語言或框架預設輸出的 x-powered-by
也會洩露網站資訊,他們一般都提供了修改或移除的方法,可以自行檢視手冊。如果部署上用到了 Nginx 的反向代理,也可以通過 proxy_hide_header 指令隱藏它:
proxy_hide_header X-Powered-By;
禁用非必要的方法
由於我的部落格只處理了 GET、POST 兩種請求方法,而 HTTP/1 協議還規定了 TRACE 這樣的方法用於網路診斷,這也可能會暴露一些資訊。所以我針對 GET、POST 以及 HEAD 之外的請求,直接返回了 444 狀態碼(444 是 Nginx 定義的響應狀態碼,會立即斷開連線,沒有響應正文)。具體配置是這樣的:
if ($request_method !~ ^(GET|HEAD|POST)$ ) {
return 444;
}
合理配置響應頭
我的部落格是由自己用 ThinkJS 寫的 Node 程式提供服務,Nginx 通過 proxy_pass 把請求反向代理給 Node 繫結的 IP 和埠。在最終輸出時,我給響應增加了以下頭部:
add_header Strict-Transport-Security "max-age=31536000";
add_header X-Frame-Options deny;
add_header X-Content-Type-Options nosniff;
add_header Content-Security-Policy "default-src 'self'; script-src 'self' 'unsafe-inline' 'unsafe-eval' https://a.disquscdn.com; img-src 'self' data: https://www.google-analytics.com; style-src 'self' 'unsafe-inline'; frame-src https://disqus.com";
Strict-Transport-Security
(簡稱為 HSTS)可以告訴瀏覽器,在指定的 max-age 內,始終通過 HTTPS 訪問我的部落格。即使使用者自己輸入 HTTP 的地址,或者點選了 HTTP 連結,瀏覽器也會在本地替換為 HTTPS 再發送請求。另外由於我的證書不支援多域名,我沒有加上 includeSubDomains
。關於 HSTS 更多資訊,可以檢視我之前的介紹。
X-Frame-Options
用來指定此網頁是否允許被 iframe 巢狀,deny 就是不允許任何巢狀發生。關於這個響應頭的更多介紹可以看這裡。
X-Content-Type-Options
用來指定瀏覽器對未指定或錯誤指定 Content-Type 資源真正型別的猜測行為,nosniff 表示不允許任何猜測。這部分內容更多介紹見這裡。
Content-Security-Policy
(簡稱為 CSP)用來指定頁面可以載入哪些資源,主要目的是減少 XSS 的發生。我允許了來自本站、disquscdn 的外鏈 JS,還允許內聯 JS,以及在 JS 中使用 eval;允許來自本站和 google 統計的圖片,以及內聯圖片(Data URI 形式);允許本站外鏈 CSS 以及內聯 CSS;允許 iframe 載入來自 disqus 的頁面。對於其他未指定的資源,都會走預設規則 self
,也就是隻允許載入本站的。關於 CSP 的詳細介紹請看這裡。
之前的部落格中,我還介紹過 X-XSS-Protection
這個響應頭,也可以用來防範 XSS。不過由於有了 CSP,所以我沒配置它。
需要注意的是,以上這些響應頭現代瀏覽器才支援,所以並不是說加上他們,網站就可以不管 XSS,萬事大吉了。但是鑑於低廉的成本,還是都配上。
HTTPS 安全配置
啟用 HTTPS 並正確配置了證書,意味著資料傳輸過程中無法被第三者解密或修改。有了 HTTPS,也得合理配置好 Web Server,才能發揮最大價值。我的部落格關於 HTTPS 這一塊有以下配置:
ssl_certificate /home/jerry/ssl/server.crt;
ssl_certificate_key /home/jerry/ssl/server.key;
ssl_dhparam /home/jerry/ssl/dhparams.pem;
ssl_ciphers ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:AES128-GCM-SHA256:AES256-GCM-SHA384:DES-CBC3-SHA;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
最終效果是我的部落格在 ssllabs 的測試中達到了 A+,如下圖:
如何配置 ssl_ciphers
可以參考這個網站。需要注意的是,這個網站預設提供的加密方式安全性較高,一些低版本客戶端並不支援,例如 IE9-、Android2.2- 和 Java6-。如果需要支援這些老舊的客戶端,需要點一下網站上的「Yes, give me a ciphersuite that works with legacy / old software」連結。
另外,我在 ssl_ciphers
最開始加上了 CHACHA20
,這是因為我的 Nginx 支援了 CHACHA20_POLY1305 加密演算法,這是由 Google 開發的新一代加密方式,它有兩方面優勢:更好的安全性和更好的效能(尤其是在移動和可穿戴裝置上)。下面有一張移動平臺上它與 AES-GCM 的加密速度對比圖(via):
啟用 CHACHA20_POLY1305 最簡單的方法是在編譯 Nginx 時,使用 LibreSSL 代替 OpenSSL。下面是用 Chrome 訪問我的部落格時,點選位址列小鎖顯示的資訊,可以看到加密方式使用的就是 CHACHA20_POLY1305:
關於 CHACHA20_POLY1305 安全性和效能的詳細介紹可以檢視本文。
補充:使用 CHACHA20_POLY1305 的最佳實踐是「僅針對不支援 AES-NI 的終端使用 CHACHA20 演算法,否則使用 AES-GCM」。關於這個話題的詳細解釋和配置方法,請參考我的這篇文章:使用 BoringSSL 優化 HTTPS 加密演算法選擇。
SSLv3 已被證實不安全,所以在 ssl_protocols
指令中,我並沒有包含它。
將 ssl_prefer_server_ciphers
配置為 on,可以確保在 TLSv1 握手時,使用服務端的配置項,以增強安全性。
好了,本文先就這樣,後面再寫跟效能有關的配置。
--EOF--
發表於 2015-05-24 20:02:42 ,並被新增「 Nginx 、 Web安全 」標籤 ,最後修改於 2015-05-25 14:30:53 。檢視本文 Markdown 版本 »
提醒:本文最後更新於 1326 天前,文中所描述的資訊可能已發生改變,請謹慎使用。
相關推薦
本部落格 Nginx 配置之安全篇
提醒:本文最後更新於 1326 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 之前有細心的朋友問我,為什麼你的部落格副標題是「專注 WEB 端開發」,是不是少了「前端」的「前」。我想說的是,儘管我從畢業到現在七年左右的時間一直都在專業前端團隊從事前端相關工作,但這並不意味著我的知識體系就必
本部落格 Nginx 配置之效能篇
提醒:本文最後更新於 1323 天前,文中所描述的資訊可能已發生改變,請謹慎使用。 在介紹完我部落格(imququ.com)的 Nginx 配置中與安全有關的一些配置後,這篇文章繼續介紹與效能有關的一些配置。WEB 效能優化是一個系統工程,涵蓋很多方面,做好其中某個環節並不意味效能就能變好,但可
部署Django部落格全記錄之Nginx篇(一)
Nginx的優點 注:具體原理沒搞清,先記著 Nginx更安全;Nginx能更好地處理靜態資源(通過一些http request header)。 Nginx也可以快取一些動態內容;Nginx可以更好地配合CDN。 Nginx可以進行多臺機器的負載均
Nginx配置之location模塊和proxy模塊
event end 虛擬主機 include 當我 服務 文件的 域名 時間 1、location指令的用法介紹 Location主要用來匹配url,如:http://www.beyond.com/nice,在這裏對於location來說www.beyond.com是域名
nginx配置—之location模式匹配
jpeg ack fetch 定義 正則表達式 con 搜索 其他 error 1、location正則 ~ 表示一個正則匹配,區分大小寫 ~* 表示一個正則匹配,不區分大小寫 ^~ 表示普通字符匹配,一般用來匹配目錄 = 表示
筆記搬到部落格 - nginx一步步整合lua模組
經過網路搜尋、整理、實踐筆記 前置條件:已安裝nginx 一 、安裝LuaJit 1.下載LuaJit http://luajit.org/download.html [[email protected]_6 source]$
筆記搬到部落格 - Nginx代理websocket超時連線斷開問題
經過網路搜尋、整理、實踐筆記 配置nginx使之支援websockt的反響代理後,發現websockt連線上就立即斷開,狀態碼為:1006 最後查到原因是proxy_read_timeout 太小,這便是websockt的有效時間 現在配置成3600,也就是維持一個小時
部落格開發總結之頁面編寫
前面是一堆廢話,正文下拉!!! 學習Java斷斷續續也快兩年了(實際應該是一年多),從大學第一次接觸C語言,就發現自己其實是喜歡程式設計的。在高中的時候,聽說了C語言後就想要學習,覺得寫程式碼是一件很酷的事情,於是在網上找了一份教程,試著在命令列介面printf("hello,world");
部落格開發總結之後臺程式碼
寫這個部落格專案也是我第一次使用Spring Boot框架,用過之後,發現真的回不去了。省去了一大堆配置檔案,簡直不能再爽。之前用Spring MVC,Spring,Hibernate,MyBatis等框架,繁瑣的配置檔案,每一個專案都是那一套,感覺不是在學框架內容,而是在學寫配置檔案。Spring
本部落格程式碼與mallocfree相關申明
首先 先看我的舊部落格 http://www.dongj.cc/blog/ 部落格中 正常人都能知道我是mallocfree出來的學員 本部落格程式碼不大部分程式碼是基於微軟的驅動演示包進行修改的 malllocfree宣稱程式碼有“著作權” 我想說: 在mal
C與C++實現高維陣列的動態開闢(本部落格學習於51CTO 鮑松山 C++高階教程)
目錄 1.VS安裝VLD記憶體洩露檢測工具 2.C語言下實現二維陣列的動態開闢 3.C++下實現二維陣列的動態開闢 4.C++下實現高維陣列的動態開闢 1.VS安裝記憶體洩漏檢測工具VLD 參考這篇部落格即可:https://blog.csdn.net/GZrhaunt/
在部落格園中配置MathJax
對於經常在部落格中撰寫學術與技術類文章的網友來說,能夠直接插入LaTeX數學公式是一項非常實用與方便的功能。幸好部落格園已經提供了對MathJax數學公式的支援,只要在部落格後臺管理介面中的“選項”一欄中勾選“啟用數學公式支援”即可。接下來,為了使用自定義的LaTeX命令與數學符號,一般來說,就需要使用Jav
本部落格去廣告規則設定
本規則適合Firefox 與 Chrome上面的 AdBlocker Ultimate 1.安裝 外掛安裝過程略 2.FireFox外掛新增自定義規則 依次填入以下規則,然後新增即可: blog.csdn.net###nav-left-menu > LI:fir
nginx 配置之 proxy_pass引數詳解
在nginx中配置proxy_pass代理轉發時,如果在proxy_pass後面的url加/,表示絕對根路徑; 如果沒有/,表示相對路徑,把匹配的路徑部分也給代理走。 假設下面四種情況分別用 http://192.168.1.1/proxy/aerchi.html 進行訪問。 第一種:
Nginx配置之負載均衡、限流、快取、黑名單和灰度釋出
一、Nginx安裝(基於CentOS 6.5) 1.yum命令安裝 yum install nginx –y (若不能安裝,執行命令yum install epel-release) 2. 啟動、停止和重啟 service nginx start service nginx stop
部署Django部落格全記錄之Gunicorn篇(二)
什麼是Gunicorn Gunicorn是一個被廣泛使用的高效能的Python WSGI UNIX HTTP伺服器,移植自Ruby的獨角獸(Unicorn )專案,使用pre-fork worker模式,具有使用非常簡單,輕量級的資源消耗,以及高效能等特點。 為什麼使用
派大星部落格的美化之路
主題 SimpleMemory 更改背景顏色、標題、子標題 css #blogTitle h1 a { color: #515151; background: #EEE url(data:image/gif;base64,iVBORw0KGgoAAAANSUhEUgAAAAQAAAA
【Mr_厚厚的部落格】學之愈深,愈是心生畏懼!
人生苦短,道阻且艱;修行不易,且行且努力。 【專業擅長領域】:iOS開發,遊戲開發,圖形學 【擅長平臺】:iOS平臺,Unity --------------------------------------------------------- 【個人主頁】:信厚
OpenPLC--可程式設計控制器的發展趨勢[本部落格注:內容主要是關於PLC的開放性與現狀]
一、PLC的發展歷史 可程式設計邏輯控制器,又稱可程式設計控制器,有過多種定義。可以看作是一種經過特殊設計的產業計算機,整個的設計原則就是簡單與實用。1968年,通用汽車公司的液壓部分為了消除既複雜又昂貴的繼電器控制系統,確立了第一個可程式設計控制器的招標指標。該設計規格需要固態系統和電腦技術,並要求能夠在產
送人玫瑰,手留餘香,如果本部落格幫助到你了,幫忙點開本篇投上一票
送人玫瑰,手留餘香,如果本部落格幫助到您了,幫忙點開本篇,為我投上一票,謝謝,2019年,我們相約,繼續加油! 而選擇投票的您,也將有機會獲得免費開跑車的機會。 請選擇第4位候選人:004 Soyoger 投票即可。 投票地址:https://bs