Nginx簡介
Nginx 是開源、高性能、高可靠的 Web 和反向代理服務(wù)器,而且支持熱部署,幾乎可以做到 7 * 24 小時(shí)不間斷運(yùn)行,即使運(yùn)行幾個月也不需要重新啟動,還能在不間斷服務(wù)的情況下對軟件版本進(jìn)行熱更新。性能是 Nginx 最重要的考量,其占用內(nèi)存少、并發(fā)能力強(qiáng)、能支持高達(dá) 5w 個并發(fā)連接數(shù),最重要的是, Nginx 是免費(fèi)的并可以商業(yè)化,配置使用也比較簡單。
Nginx是一款輕量級的Web 服務(wù)器/反向代理服務(wù)器及電子郵件(IMAP/POP3)代理服務(wù)器,在BSD-like 協(xié)議下發(fā)行。其特點(diǎn)是占有內(nèi)存少,并發(fā)能力強(qiáng),事實(shí)上nginx的并發(fā)能力在同類型的網(wǎng)頁服務(wù)器中表現(xiàn)較好,中國大陸使用nginx網(wǎng)站用戶有:百度、京東、新浪、網(wǎng)易、騰訊、淘寶等。
官網(wǎng)對各個模塊參數(shù)配置的解釋說明網(wǎng)址:https://www.nginx.cn/doc/index.html
Nginx能干什么
做虛擬主機(jī)
那什么是虛擬主機(jī)呢?也就是說,這個主機(jī)是不存在的,是虛擬出來的。而我們原來所說的服務(wù)器,實(shí)際上是一臺真正的PC機(jī)。所以虛擬主機(jī)就是原本這個機(jī)器不存在,但我們可以使用軟件模擬出來,這個就叫做虛擬主機(jī)。
反向代理
原本我們需要訪問A機(jī)器,但現(xiàn)在我們可以通過B機(jī)器,轉(zhuǎn)發(fā)到A機(jī)器來實(shí)現(xiàn)訪問,B機(jī)器就叫做代理。
負(fù)載均衡策略
首先我們來了解一下什么叫負(fù)載,舉個例子,我們每個人背的 "東西"就是負(fù)載。而均衡則是指每個人背的東西一樣多。
在程序中,如果有多臺服務(wù)器來承載請求,那么每個服務(wù)器承載的請求個數(shù)是一樣的,這就稱為負(fù)載均衡。
輪詢策略
輪詢就是每個請求按時(shí)間順序,逐一分配到不同的后端服務(wù)器,這是默認(rèn)的負(fù)載均衡策略。如果后端服務(wù)器down掉,能自動剔除。
權(quán)重(weight)策略
weight代表權(quán)重,默認(rèn)為 1,權(quán)重越高被分配的客戶端就越多。指定輪詢幾率,weight權(quán)重大小和訪問比率成正比,該策略常用于后端服務(wù)器性能不均衡的情況下。
IP_hash策略
ip_hash就是會對每個請求訪問的ip進(jìn)行hash運(yùn)算,再根據(jù)結(jié)果進(jìn)行分配,這樣每個訪客固定訪問一個后端服務(wù)器。
Nginx基本目錄解析
Nginx安全配置
以上對Nginx做了基本的功能介紹,下面重點(diǎn)介紹一下,我們的站點(diǎn)部署在生產(chǎn)環(huán)境下,如何去做安全配置和優(yōu)化。
Nginx常用命令
nginx -s reload # 向主進(jìn)程發(fā)送信號,重新加載配置文件,熱重啟 nginx -s reopen # 重啟 Nginx nginx -s stop # 快速關(guān)閉 nginx -s quit # 等待工作進(jìn)程處理完成后關(guān)閉 nginx -T # 查看當(dāng)前 Nginx 最終的配置 nginx -t # 檢查配置是否有問題
nginx.conf配置文件結(jié)構(gòu)
Nginx 的典型配置示例:
# main段配置信息 user nginx; # 運(yùn)行用戶,默認(rèn)即是nginx,可以不進(jìn)行設(shè)置 worker_processes auto; # Nginx 進(jìn)程數(shù),一般設(shè)置為和 CPU 核數(shù)一樣 error_log /var/log/nginx/error.log warn; # Nginx 的錯誤日志存放目錄 pid /var/run/nginx.pid; # Nginx 服務(wù)啟動時(shí)的 pid 存放位置 # events段配置信息 events { use epoll; # 使用epoll的I/O模型(如果你不知道Nginx該使用哪種輪詢方法,會自動選擇一個最適合你操作系統(tǒng)的) worker_connections 1024; # 每個進(jìn)程允許最大并發(fā)數(shù) } # http段配置信息 # 配置使用最頻繁的部分,代理、緩存、日志定義等絕大多數(shù)功能和第三方模塊的配置都在這里設(shè)置 http { # 設(shè)置日志模式 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訪問日志存放位置 sendfile on; # 開啟高效傳輸模式 tcp_nopush on; # 減少網(wǎng)絡(luò)報(bào)文段的數(shù)量 tcp_nodelay on; keepalive_timeout 65; # 保持連接的時(shí)間,也叫超時(shí)時(shí)間,單位秒 types_hash_max_size 2048; include /etc/nginx/mime.types; # 文件擴(kuò)展名與類型映射表 default_type application/octet-stream; # 默認(rèn)文件類型 include /etc/nginx/conf.d/*.conf; # 加載子配置項(xiàng) # server段配置信息 server { listen 80; # 配置監(jiān)聽的端口 server_name localhost; # 配置的域名 # location段配置信息 location / { root /usr/share/nginx/html; # 網(wǎng)站根目錄 index index.html index.htm; # 默認(rèn)首頁文件 deny 172.168.22.11; # 禁止訪問的ip地址,可以為all allow 172.168.33.44;# 允許訪問的ip地址,可以為all } error_page 500 502 503 504 /50x.html; # 默認(rèn)50x對應(yīng)的訪問頁面 error_page 400 404 error.html; # 同上 } }
main 全局配置,對全局生效;
events 配置影響 Nginx 服務(wù)器與用戶的網(wǎng)絡(luò)連接;
http 配置代理,緩存,日志定義等絕大多數(shù)功能和第三方模塊的配置;
server 配置虛擬主機(jī)的相關(guān)參數(shù),一個 http 塊中可以有多個 server 塊;
location 用于配置匹配的 uri ;
upstream 配置后端服務(wù)器具體地址,負(fù)載均衡配置不可或缺的部分;
用一張圖清晰的展示它的層級結(jié)構(gòu):
nginx.conf 配置文件的語法規(guī)則:
配置文件由指令與指令塊構(gòu)成
每條指令以 “;” 分號結(jié)尾,指令與參數(shù)間以空格符號分隔
指令塊以 {} 大括號將多條指令組織在一起
include 語句允許組合多個配置文件以提升可維護(hù)性
通過 # 符號添加注釋,提高可讀性
通過 $ 符號使用變量
部分指令的參數(shù)支持正則表達(dá)式,例如常用的 location 指令
基礎(chǔ)防護(hù)設(shè)置
nginx 版本信息隱藏
server_tokens off;
隱藏Nginx后端服務(wù)X-Powered-By頭
在http下配置proxy_hide_header項(xiàng); 增加或修改為 proxy_hide_header X-Powered-By; proxy_hide_header Server;
proxy_buffers和client_body_buffer_size的區(qū)別
client_body_buffer_size
處理客戶端請求體buffer大小。用來處理POST提交數(shù)據(jù),上傳文件等。
client_body_buffer_size
需要足夠大以容納如果需要上傳POST數(shù)據(jù)。
proxy_buffers
處理后端響應(yīng),一般是代理服務(wù)器請求后端服務(wù)的response。
如果這個buffer不夠大,會引起磁盤IO,response的body內(nèi)容會先寫入臨時(shí)目錄中。
黑白名單設(shè)置
如果網(wǎng)站被惡意灌水或 CC 攻 擊,可從網(wǎng)站日志中分析特征 IP,將其 IP 或 IP 段進(jìn)行屏蔽。
#語法 #allow address | CIDR | all; #deny address | CIDR | all; #模塊:http/server/location #參數(shù)說明: #allow:允許訪問。 #deny:禁止訪問。 #address:具體的ip地址。 #CIDR:ip加掩碼形式地址。 #all:所有ip地址。 白名單: # 只允許192.168.1.0/24網(wǎng)段的主機(jī)訪問,拒絕其他所有 location /path/ { allow 192.168.1.0/24; deny all; } 黑名單: location /path/ { deny 192.168.1.0/24; allow all; } 更多的時(shí)候客戶端請求會經(jīng)過層層代理,我們需要通過$http_x_forwarded_for來進(jìn)行限制,可以這樣寫 set $allow false; if ($http_x_forwarded_for = "211.144.204.2") { set $allow true; } if ($http_x_forwarded_for ~ "108.2.66.[89]") { set $allow true; } if ($allow = false) { return 404; }
屏蔽非常見蜘蛛(爬蟲)
分析網(wǎng)站日志發(fā)現(xiàn),一些奇怪的 UA 總是頻繁的來訪問,而這些 UA 對網(wǎng)站毫無意義,反而給服務(wù)器增加壓力,可以直接將其屏蔽。
if ($http_user_agent ~(SemrushBot|python|MJ12bot|AhrefsBot|AhrefsBot|hubspot|opensiteexplorer|leiki|webmeup)) { return 444; }
上面規(guī)則報(bào)錯 444 狀態(tài)碼而不是 403。444 狀態(tài)碼在 nginx 的中有特殊含義,nginx 的 444 狀態(tài)是直接由服務(wù)器中斷連接,不會向客戶端再返回任何消息。比返回 403 更加暴力。
禁止某個目錄執(zhí)行腳本
網(wǎng)站目錄,通常存放的都是靜態(tài)文件,如果因程序驗(yàn)證不嚴(yán)謹(jǐn)被上傳木馬程序,導(dǎo)致網(wǎng)站被黑。以下規(guī)則請根據(jù)自身情況改為您自己的目錄,需要禁止的腳本后綴也可以自行添加。
#uploads|templets|data 這些目錄禁止執(zhí)行 PHP location ~* ^/(uploads|templets|data)/.*.(php|php5)$ { return 444; }
防止文件被下載
比如將網(wǎng)站數(shù)據(jù)庫導(dǎo)出到站點(diǎn)根目錄進(jìn)行備份,很有可能也會被別人下載,從而導(dǎo)致數(shù)據(jù)丟失的風(fēng)險(xiǎn)。以下規(guī)則可以防止一些常規(guī)的文件被下載,可根據(jù)實(shí)際情況增減。
location ~ .(zip|rar|sql|bak|gz|7z)$ { return 444; }
防止XSS攻擊:server
在通常的請求響應(yīng)中,瀏覽器會根據(jù)Content-Type來分辨響應(yīng)的類型,但當(dāng)響應(yīng)類型未指定或錯誤指定時(shí),瀏覽會嘗試啟用MIME-sniffing來猜測資源的響應(yīng)類型,這是非常危險(xiǎn)的,例如一個.jpg的圖片文件被惡意嵌入了可執(zhí)行的js代碼,在開啟資源類型猜測的情況下,瀏覽器將執(zhí)行嵌入的js代碼,可能會有意想不到的后果。
add_header X-Frame-Options "SAMEORIGIN"; add_header X-XSS-Protection "1; mode=block"; add_header X-Content-Type-Options "nosniff"; * X-Frame-Options: 響應(yīng)頭表示是否允許瀏覽器加載frame等屬性,有三個配置 DENY:禁止任何網(wǎng)頁被嵌入; SAMEORIGIN: 只允許本網(wǎng)站的嵌套; ALLOW-FROM: 允許指定地址的嵌套; * X-XSS-Protection: 表示啟用XSS過濾(禁用過濾為X-XSS-Protection: 0),mode=block表示若檢查到XSS攻擊則停止渲染頁面 * X-Content-Type-Options: 響應(yīng)頭用來指定瀏覽器對未指定或錯誤指定Content-Type資源真正類型的猜測行為,nosniff 表示不允許任何猜測;
其他請求頭的安全配置:server
定義頁面可以加載哪些資源,上邊的配置會限制所有的外部資源,都只能從當(dāng)前域名加載,其中default-src定義針對所有類型資源的默認(rèn)加載策略,self允許來自相同來源的內(nèi)容
add_header Content-Security-Policy "default-src 'self'";
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";
會告訴瀏覽器用HTTPS協(xié)議代替HTTP來訪問目標(biāo)站點(diǎn),上邊的配置表示當(dāng)用戶第一次訪問后,會返回一個包含了Strict-Transport-Security響應(yīng)頭的字段,這個字段會告訴瀏覽器,在接下來的31536000秒內(nèi),當(dāng)前網(wǎng)站的所有請求都使用https協(xié)議訪問,參數(shù)includeSubDomains是可選的,表示所有子域名也將采用同樣的規(guī)則
緩沖區(qū)溢出攻擊
通過將數(shù)據(jù)寫入緩沖區(qū)(http、server、location)并超出緩沖區(qū)邊界和重寫內(nèi)存片段來實(shí)現(xiàn)的,限制緩沖區(qū)大小可有效防止
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: 默認(rèn)8k或16k,表示客戶端請求body占用緩沖區(qū)大小。如果連接請求超過緩存區(qū)指定的值,那么這些請求實(shí)體的整體或部分將嘗試寫入一個臨時(shí)文件。 * client_header_buffer_size: 表示客戶端請求頭部的緩沖區(qū)大小。絕大多數(shù)情況下一個請求頭不會大于1k,不過如果有來自于wap客戶端的較大的cookie它可能會大于 1k,Nginx將分配給它一個更大的緩沖區(qū),這個值可以在large_client_header_buffers里面設(shè)置 * client_max_body_size: 表示客戶端請求的最大可接受body大小,它出現(xiàn)在請求頭部的Content-Length字段, 如果請求大于指定的值,客戶端將收到一個"Request Entity Too Large" (413)錯誤,通常在上傳文件到服務(wù)器時(shí)會受到限制 * large_client_header_buffers 表示一些比較大的請求頭使用的緩沖區(qū)數(shù)量和大小,默認(rèn)一個緩沖區(qū)大小為操作系統(tǒng)中分頁文件大小,通常是4k或8k,請求字段不能大于一個緩沖區(qū)大小,如果客戶端發(fā)送一個比較大的頭,nginx將返回"Request URI too large" (414),請求的頭部最長字段不能大于一個緩沖區(qū),否則服務(wù)器將返回"Bad request" (400)
同時(shí)需要修改幾個超時(shí)時(shí)間的配置: client_body_timeout 10; client_header_timeout 10; keepalive_timeout 5 5; send_timeout 10; * client_body_timeout: 表示讀取請求body的超時(shí)時(shí)間,如果連接超過這個時(shí)間而客戶端沒有任何響應(yīng),Nginx將返回"Request time out" (408)錯誤 * client_header_timeout: 表示讀取客戶端請求頭的超時(shí)時(shí)間,如果連接超過這個時(shí)間而客戶端沒有任何響應(yīng),Nginx將返回"Request time out" (408)錯誤 * keepalive_timeout: 參數(shù)的第一個值表示客戶端與服務(wù)器長連接的超時(shí)時(shí)間,超過這個時(shí)間,服務(wù)器將關(guān)閉連接,可選的第二個參數(shù)參數(shù)表示Response頭中Keep-Alive: timeout=time的time值,這個值可以使一些瀏覽器知道什么時(shí)候關(guān)閉連接,以便服務(wù)器不用重復(fù)關(guān)閉,如果不指定這個參數(shù),nginx不會在應(yīng)Response頭中發(fā)送Keep-Alive信息 * send_timeout: 表示發(fā)送給客戶端應(yīng)答后的超時(shí)時(shí)間,Timeout是指沒有進(jìn)入完整established狀態(tài),只完成了兩次握手,如果超過這個時(shí)間客戶端沒有任何響應(yīng),nginx將關(guān)閉連接
防盜鏈:server、location
location /images/ { valid_referers none blocked www.ops-coffee.cn ops-coffee.cn; if ($invalid_referer) { return 403; } } valid_referers: 驗(yàn)證referer, none:允許referer為空 blocked:允許不帶協(xié)議的請求
除了以上兩類外僅允許referer為www.ops-coffee.cn或ops-coffee.cn時(shí)訪問images下的圖片資源,否則返回403
給不符合referer規(guī)則的請求重定向到一個默認(rèn)的圖片
location /images/ { valid_referers blocked www.ops-coffee.cn ops-coffee.cn if ($invalid_referer) { rewrite ^/images/.*.(gif|jpg|jpeg|png)$ /static/qrcode.jpg last; } }
一、限制訪問方法
禁止不安全的HTTP方法
默認(rèn)情況下,Nginx支持多種HTTP方法,包括GET、POST、OPTIONS等。然而,某些HTTP方法可能存在安全風(fēng)險(xiǎn),例如TRACE方法可以被用于跨站腳本(XSS)攻擊。我們可以使用Nginx的"limit_except"指令來限制某些HTTP方法的訪問。
示例代碼:
location / { limit_except GET POST { deny all; } }
關(guān)閉不必要的目錄列表
如果Nginx的目錄沒有默認(rèn)的index文件,會自動展示目錄下的文件列表,這可能會暴露敏感信息。我們可以通過禁止自動目錄列表的方式來阻止此行為。
示例代碼:
location / {
autoindex off; }
添加賬號認(rèn)證:http、server、location
server { location / { auth_basic "please input user&passwd"; auth_basic_user_file key/auth.key; } } 二、防止惡意請求和攻擊
防止惡意請求
惡意請求包括大量的請求、大文件上傳、惡意腳本等等,這會導(dǎo)致服務(wù)器負(fù)載過高。我們可以通過設(shè)置請求限制,來防止這種情況發(fā)生。
示例代碼:
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"指令來定義請求限制區(qū)域,設(shè)置限制的大小和速率(每秒最多允許1個請求)。然后,在相應(yīng)的"server"配置中使用"limit_req"指令來應(yīng)用該限制區(qū)域。
限制請求方法:server、location
if ($request_method !~ ^(GET|POST)$ ) { return 405; } $request_method能夠獲取到請求nginx的method 配置只允許GETPOST方法訪問,其他的method返回405
拒絕User-Agent:server、location
if ($http_user_agent ~* LWP::Simple|BBBike|wget|curl) {
return 444; } 可能有一些不法者會利用wget/curl等工具掃描我們的網(wǎng)站,我們可以通過禁止相應(yīng)的user-agent來簡單的防范 Nginx的444狀態(tài)比較特殊,如果返回444那么客戶端將不會收到服務(wù)端返回的信息,就像是網(wǎng)站無法連接一樣
防止常見攻擊
Nginx默認(rèn)提供了一些防止常見攻擊的配置選項(xiàng),例如:
防止緩沖區(qū)溢出攻擊:proxy_buffer_size和proxy_buffers配置選項(xiàng)
防止HTTP請求頭過大攻擊:large_client_header_buffers配置選項(xiàng)
防止URI長度過大攻擊:large_client_header_buffers配置選項(xiàng)
防止惡意請求:client_max_body_size配置選項(xiàng)
防止DDoS攻擊:limit_conn和limit_req配置選項(xiàng)
三、使用HTTPS保證數(shù)據(jù)傳輸安全
HTTPS協(xié)議可以保證數(shù)據(jù)傳輸?shù)臋C(jī)密性和完整性,防止數(shù)據(jù)被竊取或篡改。使用HTTPS可以防止中間人攻擊、數(shù)據(jù)劫持等安全問題。我們可以使用Nginx提供的SSL模塊來配置HTTPS。
示例代碼:
server { listen 443 ssl; server_name example.com; ssl_certificate /path/to/certificate.crt; ssl_certificate_key /path/to/private.key; location / { # 其他配置 } }上述代碼中,我們使用listen 443 ssl指令來監(jiān)聽443端口,并使用ssl_certificate和ssl_certificate_key配置選項(xiàng)指定SSL證書路徑。
審核編輯:黃飛
-
服務(wù)器
+關(guān)注
關(guān)注
12文章
9304瀏覽量
86066 -
虛擬主機(jī)
+關(guān)注
關(guān)注
0文章
69瀏覽量
11471 -
安全配置
+關(guān)注
關(guān)注
0文章
7瀏覽量
6673 -
nginx
+關(guān)注
關(guān)注
0文章
154瀏覽量
12235
原文標(biāo)題:Nginx 生產(chǎn)環(huán)境下的安全配置
文章出處:【微信號:magedu-Linux,微信公眾號:馬哥Linux運(yùn)維】歡迎添加關(guān)注!文章轉(zhuǎn)載請注明出處。
發(fā)布評論請先 登錄
相關(guān)推薦
評論