一、模塊概述
ngx_http_access_module
是 NGINX 核心模塊之一,用于基于客戶端 IP 地址或 UNIX 域套接字限制訪問。它通過簡單的 allow
/deny
規則,對請求進行最先匹配原則的過濾。與基于密碼(auth_basic
)、子請求(auth_request
)或 JWT(ngx_http_auth_jwt_module
)相結合時,可通過 satisfy
指令靈活配置“與/或”關系。
二、指令語法
allow address | CIDR | unix: | all;
deny address | CIDR | unix: | all;
- address:單個 IPv4 地址,如
192.168.1.10
。 - CIDR:IPv4/IPv6 網段,如
10.1.0.0/16
、2001:db8::/32
。 - unix::匹配 UNIX 域套接字(1.5.1+)。
- all:匹配所有客戶端。
上下文:http
, server
, location
, limit_except
。
規則按出現順序依次檢查,直到命中為止;若無規則,則默認放行。
三、基礎配置示例
location /admin/ {# 拒絕單個 IPdeny 192.168.1.1;# 允許同網段訪問allow 192.168.1.0/24;allow 10.1.1.0/16;# 允許 IPv6 網段allow 2001:0db8::/32;# 默認拒絕所有其它deny all;
}
上述配置效果:
- 192.168.1.1 被拒絕(優先于 192.168.1.0/24);
- 192.168.1.2–192.168.1.254 及 10.1.x.x、指定 IPv6 網段被允許;
- 其余地址返回 403 Forbidden。
四、與 satisfy
結合
當既要基于 IP,又要基于認證時,可使用:
location /secure/ {satisfy any;allow 192.168.0.0/24;deny all;auth_basic "Restricted";auth_basic_user_file /etc/nginx/htpasswd;
}
satisfy any
:IP 白名單 或 HTTP 基本認證 任一通過即可;- 使用
satisfy all
(默認)則需同時滿足兩者。
五、進階用法
1. 全局與局部規則
- 在
http
或server
塊定義默認規則,location
內可覆蓋或補充。 limit_except
中可只對非 GET/HEAD 等方法應用 IP 控制。
limit_except GET HEAD {allow 10.0.0.0/8;deny all;
}
2. 與 ngx_stream_geo_module
結合
當有大量網段或需動態更新時,推薦用 geo
模塊預先匹配變量,再在 access 中引用:
geo $allowed {default 0;192.168.0.0/24 1;include conf/allowed_geo.conf;
}server {location / {if ($allowed = 0) {return 403;}# 其它配置…}
}
六、性能與維護
- 順序匹配:將最常命中的規則放前,減少平均匹配次數。
- 規則規模:少量時用
allow
/deny
足矣;大量網段建議配合geo
或外部文件include
。 - 字符處理:CIDR 與單 IP 都會被轉換為無符號整數,匹配效率高;
- 日志監控:可配合
error_log
監控 403 訪問,及時調整規則。
七、安全與審計
- 拒絕
all
:應始終在最后一行寫deny all
,防止開放未覆蓋的 IP。 - 正則與變量:
allow
/deny
不支持正則,僅支持 CIDR;靈活場景下可配合$remote_addr
在if
中使用正則或自定義變量。 - 域內安全:使用
unix:
僅允許運行于本機的服務調用,提升安全性。
八、常見陷阱
- 位置錯誤:
allow
/deny
必須在可見的上下文(server
、location
),否則無效。 - 未寫
deny all
:若只有allow
,但無默認deny all
,其他客戶端仍然可訪問。 - 與
auth_basic
沖突:若既有密碼又有 IP 控制,未設置satisfy
時默認“與”關系,可能導致意外拒絕。
九、總結
ngx_http_access_module
提供了簡單高效的基于地址訪問控制,配合 satisfy
、geo
、auth_basic
等模塊,可實現精細化安全策略。制作規則時要注意順序與默認策略,針對不同場景合理拆分到全局 vs 局部,既能保障性能,也能提升可維護性。