Nginx Proxy Manager 访问列表(Access List)完全指南:IP 黑白名单与 Basic Auth 认证
【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager
访问列表(Access List)是 Nginx Proxy Manager(NPM)中用于管控代理主机(Proxy Host)入口流量的核心安全机制:通过客户端 IP 地址的黑名单/白名单规则,配合基于 Basic HTTP Authentication 的用户名密码认证,为一层不设防的上游 Web 服务提供独立于应用自身的访问控制。本文以官方帮助文档为主线,结合本项目后端源码(access-list.js、模型定义、Nginx 模板)与 OpenAPI 定义,完整讲解访问列表的概念、配置项、创建流程、底层实现原理以及真实可用的 API 调用示例,帮助你为每个代理主机量身定制访问策略。
什么是访问列表?
根据官方文档(AccessLists.md)的定义,访问列表允许你创建一份针对客户端 IP 地址的黑名单或白名单,同时通过Basic HTTP Authentication(HTTP 基本认证)为代理主机提供用户名/密码级别的认证能力。
其核心特征包括:
- 一份列表,多种规则:单个访问列表内可以同时配置多条“客户端(client)规则”和多个“用户名 + 密码”组合;
- 一对多复用:同一份访问列表可以被应用到一个或多个代理主机上,规则集中维护、统一生效;
- 典型适用场景:被代理的 Web 服务自身没有内置认证机制,或者你希望拦截未知客户端、将访问范围限制在可信网络内。
官方文档特别指出,这类防护"most useful for forwarded web services that do not have authentication mechanisms built in"(对没有内置认证机制的转发 Web 服务最为有用)——这正是反向代理场景下最常见的痛点:内网服务裸奔在公网,不想(也无法)修改应用代码,此时在 NPM 这一层做访问控制是最轻量的解法。
访问列表的三类核心配置
访问列表的配置由三个维度组成,它们在数据模型(access_list.js、access_list_auth.js、access_list_client.js)与 OpenAPI 请求体(createAccessList)中均有完整对应:
| 配置维度 | 字段 | 说明 |
|---|---|---|
| 基本属性 | name | 列表名称(必填),如My Access List |
| 认证用户 | items | 数组,每项包含username与password,用于 Basic Auth 登录 |
| 客户端规则 | clients | 数组,每项包含directive(allow/deny)与address(IP 或 CIDR 网段) |
| 匹配模式 | satisfy_any | true表示"任一规则满足即放行"(satisfy any;),false表示"所有规则必须满足"(satisfy all;) |
| 认证透传 | pass_auth | false时后端会清空Authorization请求头(proxy_set_header Authorization "";),默认true透传 |
从数据库迁移记录可以确认字段的演进历史:客户端规则由 20200410143839_access_list_client.js 引入(同时新增satify_any字段),而pass_auth由 20201014143841_pass_auth.js 在 2020 年加入,默认值为1(即默认透传认证信息)。
创建访问列表:前端表单与 API 请求
前端操作路径
在 Web 界面中,进入Access Lists(访问列表)页面,点击新建即可配置:填写名称、添加若干客户端规则(选择Allow或Deny指令并输入 IP/CIDR 地址)、添加若干用户名密码条目。前端提交时会把clients精简为directive与address两个字段(见 AccessListModal.tsx),与后端期望的数据结构完全一致。
完整 API 请求示例
以下 POST 请求创建一份同时具备 IP 白名单与 Basic Auth 的访问列表(示例取自 post.json 的官方 example):
POST /api/nginx/access-lists Content-Type: application/json Authorization: Bearer <token> { "name": "My Access List", "satisfy_any": true, "pass_auth": false, "items": [ { "username": "admin", "password": "pass" } ], "clients": [ { "directive": "allow", "address": "192.168.0.0/24" } ] }请求体 schema 的完整字段(均通过$ref引用公共定义):
name:字符串,必填,列表名称;satisfy_any:布尔值,匹配模式;pass_auth:布尔值,是否把认证头透传给上游;items:认证用户数组(access_items),元素为{ username, password };clients:客户端规则数组(access_clients),元素为{ directive, address }。
服务端创建流程
路由 access_lists.js 将 POST 请求交给internalAccessList.create(access-list.js),其内部执行顺序为:
- 权限校验
access.can("access_lists:create"); - 插入
access_list主记录(name、satisfy_any、pass_auth、owner_user_id); - 并行插入所有
items到access_list_auth表; - 串行插入所有
clients到access_list_client表; - 重新拉取完整数据(含
owner/items/clients/proxy_hosts扩展); - 调用
internalAccessList.build生成 htpasswd 文件; - 若该列表已被代理主机引用(
proxy_host_count > 0),触发bulkGenerateConfigs重新生成这些主机的 Nginx 配置; - 写入审计日志(
action: "created")并返回脱敏后的结果。
底层实现原理:从数据库到 Nginx 配置
数据模型:三表结构
访问列表在数据库中由三张表协作完成:
| 表 | 模型文件 | 职责 |
|---|---|---|
access_list | access_list.js | 列表主表,持有name、satisfy_any、pass_auth、owner_user_id,布尔字段在读写数据库时自动与 0/1 互转 |
access_list_auth | access_list_auth.js | 认证用户表,每行一个username/password组合 |
access_list_client | access_list_client.js | 客户端规则表,每行一个directive+address |
主表通过 Objection.js 的关系映射关联三张子表:items(HasMany →access_list_auth)、clients(HasMany →access_list_client)、proxy_hosts(HasMany →proxy_host,以access_list_id关联)。需要说明的是:虽然文档称其为"黑名单或白名单",但clients表中的directive字段实际支持allow与deny两种取值,且同一列表内可以混合使用多条规则。
htpasswd 文件生成
build方法(access-list.js)负责把认证用户写入/data/access/<list_id>文件:
- 删除旧文件并创建空文件;
- 对每个用户调用
openssl passwd -apr1 <password>生成APR1(Apache MD5)格式的密码哈希; - 以
用户名:哈希的格式逐行追加写入。
写入完成后,该文件路径会被模板中的auth_basic_user_file指令引用,供 Nginx 的 Basic Auth 校验使用。该目录(/data/access/)位于 NPM 容器的持久化数据卷内。
Nginx 配置模板
代理主机的 Nginx 配置通过 proxy_host.conf 引入 _access.conf,当access_list_id > 0时生成如下关键配置:
# Authorization auth_basic "Authorization required"; auth_basic_user_file /data/access/{{ access_list_id }}; {% if access_list.pass_auth == 0 or access_list.pass_auth == false %} proxy_set_header Authorization ""; {% endif %} # Access Rules: {{ access_list.clients | size }} total {% for client in access_list.clients %} {{client | nginxAccessRule}} {% endfor %} deny all; # Access checks must... satisfy any;逐行解读:
auth_basic/auth_basic_user_file:启用 HTTP 基本认证并指向对应 htpasswd 文件(仅当items非空时生成);proxy_set_header Authorization "";:当pass_auth = false时,清空转发给上游的认证头,避免把 Basic Auth 凭据泄露给后端应用(当pass_auth = true时则透传,可配合后端自身的认证体系使用);- 客户端规则循环:
nginxAccessRule过滤器(utils.js)把{ directive, address }渲染为allow 192.168.0.0/24;这类标准 nginx 指令;当存在客户端规则时,模板末尾会追加deny all;作为兜底,即白名单模式默认拒绝一切未列出的来源; satisfy any;/satisfy all;:由satisfy_any决定认证与 IP 规则之间的组合逻辑。satisfy any表示"通过 IP 规则或认证其一即可",satisfy all表示"必须同时通过 IP 规则且通过认证"。实际语义为:任一(any)满足即放行,全部(all)必须满足才放行。
更新与删除的联动效应
- 更新(access-list.js):
items采用"重建"策略——带密码的条目直接重插,password为空字符串的条目视为"保留但不改密"(加入itemsToKeep,删除时用NOT IN排除);clients则整体删除后按新数组重建(忽略空address)。保存后若存在引用该列表的代理主机,会重新生成配置并nginx.reload()热重载。 - 删除(access-list.js):软删除主记录(
is_deleted = 1),同时把引用它的所有代理主机的access_list_id置为0(即解绑),重新生成这些主机的配置并 reload,最后删除对应的/data/access/<id>htpasswd 文件。
密码安全:API 响应的脱敏处理
出于安全考虑,后端在返回访问列表数据时会对密码做**脱敏(masking)**处理。maskItems方法(access-list.js)会将每个items条目的password置空,并生成一个hint字段——取原密码首字符加一串*(长度与原密码一致)作为提示。例如密码apple会返回hint: "a****"、password: ""。这意味着:通过 API 读取列表永远拿不到明文密码;前端编辑时看到的是hint,只有重新输入新密码才能更新。
实战配置建议
结合模板语义与源码行为,给出以下可直接落地的配置思路:
- 纯白名单场景:只配置客户端规则(如
allow 10.0.0.0/8),不配置认证用户。模板会自动追加deny all;,实现"仅内网可访问"; - 纯认证场景:只配置用户名密码,不配置客户端规则。此时只有
auth_basic生效,所有访客都需登录; - "IP 或密码"双通道:设置
satisfy_any: true,同时配置内网白名单与认证用户——内网 IP 免登录直达,公网用户需凭密码访问; - "IP 且密码"强校验:设置
satisfy_any: false,要求客户端 IP 命中规则并且通过认证才放行,适合对敏感管理后台做双重防护; - 隐藏上游认证信息:若不希望 Basic Auth 凭据到达后端服务(例如后端会把
Authorization头写入日志),将pass_auth设为false。
注意:Basic Auth 的凭据以 Base64 编码传输,仅在 HTTPS 加持下才是安全的。生产环境务必通过 NPM 为对应域名启用 SSL 证书,否则用户名密码存在明文泄露风险。
小结
访问列表是 Nginx Proxy Manager 在"代理层"提供的一站式访问控制方案:clients负责 IP 维度的放行/拦截(支持allow/deny与 CIDR),items负责基于 htpasswd 文件的 Basic Auth 身份认证,satisfy_any决定二者的组合逻辑,pass_auth控制认证头的透传。从数据库三表结构、openssl passwd -apr1哈希生成,到 Nginx 模板 的指令渲染与热重载联动,整个链路在源码中清晰可循。对于"应用无认证机制、仅限可信网络访问、或需要统一管控多个代理主机入口"的场景,访问列表都能以极低改造成本直接落地。
【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考