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