Nginx 访问控制与认证
有的内容只想让特定 IP、账号或来源访问。Nginx 提供三层手段:allow/deny 按 IP 放行、auth_basic 用户名密码认证、valid_referers 与 limit_except 限制来源和请求方法,可单独用也可叠加。
| 手段 | 适用场景 | 关键指令 |
|---|---|---|
| IP 控制 | 内网后台、跳板机专用接口 | allow / deny |
| 账号认证 | 测试环境、临时分享页 | auth_basic / auth_basic_user_file |
| 来源与方法限制 | 防盗链、只读接口 | valid_referers / limit_except |
按 IP 放行与拒绝
allow/deny 按书写顺序匹配,命中即生效;若没有任何规则命中,默认是放行(可写在 http/server/location,会向子级继承):
location /admin {
allow 192.168.1.0/24; # 内网放行
allow 10.0.0.5; # 指定 IP 放行
deny all; # 其余全部拒绝,必须放最后
}
curl -s -o /dev/null -w '%{http_code}\n' http://example.com/admin
# 输出:403(未放行的 IP);内网 IP 访问则为 200
注意 deny all 若写在 allow 前面,后面的放行规则永远不会生效(先匹配先生效)。
用户名密码认证 auth_basic
适合给后台或测试环境加一道简单密码。先生成密码文件(每行 用户名:密码哈希):
# 方式一:htpasswd(Debian/Ubuntu 安装 apache2-utils 后可用)
sudo htpasswd -c /etc/nginx/.htpasswd zhangsan
# 方式二:openssl 生成 apr1 哈希后追加写入
echo "lisi:$(openssl passwd -apr1 '你的密码')" | sudo tee -a /etc/nginx/.htpasswd
配置里打开认证并指向密码文件:
location /admin {
auth_basic "Admin Area"; # 弹窗里显示的文字
auth_basic_user_file /etc/nginx/.htpasswd;
}
curl -u zhangsan:密码 -s -o /dev/null -w '%{http_code}\n' http://example.com/admin
# 输出:200(带账号);不带账号输出 401
限制来源与请求方法
防盗链用 valid_referers 校验来源页,来源不合法时 $invalid_referer 为 1:
location /download {
valid_referers none blocked server_names *.example.com;
if ($invalid_referer) {
return 403;
}
}
按 User-Agent 封禁爬虫,在 if 里匹配 $http_user_agent:
if ($http_user_agent ~* "(python-requests|curl|SemrushBot)") {
return 403;
}
只允许 GET/HEAD 的接口用 limit_except 拒绝其余方法:
location /api/read {
limit_except GET {
deny all; # POST/PUT/DELETE 等一律 403
}
}
小结
访问控制按需组合三招:allow/deny 控 IP(牢记先放行后拒绝的顺序)、auth_basic + htpasswd 控账号、valid_referers/UA/limit_except 控来源与方法。生产环境务必叠加 HTTPS,避免认证信息与内容明文传输。