Nginx访问控制 #
一、访问控制概述 #
Nginx提供了多种访问控制机制:
- IP地址限制
- HTTP Basic认证
- 请求方法限制
- 请求频率限制
- 基于变量的条件控制
二、IP访问控制 #
2.1 基本语法 #
nginx
location /admin/ {
allow 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
}
2.2 allow和deny指令 #
nginx
allow address;
allow CIDR;
allow all;
deny address;
deny CIDR;
deny all;
2.3 规则匹配顺序 #
规则按配置顺序匹配,匹配成功即停止:
nginx
location / {
allow 192.168.1.100;
deny 192.168.1.0/24;
allow 10.0.0.0/8;
deny all;
}
上述配置中,192.168.1.100被允许,其他192.168.1.x被拒绝。
2.4 全局IP限制 #
nginx
server {
listen 80;
server_name example.com;
allow 192.168.0.0/16;
allow 10.0.0.0/8;
deny all;
location / {
root /var/www/html;
}
}
2.5 特定路径限制 #
nginx
server {
listen 80;
server_name example.com;
location / {
root /var/www/html;
}
location /admin/ {
allow 192.168.1.0/24;
deny all;
root /var/www/html;
}
location /api/internal/ {
allow 127.0.0.1;
deny all;
proxy_pass http://backend;
}
}
2.6 基于地理位置限制 #
使用GeoIP模块:
nginx
http {
geoip_country /usr/share/GeoIP/GeoIP.dat;
map $geoip_country_code $allowed_country {
default no;
CN yes;
US yes;
JP yes;
}
}
server {
location / {
if ($allowed_country = no) {
return 403;
}
root /var/www/html;
}
}
2.7 使用geo模块 #
nginx
http {
geo $allowed_ip {
default 0;
192.168.1.0/24 1;
10.0.0.0/8 1;
172.16.0.0/12 1;
}
}
server {
location /admin/ {
if ($allowed_ip = 0) {
return 403;
}
root /var/www/html;
}
}
三、HTTP Basic认证 #
3.1 创建密码文件 #
使用htpasswd工具:
bash
sudo apt install apache2-utils
sudo htpasswd -c /etc/nginx/.htpasswd admin
sudo htpasswd /etc/nginx/.htpasswd user2
3.2 基本配置 #
nginx
location /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/html;
}
3.3 组合IP和密码认证 #
nginx
location /admin/ {
satisfy any;
allow 192.168.1.0/24;
deny all;
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/html;
}
3.4 satisfy指令 #
| 值 | 说明 |
|---|---|
| all | 必须满足所有条件 |
| any | 满足任一条件即可 |
3.5 密码文件格式 #
text
username:encrypted_password
user2:$apr1$xxx$yyy
3.6 多用户管理 #
nginx
location /admin/ {
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd.admin;
}
location /staff/ {
auth_basic "Staff Area";
auth_basic_user_file /etc/nginx/.htpasswd.staff;
}
四、请求方法限制 #
4.1 限制特定方法 #
nginx
location /api/ {
limit_except GET HEAD POST {
deny all;
}
proxy_pass http://backend;
}
4.2 只读API #
nginx
location /api/read/ {
limit_except GET HEAD {
deny all;
}
proxy_pass http://backend;
}
4.3 使用if判断 #
nginx
location /api/ {
if ($request_method !~ ^(GET|POST|HEAD)$) {
return 405;
}
proxy_pass http://backend;
}
五、请求频率限制 #
5.1 定义限制区域 #
nginx
http {
limit_req_zone $binary_remote_addr zone=req_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
}
5.2 应用限制 #
nginx
server {
location /api/ {
limit_req zone=req_limit burst=20 nodelay;
limit_conn conn_limit 10;
proxy_pass http://backend;
}
}
5.3 参数说明 #
| 参数 | 说明 |
|---|---|
| zone | 限制区域名称 |
| rate | 请求速率 |
| burst | 突发请求数 |
| nodelay | 不延迟处理突发请求 |
5.4 返回自定义状态码 #
nginx
limit_req_status 429;
limit_conn_status 429;
5.5 白名单配置 #
nginx
http {
geo $limit_key {
default $binary_remote_addr;
127.0.0.1 "";
192.168.1.0/24 "";
}
limit_req_zone $limit_key zone=req_limit:10m rate=10r/s;
}
server {
location /api/ {
limit_req zone=req_limit burst=20;
proxy_pass http://backend;
}
}
六、基于变量的访问控制 #
6.1 基于User-Agent #
nginx
location / {
if ($http_user_agent ~* (bot|spider|crawler)) {
return 403;
}
root /var/www/html;
}
6.2 基于Referer防盗链 #
nginx
location /images/ {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
root /var/www/images;
}
6.3 基于Cookie #
nginx
location /premium/ {
if ($cookie_premium_user = "") {
return 403;
}
root /var/www/premium;
}
6.4 基于请求头 #
nginx
location /api/ {
if ($http_x_api_key = "") {
return 401;
}
proxy_pass http://backend;
}
6.5 基于时间 #
nginx
location /maintenance/ {
set $maintenance 0;
if ($time_iso8601 ~ "T(0[0-5]):") {
set $maintenance 1;
}
if ($maintenance = 1) {
return 503 "System under maintenance";
}
root /var/www/html;
}
七、JWT验证 #
7.1 使用auth_request模块 #
nginx
server {
location /api/ {
auth_request /auth;
auth_request_set $user $upstream_http_x_user;
proxy_set_header X-User $user;
proxy_pass http://backend;
}
location = /auth {
internal;
proxy_pass http://auth-service/validate;
proxy_pass_request_body off;
proxy_set_header Content-Length "";
proxy_set_header X-Original-URI $request_uri;
}
}
7.2 使用Lua验证JWT #
nginx
location /api/ {
access_by_lua_block {
local jwt = require "resty.jwt"
local token = ngx.var.http_authorization
if not token then
ngx.exit(401)
end
local jwt_obj = jwt:verify("secret", token)
if not jwt_obj.verified then
ngx.exit(401)
end
ngx.req.set_header("X-User", jwt_obj.payload.sub)
}
proxy_pass http://backend;
}
八、OAuth2认证 #
8.1 使用oauth2-proxy #
nginx
server {
listen 80;
server_name app.example.com;
location /oauth2/ {
proxy_pass http://oauth2-proxy:4180;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
}
location / {
auth_request /oauth2/auth;
error_page 401 = /oauth2/sign_in;
proxy_pass http://backend;
}
}
九、访问日志记录 #
9.1 记录被拒绝的请求 #
nginx
location /admin/ {
allow 192.168.1.0/24;
deny all;
access_log /var/log/nginx/admin.access.log;
error_log /var/log/nginx/admin.error.log;
root /var/www/admin;
}
9.2 条件日志 #
nginx
map $status $loggable {
~^[23] 0;
default 1;
}
server {
access_log /var/log/nginx/access.log combined if=$loggable;
}
十、安全最佳实践 #
10.1 隐藏敏感信息 #
nginx
server_tokens off;
server_name_in_redirect off;
port_in_redirect off;
10.2 安全头配置 #
nginx
add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Content-Security-Policy "default-src 'self'" always;
10.3 限制请求体大小 #
nginx
client_max_body_size 10m;
client_body_buffer_size 128k;
10.4 超时设置 #
nginx
client_body_timeout 12;
client_header_timeout 12;
send_timeout 10;
10.5 禁止访问敏感文件 #
nginx
location ~* /\.(git|svn|htaccess|htpasswd|env) {
deny all;
return 404;
}
location ~* \.(log|bak|sql|conf|ini|swp)$ {
deny all;
return 404;
}
十一、完整配置示例 #
nginx
http {
limit_req_zone $binary_remote_addr zone=api_limit:10m rate=10r/s;
limit_conn_zone $binary_remote_addr zone=conn_limit:10m;
geo $allowed_ip {
default 0;
192.168.0.0/16 1;
10.0.0.0/8 1;
}
server {
listen 80;
server_name example.com;
server_tokens off;
location / {
root /var/www/html;
index index.html;
}
location /admin/ {
satisfy any;
allow 192.168.1.0/24;
deny all;
auth_basic "Admin Area";
auth_basic_user_file /etc/nginx/.htpasswd;
root /var/www/admin;
}
location /api/ {
limit_req zone=api_limit burst=20 nodelay;
limit_conn conn_limit 10;
limit_except GET HEAD POST {
deny all;
}
if ($http_user_agent ~* (bot|spider)) {
return 403;
}
proxy_pass http://backend;
}
location /internal/ {
if ($allowed_ip = 0) {
return 403;
}
proxy_pass http://backend;
}
location ~* /\.(git|svn|htaccess|htpasswd|env) {
deny all;
return 404;
}
location ~* \.(log|bak|sql|conf|ini)$ {
deny all;
return 404;
}
}
}
十二、总结 #
本章我们学习了:
- IP访问控制:allow/deny指令
- Basic认证:密码文件和配置
- 请求方法限制:limit_except指令
- 请求频率限制:limit_req和limit_conn
- 变量控制:基于User-Agent、Referer、Cookie等
- JWT验证:auth_request和Lua方式
- 安全最佳实践:隐藏信息、安全头、敏感文件保护
掌握访问控制后,让我们进入下一章,学习日志管理!
最后更新:2026-03-27