nginx---訪問控制

Nginx訪問控制 —— deny_allow

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的訪問控制

在生產環境中,咱們會對某些特殊的請求進行限制,好比對網站的後臺進行限制訪問。
這就用到了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

Nginx基於$document_uri的訪問控制

這就用到了變量$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 不匹配

nginx基於$request_uri訪問控制

$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狀態碼。

Nginx基於$user_agent的訪問控制

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"

Nginx基於$http_referer的訪問控制

在前面講解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>

}

Nginx的限速

能夠經過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;
        }
    }
}
相關文章
相關標籤/搜索