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,避免认证信息与内容明文传输。

笔记加载中…