目录
在 Nginx 中实施白名单机制是生产环境中保障应用安全、进行精细流量控制的关键策略。根据不同的安全目标和网络层级,有多种成熟的实践方案。下面这个表格汇总了几种在生产环境中经过验证的核心方案。
1. 方案对比表
| 方案类别 | 工作层级 | 核心控制目标 | 关键配置方法 | 典型适用场景 |
|---|---|---|---|---|
| IP 访问控制 | 网络层 | 客户端 IP 地址 |
| 保护管理后台、内网服务、防御恶意扫描 |
| Token/Header 验证 | 应用层 | 请求头的合法性(如 Token) |
| API 接口授权、微服务间内部通信 |
| URI/路径白名单 | 应用层 | 可访问的 URL 路径 |
| 限制对外暴露的接口,减少攻击面 |
| 四层代理白名单 | 传输层 | TCP/UDP 连接 |
| 代理数据库、SSH、邮件等非 HTTP 服务 |
2. IP白名单配置实践
这是最基本也是最常用的一种方式,主要用于控制源IP地址的访问。
-
基础配置:使用
allow和deny你可以在
http、server或location块中定义规则。规则按配置的顺序匹配,一旦匹配则不再继续。一个常见的模式是“允许特定IP,拒绝所有”。# 在 server 或 location 块中 location /admin { allow 192.168.33.200; # 允许管理员IP allow 10.10.0.0/16; # 允许整个内网网段 deny all; # 拒绝所有其他IP # ... 其他代理配置 ... }将更具体的规则放在前面是良好的实践 。
-
高级管理:使用
geo模块当需要管理的IP地址较多或需要更灵活的匹配时,
geo模块非常有用。它允许你定义一个变量,并根据客户端IP为其赋值。# 在 http 块中定义 geo $whitelist { default 0; 192.168.33.0/24 1; 10.10.0.0/8 1; # 也可以从外部文件引入 include /etc/nginx/conf.d/ip_whitelist.conf; } server { location /secure { if ($whitelist = 0) { return 403; # 如果变量为0(不在白名单),返回403 } # ... 其他代理配置 ... } }这种方式更利于管理大量的IP列表 。
3. 基于 Token 的请求头验证
对于API接口,除了IP,通常还需要验证请求本身的合法性,例如检查HTTP请求头中的Token。
-
核心配置:使用
map指令通过在
http块中定义map,将合法的Token映射为一个变量,逻辑清晰且性能较好 。http { map $http_token $token_valid { default 0; # 默认值0,表示Token无效 "your_secure_token_abcde12345" 1; # 有效的Token,值为1 "another_valid_token_56789" 1; } server { location /api/ { if ($token_valid = 0) { return 403; # Token无效则拒绝访问 } proxy_pass http://your_backend; } } }安全建议:由于Token在Header中明文传输,务必为服务启用HTTPS以防止Token被窃听 。
-
七层代理白名单案例
# 定义白名单 IP 映射
map $remote_addr $allowed_admin {
default 0;
192.168.1.100 1;
~^125\.90\.86\. 1; # 匹配 125.90.86.0/24
}
server {
listen 9443;
location / {
if ($allowed_admin = 0) {
return 403;
}
proxy_pass http://47.98.158.28;
}
}
注意:map 不支持 CIDR 直接匹配!需用正则。
4. 四层代理(TCP/UDP)白名单
当使用Nginx的stream模块作为四层代理(例如代理MySQL、Redis、SSH等服务)时,同样可以配置白名单。
-
配置方法
配置在
stream块中,与http块同级 。stream { # 在stream块或具体的server块内定义规则 server { listen 3306; # 代理MySQL服务 allow 10.0.0.0/24; # 允许应用服务器网段 deny all; proxy_pass backend_mysql:3306; } server { listen 2222; # 代理SSH服务 allow 192.168.1.105; # 只允许特定管理IP deny all; proxy_pass backend_ssh:22; } }
或者创建独立的白名单文件,通过include指令引入
创建一个新文件来存放白名单IP地址,例如/etc/nginx/whiteiplist_global.conf。每行写一个允许的IP地址或网段,以分号结尾
# /etc/nginx/whiteiplist_global.conf
# 白名单IP列表
allow 192.168.33.200;
allow 10.10.0.0/16;
allow 202.202.202.100;
# 在nginx.conf中,与http块同级
stream {
# 引入外部白名单文件
include /etc/nginx/whiteiplist_global.conf;
deny all; # 关键:拒绝所有非白名单IP的连接
# 示例:代理MySQL服务
server {
listen 63306;
proxy_pass 192.168.33.88:3306;
# 此server块将应用在stream块顶部定义的访问规则
}
# 示例:为不同服务设置不同的白名单(可选)
# 如果需要为不同端口设置完全独立的白名单,可以在各自的server块内单独引入文件或直接写规则
server {
listen 65222;
include /etc/nginx/whiteiplist_ssh.conf; # 为SSH服务使用独立的名单
deny all;
proxy_pass 192.168.33.88:22;
}
}
备注:如果需要为不同端口设置完全独立的白名单,可以在各自的server块内单独引入文件或直接写规则。
5. 生产环境注意事项
-
规则顺序至关重要:Nginx的访问规则是按顺序匹配的,遇到第一个匹配的规则就会停止。务必确保
allow规则在deny规则之前,并且将更精确的IP匹配放在前面 。 -
动态管理与持久化:对于需要频繁变更的白名单,可以考虑使用
include指令引入外部配置文件,便于管理。修改配置后,务必使用nginx -t测试语法,然后用nginx -s reload平滑重载配置 。 -
组合使用,纵深防御:不要依赖单一的白名单策略。例如,可以同时配置IP白名单和Token验证,为敏感服务构建多重安全屏障 。
-
清晰的错误页面:可以考虑为403(Forbidden)等错误定制统一的错误页面,避免泄露不必要的服务器信息 。
1206

被折叠的 条评论
为什么被折叠?



