Nginx 通过 IP 黑白名单、HTTP 基本认证、geo 模块动态变量及请求特征(User-Agent、Referer 等)实现客户端差异化访问控制,需注意规则顺序、反向代理下 IP 获取方式、文件权限与安全限制。

Nginx 限制不同客户端的访问权限,核心是识别“谁”在访问(IP、用户身份、请求特征等),再施加差异化控制。不依赖外部服务时,主要靠内置模块实现,方式清晰、部署轻量。
按客户端 IP 实施黑白名单控制
这是最常用且见效快的方式,适用于运维后台、内部接口等场景。Nginx 按 从上到下顺序匹配 allow/deny 规则,最后必须以 deny all 收尾,否则前面的 deny 可能被跳过。
- 在 location 块中直接写:允许指定 IP,拒绝其余所有
- allow 192.168.10.5;
- allow 2001:db8::/32;
- deny all;
- 若规则较多,建议抽离为独立文件(如
/etc/nginx/conf.d/ip-whitelist.conf),用include引入,便于多站点复用和版本管理 - 注意:若有反向代理(如 CDN 或负载均衡),
$remote_addr是代理 IP,需改用$http_x_forwarded_for并配合set_real_ip_from设置可信源,否则会误封
通过 HTTP 基本认证区分用户身份
适合需要账号密码登录的管理页面或测试环境,不加密传输但配置简单。Nginx 自带支持,无需额外模块。
- 先用
htpasswd生成密码文件:sudo htpasswd -c /etc/nginx/.htpasswd admin - 在 location 中启用认证:
auth_basic "Admin Area"; auth_basic_user_file /etc/nginx/.htpasswd; - 每个用户凭据单独一行,可多人共用同一文件;密码明文存储在文件中,务必设好文件权限(
chmod 600) - 注意:该方式对浏览器友好,但不适合高安全要求场景(推荐搭配 HTTPS 使用)
结合 geo 模块实现动态变量控制
当黑名单规模较大(如数百个恶意 IP)、或需跨多个 server 复用逻辑时,geo 模块比重复写 allow/deny 更高效、更易维护。
- 在 http 块顶部定义变量:
geo $is_blocked { default 0; 192.168.200.100 1; 203.0.113.0/24 1; } - 在 location 中判断:
if ($is_blocked) { return 403; } - 支持 include 外部 IP 列表文件,方便脚本自动更新(例如定时拉取威胁情报)
- 注意:if 在 location 内使用是安全的,但在 server 或 http 级别慎用,避免与 rewrite 等指令冲突
基于请求特征做精细化过滤
除了来源 IP 和用户凭证,还可依据 User-Agent、Referer、请求方法甚至自定义 Header 控制访问,适合防爬、防盗链或灰度发布。
- 屏蔽工具类访问:
if ($http_user_agent ~* "(wget|curl|python-requests)") { return 403; } - 限制图片外链:
if ($http_referer !~ ^(https?://yourdomain\.com/|https?://$host/)) { return 403; } - 只允许 GET/HEAD:
if ($request_method !~ ^(GET|HEAD)$) { return 405; } - 注意:正则匹配有性能开销,高频路径慎用;部分客户端可伪造 User-Agent 或 Referer,不能作为唯一安全依据











