關註上方 浩道Linux ,回復 資料 ,即可獲取海量 L inux 、 Python 、 網路通訊、網路安全 等學習資料!
前言
大家好,這裏是 浩道Linux ,主要給大家分享 L inux 、 P ython 、 網路通訊、網路安全等 相關的IT知識平台。
今天浩道跟大家分享Nginx 生產環境下的安全配置相關硬核幹貨,可以說安全的策略,我們運維人員應該形成一種先天意識,不得不會,一起學習下吧!
文章來源:https://blog.51cto.com/u_14249042/7633794
Nginx簡介
Nginx 是開源、高效能、高可靠的 Web 和反向代理伺服器,而且支持熱部署,幾乎可以做到 7 * 24 小時不間斷執行,即使執行幾個月也不需要重新啟動,還能在不間斷服務的情況下對軟體版本進行熱更新。效能是 Nginx 最重要的考量,其占用記憶體少、並行能力強、能支持高達 5w 個並行連線數,最重要的是, Nginx 是免費的並可以商業化,配置使用也比較簡單。
Nginx是一款輕量級的Web 伺服器/反向代理伺服器及電子信件(IMAP/POP3)代理伺服器,在BSD-like 協定下發行。其特點是占有記憶體少,並行能力強,事實上nginx的並行能力在同型別的網頁伺服器中表現較好,中國大陸使用nginx網站使用者有:百度、京東、新浪、網易、騰訊、淘寶等。
官網對各個模組參數配置的解釋說明網址: https://www.nginx.cn/doc/index.html
Nginx能幹什麽
做虛擬主機
那什麽是虛擬主機呢?也就是說,這個主機是不存在的,是虛擬出來的。而我們原來所說的伺服器,實際上是一台真正的PC機。所以虛擬主機就是原本這個機器不存在,但我們可以使用軟體模擬出來,這個就叫做虛擬主機。
反向代理
原本我們需要存取A機器,但現在我們可以透過B機器,轉發到A機器來實作存取,B機器就叫做代理。
負載均衡策略
首先我們來了解一下什麽叫負載,舉個例子,我們每個人背的 "東西"就是負載。而均衡則是指每個人背的東西一樣多。
在程式中,如果有多台伺服器來承載請求,那麽每個伺服器承載的請求個數是一樣的,這就稱為負載均衡。
輪詢策略
輪詢就是每個請求按時間順序,逐一分配到不同的後端伺服器,這是預設的負載均衡策略。如果後端伺服器down掉,能自動剔除。
權重(weight)策略
weight代表權重,預設為 1,權重越高被分配的客戶端就越多。指定輪詢機率,weight權重大小和存取比率成正比,該策略常用於後端伺服器效能不均衡的情況下。
IP_hash策略
ip_hash就是會對每個請求存取的ip進行hash運算,再根據結果進行分配,這樣每個訪客固定存取一個後端伺服器。
Nginx基本目錄解析
Nginx安全配置
以上對Nginx做了基本的功能介紹,下面重點介紹一下,我們的站點部署在生產環境下,如何去做安全配置和最佳化。
Nginx常用命令
nginx -s reload # 向主行程發送訊號,重新載入配置檔,熱重新開機
nginx -s reopen # 重新開機 Nginx
nginx -s stop # 快速關閉
nginx -s quit # 等待工作行程處理完成後關閉
nginx -T # 檢視當前 Nginx 最終的配置
nginx -t # 檢查配置是否有問題
nginx.conf配置檔結構
Nginx 的典型配置範例:
# main段配置資訊
user nginx; # 執行使用者,預設即是nginx,可以不進行設定
worker_processes auto; # Nginx 行程數,一般設定為和 CPU 核數一樣
error_log /var/log/nginx/error.log warn; # Nginx 的錯誤日誌存放目錄
pid /var/run/nginx.pid; # Nginx 服務啟動時的 pid 存放位置
# events段配置資訊
events {
useepoll; # 使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你作業系統的)
worker_connections1024; # 每個行程允許最大並行數
}
# http段配置資訊
# 配置使用最頻繁的部份,代理、緩存、日誌定義等絕大多數功能和第三方模組的配置都在這裏設定
http {
# 設定日誌模式
log_format main '$remote_addr - $remote_user [$time_local] "$request" '
'$status$body_bytes_sent "$http_referer" '
'"$http_user_agent" "$http_x_forwarded_for"';
access_log /var/log/nginx/access.log main; # Nginx存取日誌存放位置
sendfileon; # 開啟高效傳輸模式
tcp_nopushon; # 減少網路報文段的數量
tcp_nodelayon;
keepalive_timeout65; # 保持連線的時間,也叫超時時間,單位秒
types_hash_max_size2048;
include /etc/nginx/mime.types; # 副檔名與型別對映表
default_type application/octet-stream; # 預設檔型別
include /etc/nginx/conf.d/*.conf; # 載入子配置項
# server段配置資訊
server {
listen80; # 配置監聽的埠
server_name localhost; # 配置的網域名稱
# location段配置資訊
location / {
root /usr/share/nginx/html; # 網站根目錄
index index.html index.htm; # 預設首頁檔
deny172.168.22.11; # 禁止存取的ip地址,可以為all
allow172.168.33.44;# 允許存取的ip地址,可以為all
}
error_page 500502503504 /50x.html; # 預設50x對應的存取頁面
error_page400404error.html; # 同上
}
}
main 全域配置,對全域生效;
events 配置影響 Nginx 伺服器與使用者的網路連線;
http 配置代理,緩存,日誌定義等絕大多數功能和第三方模組的配置;
server 配置虛擬主機的相關參數,一個 http 塊中可以有多個 server 塊;
location 用於配置匹配的 uri ;
upstream 配置後端伺服器具體地址,負載均衡配置不可或缺的部份;
用一張圖清晰的展示它的層級結構:
nginx.conf 配置檔的語法規則:
配置檔由指令與指令塊構成
每條指令以 「;」 分號結尾,指令與參數間以空格符號分隔
指令塊以 {} 大括弧將多條指令組織在一起
include 語句允許組合多個配置檔以提升可維護性
透過 # 符號添加註釋,提高可讀性
透過 $ 符號使用變量
部份指令的參數支持正規表式,例如常用的 location 指令
基礎防護設定
nginx 版本資訊隱藏
server_tokensoff;
隱藏Nginx後端服務X-Powered-By頭
在http下配置proxy_hide_header項;
增加或修改為
proxy_hide_headerX-Powered-By;
proxy_hide_headerServer;
proxy_buffers和client_body_buffer_size的區別
client_body_buffer_size
處理客戶端請求體buffer大小。用來處理POST送出數據,上傳檔等。
client_body_buffer_size
需要足夠大以容納如果需要上傳POST數據。
proxy_buffers
處理後端響應,一般是代理伺服器請求後端服務的response。
如果這個buffer不夠大,會引起磁盤IO,response的body內容會先寫入臨時目錄中。
黑白名單設定
如果網站被惡意灌水或 CC 攻 擊,可從網站日誌中分析特征 IP,將其 IP 或 IP 段進行遮蔽。
#語法
#allow address | CIDR | all;
#deny address | CIDR | all;
#模組:http/server/location
#參數說明:
#allow:允許存取。
#deny:禁止存取。
#address:具體的ip地址。
#CIDR:ip加掩碼形式地址。
#all:所有ip地址。
白名單:
# 只允許192.168.1.0/24網段的主機存取,拒絕其他所有
location /path/ {
allow 192.168.1.0/24;
deny all;
}
黑名單:
location /path/ {
deny 192.168.1.0/24;
allow all;
}
更多的時候客戶端請求會經過層層代理,我們需要透過$http_x_forwarded_for來進行限制,可以這樣寫
set$allowfalse;
if ($http_x_forwarded_for = "211.144.204.2") { set$allowtrue; }
if ($http_x_forwarded_for ~ "108.2.66.[89]") { set$allowtrue; }
if ($allow = false) { return 404; }
遮蔽非常見蜘蛛(爬蟲)
分析網站日誌發現,一些奇怪的 UA 總是頻繁的來存取,而這些 UA 對網站毫無意義,反而給伺服器增加壓力,可以直接將其遮蔽。
if ($http_user_agent ~(SemrushBot|python|MJ12bot|AhrefsBot|AhrefsBot|hubspot|opensiteexplorer|leiki|webmeup)) {
return444;
}
上面規則報錯 444 狀態碼而不是 403。444 狀態碼在 nginx 的中有特殊含義,nginx 的 444 狀態是直接由伺服器中斷連線,不會向客戶端再返回任何訊息。比返回 403 更加暴力。
禁止某個目錄執行指令碼
網站目錄,通常存放的都是靜態檔,如果因程式驗證不嚴謹被上傳木馬程式,導致網站被黑。以下規則請根據自身情況改為您自己的目錄,需要禁止的指令碼字尾也可以自行添加。
#uploads|templets|data 這些目錄禁止執行 <a href="https://hexsen.com/tag/phpcode" title="更多關於 PHP 的文章" target="_blank">PHP</a>
location ~* ^/(uploads|templets|data)/.*.(php|php5)$ {
return444;
}
防止檔被下載
比如將網站資料庫匯出到站點根目錄進行備份,很有可能也會被別人下載,從而導致數據遺失的風險。以下規則可以防止一些常規的檔被下載,可根據實際情況增減。
location~ \.(zip|rar|sql|bak|gz|7z)$ {
return444;
}
防止XSS攻擊:server
在通常的請求響應中,瀏覽器會根據Content-Type來分辨響應的型別,但當響應型別未指定或錯誤指定時,瀏覽會嘗試啟用MIME-sniffing來猜測資源的響應型別,這是非常危險的,例如一個.jpg的圖片檔被惡意嵌入了可執行的js程式碼,在開啟資源型別猜測的情況下,瀏覽器將執行嵌入的js程式碼,可能會有意想不到的後果。
add_headerX-Frame-Options "SAMEORIGIN";
add_headerX-XSS-Protection "1; mode=block";
add_headerX-Content-Type-Options "nosniff";
*X-Frame-Options:響應頭表示是否允許瀏覽器載入frame等內容,有三個配置
DENY:禁止任何網頁被嵌入;
SAMEORIGIN: 只允許本網站的巢狀;
ALLOW-FROM: 允許指定地址的巢狀;
*X-XSS-Protection:表示啟用XSS過濾(禁用過濾為X-XSS-Protection: 0),mode=block表示若檢查到XSS攻擊則停止渲染頁面
*X-Content-Type-Options:響應頭用來指定瀏覽器對未指定或錯誤指定Content-Type資源真正型別的猜測行為,nosniff 表示不允許任何猜測;
其他請求頭的安全配置:server
定義頁面可以載入哪些資源,上邊的配置會限制所有的外部資源,都只能從當前網域名稱載入,其中default-src定義針對所有型別資源的預設載入策略,self允許來自相同來源的內容
add_header Content-Security-Policy "default-src 'self'";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
會告訴瀏覽器用HTTPS協定代替HTTP來存取目標站點,上邊的配置表示當使用者第一次存取後,會返回一個包含了Strict-Transport-Security響應頭的欄位,這個欄位會告訴瀏覽器,在接下來的31536000秒內,當前網站的所有請求都使用https協定存取,參數includeSubDomains是可選的,表示所有子網域名稱也將采用同樣的規則
緩沖區溢位攻擊
透過將數據寫入緩沖區(http、server、location )並超出緩沖區邊界和重寫記憶體片段來實作的,限制緩沖區大小可有效防止
client_body_buffer_size 1K;
client_header_buffer_size 1k;
client_max_body_size 1k;
large_client_header_buffers 2 1k;
* client_body_buffer_size:預設8k或16k,表示客戶端請求body占用緩沖區大小。如果連線請求超過緩存區指定的值,那麽這些請求實體的整體或部份將嘗試寫入一個臨時檔。
* client_header_buffer_size:表示客戶端請求頭部的緩沖區大小。絕大多數情況下一個請求頭不會大於1k,不過如果有來自於wap客戶端的較大的cookie它可能會大於 1k,Nginx將分配給它一個更大的緩沖區,這個值可以在large_client_header_buffers裏面設定
* client_max_body_size:表示客戶端請求的最大可接受body大小,它出現在請求頭部的Content-Length欄位, 如果請求大於指定的值,客戶端將收到一個"Request Entity Too Large" (413)錯誤,通常在上傳檔到伺服器時會受到限制
* large_client_header_buffers 表示一些比較大的請求頭使用的緩沖區數量和大小,預設一個緩沖區大小為作業系統中分頁檔大小,通常是4k或8k,請求欄位不能大於一個緩沖區大小,如果客戶端發送一個比較大的頭,nginx將返回"Request URI too large" (414),請求的頭部最長欄位不能大於一個緩沖區,否則伺服器將返回"Bad request" (400)
同時需要修改幾個超時時間的配置:
client_body_timeout 10;
client_header_timeout 10;
keepalive_timeout 5 5;
send_timeout 10;
* client_body_timeout:表示讀取請求body的超時時間,如果連線超過這個時間而客戶端沒有任何響應,Nginx將返回"Request time out" (408)錯誤
* client_header_timeout:表示讀取客戶端請求頭的超時時間,如果連線超過這個時間而客戶端沒有任何響應,Nginx將返回"Request time out" (408)錯誤
* keepalive_timeout:參數的第一個值表示客戶端與伺服器長連線的超時時間,超過這個時間,伺服器將關閉連線,可選的第二個參數參數列示Response頭中Keep-Alive: timeout=time的time值,這個值可以使一些瀏覽器知道什麽時候關閉連線,以便伺服器不用重復關閉,如果不指定這個參數,nginx不會在應Response頭中發送Keep-Alive資訊
* send_timeout:表示發送給客戶端應答後的超時時間,Timeout是指沒有進入完整established狀態,只完成了兩次握手,如果超過這個時間客戶端沒有任何響應,nginx將關閉連線
防盜鏈:server、location
location/images/ {
valid_referersnone blocked www.ops-coffee.cn ops-coffee.cn;
if($invalid_referer) {
return403;
}
}
valid_referers:驗證referer,
none:允許referer為空
blocked:允許不帶協定的請求
除了以上兩類外僅允許referer為www.ops-coffee.cn或ops-coffee.cn時存取images下的圖片資源,否則返回403
給不符合referer規則的請求重新導向到一個預設的圖片
location /images/ {
valid_referersblocked www.ops-coffee.cn ops-coffee.cn
if ($invalid_referer) {
rewrite ^/images/.*\.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last;
}
}
一、限制存取方法
禁止不安全的HTTP方法
預設情況下,Nginx支持多種HTTP方法,包括GET、POST、OPTIONS等。然而,某些HTTP方法可能存在安全風險,例如TRACE方法可以被用於跨站指令碼(XSS)攻擊。我們可以使用Nginx的"limit_except"指令來限制某些HTTP方法的存取。
範例程式碼:
location / {
limit_except GET POST {
deny all;
}
}
關閉不必要的目錄列表
如果Nginx的目錄沒有預設的index檔,會自動展示目錄下的檔列表,這可能會暴露敏感資訊。我們可以透過禁止自動目錄列表的方式來阻止此行為。
範例程式碼:
location / {
autoindexoff;
}
添加帳號認證:http、server、location
server {
location / {
auth_basic"please input user&passwd";
auth_basic_user_file key/auth.key;
}
}
二、防止惡意請求和攻擊
防止惡意請求
惡意請求包括大量的請求、大檔上傳、惡意指令碼等等,這會導致伺服器負載過高。我們可以透過設定請求限制,來防止這種情況發生。
範例程式碼:
http {
limit_req_zone$binary_remote_addr zone=req_limit:10m rate=1r/s;
server {
location / {
limit_req zone=req_limit burst=5 nodelay;
# 其他配置
}
}
}
上述程式碼中,我們使用"limit_req_zone"指令來定義請求限制區域,設定限制的大小和速率(每秒最多允許1個請求)。然後,在相應的"server"配置中使用"limit_req"指令來套用該限制區域。
限制請求方法:server、location
if ($request_method !~ ^(GET|POST)$ ) {
return 405;
}
$request_method能夠獲取到請求nginx的method
配置只允許GET\POST方法存取,其他的method返回405
拒絕User-Agent:server、location
if ($http_user_agent ~* LWP::Simple|BBBike|wget|curl) {
return 444;
}
可能有一些不法者會利用wget/curl等工具掃描我們的網站,我們可以透過禁止相應的user-agent來簡單的防範
Nginx的444狀態比較特殊,如果返回444那麽客戶端將不會收到伺服端返回的資訊,就像是網站無法連線一樣
防止常見攻擊
Nginx預設提供了一些防止常見攻擊的配置選項,例如:
防止緩沖區溢位攻擊:
proxy_buffer_size
和proxy_buffers
配置選項防止HTTP請求頭過大攻擊:
large_client_header_buffers
配置選項防止URI長度過大攻擊:
large_client_header_buffers
配置選項防止惡意請求:
client_max_body_size
配置選項防止DDoS攻擊:
limit_conn
和limit_req
配置選項
三、使用HTTPS保證數據傳輸安全
HTTPS協定可以保證數據傳輸的機密性和完整性,防止數據被竊取或篡改。使用HTTPS可以防止中間人攻擊、數據劫持等安全問題。我們可以使用Nginx提供的SSL模組來配置HTTPS。
範例程式碼:
server {
listen443 ssl;
server_name example.com;
ssl_certificate /path/to/certificate.crt;
ssl_certificate_key /path/to/private.key;
location / {
# 其他配置
}
}
上述程式碼中,我們使用
listen 443 ssl
指令來監聽443埠,並使用
ssl_certificate
和
ssl_certificate_key
配置選項指定SSL證書路徑。
更多精彩
關註公眾號 「 浩道Linux 」
浩道Linux ,專註於 Linux系統 的相關知識、 網路通訊 、 網路安全 、 Python相關 知識以及涵蓋IT行業相關技能的學習, 理論與實戰結合,真正讓你在學習工作中真正去用到所學。同時也會分享一些面試經驗,助你找到高薪offer,讓我們一起去學習,一起去進步,一起去漲薪!期待您的加入~~~ 關註回復「資料」可 免費獲取學習資料 (含有電子書籍、視訊等)。
喜歡的話,記得 點「贊」 和 「在看」 哦