Nginx的deny和allow指令是由ngx_http_access_module模塊提供,Nginx安裝默認內置了該模塊。 除非在安裝時有指定 --without-http_access_module。
語法php
語法:allow/deny address | CIDR | unix: | all 它表示,容許/拒絕某個ip或者一個ip段訪問.若是指定unix:,那將容許socket的訪問。 注意:unix在1.5.1中新加入的功能。 在nginx中,allow和deny的規則是按順序執行的。
示例html
示例1:node
location / { allow 192.168.0.0/24; allow 127.0.0.1; deny all; } 說明:這段配置只容許192.168.0.0/24網段和127.0.0.1的請求,其餘來源IP所有拒絕。
示例2:linux
location ~ "admin" { allow 110.21.33.121; deny all } 說明:訪問的uri中包含admin的請求,只容許110.21.33.121這個IP的請求。
在生產環境中,咱們會對某些特殊的請求進行限制,好比對網站的後臺進行限制訪問。 這就用到了location配置。
示例1nginx
location /aming/ { deny all; } 說明:針對/aming/目錄,所有禁止訪問,這裏的deny all能夠改成return 403.
示例2正則表達式
location ~ ".bak|\.ht" { return 403; } 說明:訪問的uri中包含.bak字樣的或者包含.ht的直接返回403狀態碼。 測試連接舉例: 1. www.aminglinux.com/123.bak 2. www.aminglinux.com/aming/123/.htalskdjf
示例3瀏覽器
location ~ (data|cache|tmp|image|attachment).*\.php$ { deny all; } 說明:請求的uri中包含data、cache、tmp、image、attachment而且以.php結尾的,所有禁止訪問。 測試連接舉例: 1. www.aminglinux.com/aming/cache/1.php 2. www.aminglinux.com/image/123.phps 3. www.aminglinux.com/aming/datas/1.php
這就用到了變量$document_uri,根據前面所學內容,該變量等價於$uri,其實也等價於location匹配。
示例1服務器
if ($document_uri ~ "/admin/") { return 403; } 說明:當請求的uri中包含/admin/時,直接返回403. if結構中不支持使用allow和deny。 測試連接: 1. www.aminglinux.com/123/admin/1.html 匹配 2. www.aminglinux.com/admin123/1.html 不匹配 3. www.aminglinux.com/admin.php 不匹配
示例2併發
if ($document_uri = /admin.php) { return 403; } 說明:請求的uri爲/admin.php時返回403狀態碼。 測試連接: 1. www.aminglinux.com/admin.php 匹配 2. www.aminglinux.com/123/admin.php 不匹配
示例3curl
if ($document_uri ~ '/data/|/cache/.*\.php$') { return 403; } 說明:請求的uri包含data或者cache目錄,而且是php時,返回403狀態碼。 測試連接: 1. www.aminglinux.com/data/123.php 匹配 2. www.aminglinux.com/cache1/123.php 不匹配
$request_uri比$docuemnt_uri多了請求的參數。 主要是針對請求的uri中的參數進行控制。
示例
if ($request_uri ~ "gid=\d{9,12}") { return 403; } 說明:\d{9,12}是正則表達式,表示9到12個數字,例如gid=1234567890就符號要求。 測試連接: 1. www.aminglinux.com/index.php?gid=1234567890&pid=111 匹配 2. www.aminglinux.com/gid=123 不匹配 背景知識: 曾經有一個客戶的網站cc攻擊,對方發起太多相似這樣的請求:/read-123405150-1-1.html 實際上,這樣的請求並非正常的請求,網站會拋出一個頁面,提示帖子不存在。 因此,能夠直接針對這樣的請求,return 403狀態碼。
user_agent你們並不陌生,能夠簡單理解成瀏覽器標識,包括一些蜘蛛爬蟲均可以經過user_agent來辨識。 經過觀察訪問日誌,能夠發現一些搜索引擎的蜘蛛對網站訪問特別頻繁,它們並不友好。 爲了減小服務器的壓力,其實能夠把除主流搜索引擎蜘蛛外的其餘蜘蛛爬蟲所有封掉。 另外,一些cc攻擊,咱們也能夠經過觀察它們的user_agent找到規律。
示例
if ($user_agent ~ 'YisouSpider|MJ12bot/v1.4.2|YoudaoBot|Tomato') { return 403; } 說明:user_agent包含以上關鍵詞的請求,所有返回403狀態碼。 測試: 1. curl -A "123YisouSpider1.0" 2. curl -A "MJ12bot/v1.4.1"
在前面講解rewrite時,曾經用過該變量,當時實現了防盜鏈功能。 其實基於該變量,咱們也能夠作一些特殊的需求。
示例
背景:網站被黑掛馬,搜索引擎收錄的網頁是有問題的,當經過搜索引擎點擊到網站時,卻顯示一個博彩網站。 因爲查找木馬須要時間,不能立刻解決,爲了避免影響用戶體驗,能夠針對此類請求作一個特殊操做。 好比,能夠把從百度訪問的連接直接返回404狀態碼,或者返回一段html代碼。 if ($http_referer ~ 'baidu.com') { return 404; } 或者 if ($http_referer ~ 'baidu.com') { return 200 "<html><script>window.location.href='//$host$request_uri';</script></html> }
能夠經過ngx_http_limit_conn_module和ngx_http_limit_req_module模塊來實現限速的功能。
ngx_http_limit_conn_module
該模塊主要限制下載速度。
1. 併發限制
nginx.conf配置示例
http { ... limit_conn_zone $binary_remote_addr zone=aming:10m; ... } 虛擬主機: server { ... limit_conn aming 10; 放到location外面也能夠 ... } 說明:首先用limit_conn_zone定義了一個內存區塊索引aming,大小爲10m,它以$binary_remote_addr做爲key。 該配置只能在http裏面配置,不支持在server裏配置。 limit_conn 定義針對aming這個zone,併發鏈接爲10個。在這須要注意一下,這個10指的是單個IP的併發最多爲10個。
使用httpd的工具進行測試,能夠經過日誌看結果
ab -n 5 -c 5 http://www.tobeblog.com/nginx-1.14.2.tar.gz -n 訪問幾回 -c 併發幾回
2. 速度限制
nginx.conf配置:
http { ... limit_conn_zone $binary_remote_addr zone=aming:10m; ... }
虛擬主機:
location ~ /download/ { ... limit_rate_after 512k; limit_rate 150k; ... } 說明:limit_rate_after定義當一個文件下載到指定大小(本例中爲512k)以後開始限速; limit_rate 定義下載速度爲150k/s。 注意:這兩個參數針對每一個請求限速。
ngx_http_limit_req_module
該模塊主要用來限制請求數。
1. limit_req_zone
語法: limit_req_zone $variable zone=name:size rate=rate; 默認值: none 配置段: http 設置一塊共享內存限制域用來保存鍵值的狀態參數。 特別是保存了當前超出請求的數量。 鍵的值就是指定的變量(空值不會被計算)。 如limit_req_zone $binary_remote_addr zone=one:10m rate=1r/s; 說明:區域名稱爲one,大小爲10m,平均處理的請求頻率不能超過每秒一次,鍵值是客戶端IP。 使用$binary_remote_addr變量, 能夠將每條狀態記錄的大小減小到64個字節,這樣1M的內存能夠保存大約1萬6千個64字節的記錄。 若是限制域的存儲空間耗盡了,對於後續全部請求,服務器都會返回 503 (Service Temporarily Unavailable)錯誤。 速度能夠設置爲每秒處理請求數和每分鐘處理請求數,其值必須是整數, 因此若是你須要指定每秒處理少於1個的請求,2秒處理一個請求,可使用 「30r/m」(一秒鐘30次)。 r -> request
2. limit_req
語法: limit_req zone=name [burst=number] [nodelay]; 默認值: — 配置段: http, server, location 設置對應的共享內存限制域和容許被處理的最大請求數閾值。 若是請求的頻率超過了限制域配置的值,請求處理會被延遲,因此全部的請求都是以定義的頻率被處理的。 超過頻率限制的請求會被延遲,直到被延遲的請求數超過了定義的閾值, 這時,這個請求會被終止,並返回503 (Service Temporarily Unavailable) 錯誤。 這個閾值的默認值爲0。如: limit_req_zone $binary_remote_addr zone=aming:10m rate=1r/s; server { location /upload/ { limit_req zone=aming burst=5; burst能夠理解爲銀行辦理業務的窗口有幾個 } } 限制平均每秒不超過一個請求,同時容許超過頻率限制的請求數很少於5個。 若是不但願超過的請求被延遲,能夠用nodelay參數,如: limit_req zone=aming burst=5 nodelay;
示例
nginx.conf:
注意zone的名稱不能同樣
http { limit_req_zone $binary_remote_addr zone=aming1:10m rate=1r/s; } 虛擬主機: server { location ^~ /download/ { limit_req zone=aming1 burst=5; } }
測試:
ab -n 5 -c 5 http://www.tobeblog.com/nginx-1.14.2.tar.gz
設定白名單IP
若是是針對公司內部IP或者lo(127.0.0.1)不進行限速,如何作呢?這就要用到geo模塊了。 假如,預把127.0.0.1和192.168.100.0/24網段設置爲白名單,須要這樣作。 在http { }裏面增長: geo $limited { default 1; 127.0.0.1/32 0; 192.168.100.0/24 0; } map $limited $limit { 1 $binary_remote_addr; 0 ""; } 原來的 「limit_req_zone $binary_remote_addr 」 改成「limit_req_zone $limit」 完整示例: http { geo $limited { default 1; 127.0.0.1/32 0; 192.168.100.0/24 0; } map $limited $limit { 1 $binary_remote_addr; 0 ""; } limit_req_zone $limit zone=aming:10m rate=1r/s; server { location ^~ /download/ { limit_req zone=aming burst=5; } } }