限制主要有兩種類型:php
HTTP協議的鏈接與請求html
HTTP協議是基於TCP的,若是要完成一次HTTP請求的時候,首先進行TCP的三次握手。當創建鏈接的時候就能夠進行請求和響應。node
能夠獲得結論:
HTTP請求創建在一次TCP鏈接基礎上,一次TCP請求至少產生一次HTTP請求(能夠有多個)nginx
對於 limit_conn_module模塊ruby
該ngix_http_limit_conn_module模塊用於限制每一個定義的密鑰的鏈接數量,特別是來自單個IP地址的鏈接數量。服務器
並不是全部鏈接都被計算在內 只有在服務器處理請求而且已經讀取了整個請求頭時才計算鏈接。併發
對於鏈接限制的配置:app
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的訪問控制主要分爲兩類:
對於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模塊