插件窝 干货文章 Nginx反向代理中基于用户IP的访问控制配置

Nginx反向代理中基于用户IP的访问控制配置

Nginx location http 代理 37    来源:    2025-04-20

Nginx反向代理中基于用户IP的访问控制配置

在Nginx反向代理环境中,基于用户IP进行访问控制是常见的安全需求。以下是几种实现方式:

1. 基本IP访问控制

允许/拒绝特定IP

location / {
    allow 192.168.1.100;
    allow 192.168.1.0/24;
    deny all;
}

基于反向代理的特殊配置

当Nginx作为反向代理时,客户端真实IP通常保存在X-Forwarded-ForX-Real-IP头中:

location / {
    set $real_ip $remote_addr;
    if ($http_x_forwarded_for) {
        set $real_ip $http_x_forwarded_for;
    }
    if ($real_ip !~* "^(192\.168\.1\.100|10\.0\.0\.1)$") {
        return 403;
    }

    proxy_pass http://backend;
}

2. 使用geo模块

geo $client_ip {
    default         0;
    192.168.1.0/24  1;
    10.0.0.1        1;
}

server {
    location / {
        if ($client_ip = 0) {
            return 403;
        }
        proxy_pass http://backend;
    }
}

3. 使用map模块

map $remote_addr $is_allowed {
    default         0;
    192.168.1.100   1;
    10.0.0.1        1;
}

server {
    location / {
        if ($is_allowed = 0) {
            return 403;
        }
        proxy_pass http://backend;
    }
}

4. 结合真实IP获取

对于多层代理环境,确保获取真实客户端IP:

real_ip_header X-Forwarded-For;
set_real_ip_from 10.0.0.0/8;  # 信任的代理IP范围
real_ip_recursive on;

location / {
    allow 192.168.1.0/24;
    deny all;

    proxy_pass http://backend;
}

5. 动态IP黑名单

使用Nginx+Lua实现动态黑名单:

lua_shared_dict ip_blacklist 10m;

server {
    location / {
        access_by_lua_block {
            local blacklist = ngx.shared.ip_blacklist
            local client_ip = ngx.var.remote_addr
            if blacklist:get(client_ip) then
                ngx.exit(ngx.HTTP_FORBIDDEN)
            end
        }

        proxy_pass http://backend;
    }

    location /admin/blacklist {
        content_by_lua_block {
            -- 此处添加管理黑名单的Lua代码
        }
    }
}

最佳实践建议

  1. 多层代理环境:确保正确配置real_ip_header获取真实客户端IP
  2. IP范围:尽量使用CIDR表示法指定IP范围而非单个IP
  3. 性能考虑:大量IP规则时,geo模块比多个allow/deny指令更高效
  4. 动态更新:对于频繁变化的IP列表,考虑使用Lua或外部数据库
  5. 日志记录:记录被拒绝的访问以便审计
log_format blocked '$time_local|$remote_addr|$http_x_forwarded_for|$status|blocked';

server {
    location / {
        error_page 403 /403.html;
        allow 192.168.1.0/24;
        deny all;

        access_log /var/log/nginx/blocked.log blocked;

        proxy_pass http://backend;
    }
}

以上配置可根据实际环境需求组合使用,实现灵活高效的IP访问控制。