請求限制
限制主要有兩種類型:
- 連接頻率限制: 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: httpSyntax: 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: httpSyntax: 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_exceptSyntax: 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_exceptSyntax: 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模塊
