nginx 請求限制和訪問控制


請求限制

限制主要有兩種類型:

  • 連接頻率限制: limit_conn_module
  • 請求頻率限制: limit_req_module

HTTP協議的連接與請求

 

HTTP協議是基於TCP的,如果要完成一次HTTP請求的時候,首先進行TCP的三次握手。當建立連接的時候就可以進行請求和響應。

可以得到結論:
HTTP請求建立在一次TCP連接基礎上,一次TCP請求至少產生一次HTTP請求(可以有多個)

對於 limit_conn_module模塊

該ngix_http_limit_conn_module模塊用於限制每個定義的密鑰的連接數量,特別是來自單個IP地址的連接數量。

並非所有連接都被計算在內 只有在服務器處理請求並且已經讀取了整個請求頭時才計算連接。

對於連接限制的配置:

  • Syntax: limit_conn_zone key zone=name:size;
  • Default: —
  • Context: http
  • Syntax: limit_conn zone number;
  • Default: — Context: http, server, location

 

對於第一部分可以理解在內存中開辟一個區域對於指定的nginx變量(key,例如:binary_remote_addr)進行限制。name表示申請的空間的名字,size表示申請空間的大小。

對於第二部分zone就是第一部分設置的名字name,number表示進行並發的限制。例如設置為1,表示一個時間段只能有一個。

對於ngx_http_limit_req_module模塊:

用於限制每一個定義的密鑰的請求的處理速率,特別是從一個單一的IP地址的請求的處理速率。限制是使用“泄漏桶”方法完成的

對於請求限制的配置:

  • Syntax: limit_req_zone key zone=name:size rate=rate;
  • Default: —
  • Context: http
  • Syntax: limit_req zone=name [burst=number] [nodelay];
  • Default: —
  • Context: http, server, location

對於第一部分配置和連接配置相似,rate表示速率,以秒s為單位(rate=1r/s)
對於第二部分zone就是第一部分設置的名字name,[]內為可配置選項。

實例:
首先編寫配置文件 default.conf

    limit_conn_zone $binary_remote_addr zone=conn_zone:1m;
    limit_req_zone $binary_remote_addr zone=req_zone:1m rate=1r/s;
server {
    listen       80;
    server_name  localhost;

    #charset koi8-r;
    #access_log  /var/log/nginx/log/host.access.log  main;


    location / {
        root /opt/app/code;
        #limit_conn conn_zone 1;
        #limit_req zone=req_zone burst=3 nodelay;
        #limit_req zone=req_zone burst=3;
        #limit_req zone=req_zone;
        index  index.html index.htm;
    }

  

 

 

我們看到上面為定義zone,第二行是請求定義,表示對遠程請求進行每秒一次的請求限制。這里的binary_remote_addr和remote_addr代表的含義是一樣的(遠程主機的IP)只是使用binary_remote_addr存儲一個IP會比remote_addr省10個字節。burst 參數往后延遲3個請求 nodelay 立即返回

保存重新加載

使用 ab 進行壓力測試

ab -n 40 -c 20 http://192.168.1.112/

可以看到40 個都連接成功

 

請求限制打開,1s同一個客戶端只允許連接一次

 

再次進行測試

ab -n 40 -c 20 http://192.168.1.112/

可以發現只成功了一次

 

訪問控制

nginx的訪問控制主要分為兩類:

  • 基於IP的訪問控制 http_access_module
  • 基於用戶的信任登錄 http_auth_basic_module

對於http_access_module模塊:

模塊允許限制訪問某些客戶端地址。訪問也可以通過密碼子請求結果或JWT來限制滿足控制地址和密碼的同時訪問限制。

配置語法:

  • Syntax: allow address | CIDR | unix: | all;
  • Default: —
  • Context: http, server, location, limit_except
  • Syntax: deny address | CIDR | unix: | all;
  • Default: —
  • Context: http, server, location, limit_except

語法中address表示地址,CIDR表示網段。unix:指定了特殊值,則允許訪問所有UNIX域套接字。all表示所有的。

實例:配置訪問控制
首先我們查看沒有限制的時候進行的輸出

 

編輯配置文件

location ~ ^/admin.html {
        root   /opt/app/code;
        deny 192.168.1.6;
        allow all;
        index  index.html index.htm;
    }

 

其中 ~ 表示對請求路徑URL模式匹配,表示跟目下以1.html開頭的家目錄設置在/opt/app/code。

然后檢查配置重啟

nginx -tc /etc/nginx/nginx.conf 
systemctl reload nginx

重新訪問我們的頁面  

 

 

 

現在配置只有本機可以訪問

    location ~ ^/admin.html {
        root   /opt/app/code;
        allow 192.168.1.0/24;
        deny all;
        index  index.html index.htm;
    }

然后檢查配置重啟 

nginx -tc /etc/nginx/nginx.conf 
systemctl reload nginx

  

重新訪問我們的頁面 

 

 

http_access_module模塊的局限性:

nginx的訪問控制限制是針對客戶端的IP來進行限制的,但是nginx並不確定真正的客戶端是哪個,凡是和nginx進行交互的都被當做是客戶端。(remote_addr是直接和nginx通信的IP)如果我們訪問不是直接訪問到服務端而是由中間代理進行(如上圖),訪問控制這時就會失效。

局限性解決方法總結:

方法一: 采用http頭信息控制訪問,如HTTP_X_FORWARD_FOR
方法二: 結合geo模塊
方法三: 通過HTTP自定義變量傳遞

http_x_forwarded_for頭信息控制訪問 會更好的解決該問題,它要求訪問時必須帶上所有用到的ip的地址信息
我們看一下http_x_forwarded_for記錄過程:

http_x_forwarded_for = Client IP, Proxy(1)IP, Proxy(2)IP,...

http_auth_basic_module模塊

配置語法

  • Syntax: auth_basic string | off;
  • Default: auth_basic off;
  • Context: http, server, location, limit_except
  • Syntax: auth_basic_user_file file;
  • Default: —
  • Context: http, server, location, limit_except

語法講解:
auth_basic 默認關閉,開啟的話輸入一段字符串即可。
auth_basic_user_file 該文件存儲用戶賬號密碼。

我們看一下官網的文件格式

# comment
name1:password1
name2:password2:comment
name3:password3

詳細官方鏈接

 

密碼加密方式有多中這里我們使用htpasswd  

can be generated using the “htpasswd” utility from the Apache HTTP Server distribution or the “openssl passwd” command

想要使用該方式,首先要裝對應的包 

yum -y install httpd-tools

接下來創建對應的use_file文件  

htpasswd -c ./auth_conf zhangbiao

編輯配置文件
    location ~ ^/admin.html {
        root   /opt/app/code;
    auth_basic "Auth access test! input your password!";
    auth_basic_user_file /etc/nginx/auth_conf;
        index  index.html index.htm;
    }

  

進行語法檢查

nginx -tc /etc/nginx/nginx.conf
systemctl reload nginx

現在我們再次訪問頁面的時候就需要輸入用戶名密碼  

輸入剛才的賬號密碼就可以正常訪問了。

 

局限性:

一: 用戶信息依賴文件
二: 操作管理機械,效率低

解決方式:

一: nginx結合LUA實現高效驗證
二: nginx配合LDAP打通,利用nginx-auth-ldap模塊

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM