Nginx Proxy Manager 中的 Proxy Host:入口端点、SSL 终止与反向代理配置全解析
2026/9/10 13:22:59 网站建设 项目流程

Nginx Proxy Manager 中的 Proxy Host:入口端点、SSL 终止与反向代理配置全解析

【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager

Proxy Host(代理主机)是 Nginx Proxy Manager 中最核心、使用最频繁的资源类型:它是你想转发的外部 Web 服务进入 Nginx 的"入口端点"(incoming endpoint)。本文从官方文档对 Proxy Host 的定义出发,结合当前仓库的后端实现、数据库模型与 Nginx 模板源码,讲透 Proxy Host 的本质、它如何为不具备 SSL 能力的后端服务提供可选的 SSL 终止(SSL termination),以及一个 Proxy Host 从创建到生成 Nginx 配置的完整链路。读完本文,你将能够理解 Nginx Proxy Manager 中 "域名 → Proxy Host → 后端服务" 这条转发链路是如何工作的,并掌握 Proxy Host 各配置项在底层产生的实际效果。

什么是 Proxy Host

按项目内置帮助文档(爱尔兰语版、英语版)的定义,Proxy Host 是你想转发的 Web 服务在 Nginx 上的入口端点。它本质上是一条反向代理规则:

  • 外部客户端通过域名server_name)访问 Nginx 的 80/443 端口;
  • Nginx 根据域名匹配到对应的 Proxy Host;
  • 再将请求转发到由forward_hostforward_port指定的上游服务

文档同时强调两点关键性质:

  1. 可选的 SSL 终止:Proxy Host 可以为那些本身没有内置 SSL 支持的后端服务提供 HTTPS 能力。SSL 证书加载、HTTPS 监听、解密都发生在 Nginx 这一侧,后端服务只需要继续提供普通的 HTTP 服务即可。
  2. 最常见的用途:在 Nginx Proxy Manager 提供的所有主机类型(Proxy Host、Redirection Host、Dead Host、Stream)中,Proxy Host 是日常使用最广泛的——它解决了"如何用统一的域名和 HTTPS 对外暴露多个内部 Web 应用"这一核心问题。

对应地,项目的前端帮助文档(zh/ProxyHosts.md)将其译为"代理服务":代理服务是你想转发网络应用的主机,可为没有 SSL 服务的网络应用提供 SSL 服务(可选)。

Proxy Host 在数据层的落盘:一张专门的数据库表

Proxy Host 在后端对应一个独立的数据库表proxy_host。从初始数据库迁移脚本可以看到其完整表结构:

CREATE TABLE "proxy_host" ( id INTEGER PRIMARY KEY, created_on DATETIME NOT NULL, modified_on DATETIME NOT NULL, owner_user_id INTEGER NOT NULL, -- 属主用户 is_deleted INTEGER NOT NULL DEFAULT 0, -- 软删除标记 domain_names JSON NOT NULL, -- 绑定的域名列表(可多个) forward_ip VARCHAR NOT NULL, -- 上游主机地址(forward_host) forward_port INTEGER NOT NULL, -- 上游端口 access_list_id INTEGER NOT NULL DEFAULT 0, -- 访问控制列表 certificate_id INTEGER NOT NULL DEFAULT 0, -- SSL 证书 ssl_forced INTEGER NOT NULL DEFAULT 0, -- 强制 HTTPS caching_enabled INTEGER NOT NULL DEFAULT 0, -- 缓存 block_exploits INTEGER NOT NULL DEFAULT 0, -- 拦截常见攻击 advanced_config TEXT NOT NULL DEFAULT '', -- 高级 Nginx 配置 meta JSON NOT NULL -- 扩展元数据 );

由此表可见,"入口端点"的三个核心要素在数据层就是三组字段:

  • 对外入口domain_names(一个 Proxy Host 可以绑定多个域名,多个域名共用同一条转发规则);
  • 对内出口forward_ip+forward_port(上游服务地址);
  • SSL 能力certificate_id+ssl_forced(决定是否终止 TLS、是否强制跳转 HTTPS)。

对应的 Objection.js 模型位于 backend/models/proxy_host.js,它通过relationMappings声明了三个关联关系:owner(属主用户)、access_list(访问控制列表)、certificate(SSL 证书),并通过boolFields数组在读写数据库时自动完成 0/1 与true/false的互转。同时,后续迁移还为proxy_host表补充了http2_support(20181113041458_http2_support.js)、hsts_enabled等字段,这些都在前端表单的 SSL 标签页中体现。

在界面上创建一个 Proxy Host:四个标签页

前端创建/编辑 Proxy Host 的入口是 frontend/src/modals/ProxyHostModal.tsx,其表单按四个标签页组织,完整覆盖了"入口端点 + SSL 终止"的全部配置项:

标签页字段含义默认值
DetailsdomainNames绑定的域名列表[]
DetailsforwardScheme上游协议http/httpshttp
DetailsforwardHost上游主机 IP/域名
DetailsforwardPort上游端口
DetailsaccessListId访问控制列表0
DetailscachingEnabled启用缓存false
DetailsblockExploits拦截常见攻击false
DetailsallowWebsocketUpgrade允许 WebSocket 升级false
Locationslocations自定义 location 规则[]
SSLcertificateIdSSL 证书(0表示不启用)0
SSLsslForced强制跳转 HTTPSfalse
SSLhttp2Support启用 HTTP/2false
SSLhstsEnabled启用 HSTSfalse
SSLhstsSubdomainsHSTS 覆盖子域名false
SSLtrustForwardedProto信任X-Forwarded-Protofalse
AdvancedadvancedConfig追加的原始 Nginx 配置""

其中的forwardScheme+forwardHost+forwardPort即文档所说"想转发的 Web 服务":Nginx 收到请求后按该协议与地址把请求代理到上游;而certificateIdsslForced等 SSL 标签页字段,正是"为没有 SSL 能力的服务提供可选的 SSL 终止"这一特性的界面入口。域名、证书、访问控制列表等还分别由 DomainNamesField.tsx、SSLCertificateField.tsx、SSLOptionsFields.tsx 等组件渲染。

创建 Proxy Host 的后端链路:校验 → 入库 → 生成 Nginx 配置

从源码层面看,创建一个 Proxy Host 的完整调用链位于 backend/internal/proxy-host.js 的create()方法,共分五个阶段:

  1. 权限校验access.can("proxy_hosts:create", thisData)检查当前用户是否拥有创建权限,权限定义见 backend/lib/access/proxy_hosts-create.json(需要proxy_hostsmanage权限或 admin 角色)。
  2. 域名占用检查:遍历domain_names,逐个调用internalHost.isHostnameTaken()与已有记录比对,防止同一域名被多个主机占用(重复绑定会被拒绝并抛出ValidationError)。
  3. 数据清洗与入库:通过internalHost.cleanSslHstsData()规范化 SSL/HSTS 字段(advanced_config缺省时补空字符串),然后proxyHostModel.query().insertAndFetch(thisData)写入数据库。
  4. 快速签发证书:前端可以选择certificate_id === "new"来要求"创建主机的同时一键申请 Let's Encrypt 证书",此时后端会调用internalCertificate.createQuickCertificate()完成快速签发,再回填certificate_id
  5. 生成 Nginx 配置并审计:调用internalNginx.configure(proxyHostModel, "proxy_host", row)渲染 Nginx 配置,最后写入一条action: "created"的审计日志(backend/internal/audit-log.js)。

创建之后的日常操作同样走这套"配置生成"机制:update()更新数据后若主机处于启用状态则重新configureenable()重新生成配置;disable()delete()则调用internalNginx.deleteConfig()删除配置并internalNginx.reload()重载 Nginx。也就是说,界面上每一次对 Proxy Host 的增删改启用禁用,最终都会反映为 Nginx 配置文件的生成与重载

SSL 终止在 Nginx 层的实现:从证书到监听再到强制跳转

Proxy Host 的"可选 SSL 终止"由三个 Nginx 子模板协作完成,它们被主模板逐段 include 进最终生成的 server 块。

1. 监听 443 与证书加载(_listen.conf + _certificates.conf)

_listen.conf负责监听端口与 server_name:

listen 80; listen [::]:80; {% if certificate -%} listen 443 ssl; # 存在证书时才监听 443 listen [::]:443 ssl; {% endif %} server_name {{ domain_names | join: " " }}; {% if http2_support %} http2 on; {% else %} http2 off; {% endif %}

_certificates.conf负责挂载证书文件,且按证书来源区分两种路径:

{% if certificate and certificate_id > 0 -%} {% if certificate.provider == "letsencrypt" %} # Let's Encrypt SSL ssl_certificate /etc/letsencrypt/live/npm-{{ certificate_id }}/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/npm-{{ certificate_id }}/privkey.pem; {% else %} # Custom SSL(用户上传的自定义证书) ssl_certificate /data/custom_ssl/npm-{{ certificate_id }}/fullchain.pem; ssl_certificate_key /data/custom_ssl/npm-{{ certificate_id }}/privkey.pem; {% endif %} {% endif %}

这正是"为没有 SSL 能力的内网服务提供 HTTPS"的实现原理:TLS 握手与加解密全部在 Nginx 侧完成,上游服务只收到明文 HTTP 请求。用户只需在 SSL 标签页选择一个证书(自建 Let's Encrypt 证书或上传的自定义证书),无需改动后端服务本身。

2. 强制 HTTPS(_forced_ssl.conf)

当存在证书且开启了ssl_forced时,模板会设置$trust_forwarded_proto变量并引入force-ssl.conf,实现 HTTP 请求 301 跳转到 HTTPS:

{% if certificate and certificate_id > 0 -%} {% if ssl_forced == 1 or ssl_forced == true %} set $trust_forwarded_proto "T"; include conf.d/include/force-ssl.conf; {% endif %} {% endif %}

注意ssl_forced依赖certificate的存在——没有证书就无从强制 HTTPS,这也是为什么该选项默认关闭。

3. HSTS 与 WebSocket 支持(_hsts.conf / proxy_host.conf)

启用hsts_enabled时,模板会为响应追加Strict-Transport-Security头(可选覆盖子域名);启用allow_websocket_upgrade时则注入 WebSocket 升级所需的三个指令:

proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection $http_connection; proxy_http_version 1.1;

这两类能力都封装在 proxy_host.conf 主模板中,按字段条件化输出。

生成出的最终 server 块:一份完整的 Proxy Host 配置

综合以上子模板,一个启用了证书的 Proxy Host 最终会渲染为类似下面的 server 块(主模板见 backend/templates/proxy_host.conf):

server { set $forward_scheme http; # 由 forwardScheme 决定 set $server "192.168.1.10"; # 由 forwardHost 决定 set $port 8080; # 由 forwardPort 决定 listen 80; listen [::]:80; listen 443 ssl; # 存在证书时 listen [::]:443 ssl; server_name app.example.com; ssl_certificate /etc/letsencrypt/live/npm-1/fullchain.pem; ssl_certificate_key /etc/letsencrypt/live/npm-1/privkey.pem; # 缓存 / 攻击拦截 / HSTS / 强制 SSL 等可选块 # ... location / { # 访问控制(_access.conf) # 反向代理核心:include conf.d/include/proxy.conf; proxy_pass $forward_scheme://$server:$port; } # 自定义 location 与高级配置({{ locations }} / {{ advanced_config }}) include /data/nginx/custom/server_proxy[.]conf; }

从中可以看到"入口端点"的完整含义:server_name是入口的匹配键,location /内的proxy_pass(封装在 docker/rootfs/etc/nginx/conf.d/include/proxy.conf)负责把请求转发给上游;SSL 相关的listen 443 sslssl_certificatessl_forced则共同构成了可选的 SSL 终止层。每个 Proxy Host 还有独立的访问日志与错误日志文件(/data/logs/proxy-host-{{ id }}_access.log),便于单独排障。

权限、审计与常见操作

Proxy Host 的使用还涉及权限体系与审计追踪:

  • 权限:后端按操作拆分权限点,如proxy_hosts:createproxy_hosts:updateproxy_hosts:deleteproxy_hosts:list等,前端组件配合HasPermission(frontend/src/components/HasPermission.tsx)控制按钮显隐;普通用户只能看到/操作自己名下的主机(permission_visibility !== "all"时按owner_user_id过滤)。
  • 审计create/update/delete/enable/disable每次操作都会写入审计日志(object_type: "proxy-host"),可在"Audit Log"页面回溯谁在什么时间做了什么改动,相关列表接口见 frontend/src/api/backend/getAuditLogs.ts。
  • API 层面:Proxy Host 的增删改查、启停均有对应 REST 接口与 OpenAPI 描述,例如 backend/lib/access/proxy_hosts-create.json(权限)、backend/lib/access/proxy_hosts-get.json(查看),前端 API 封装位于 frontend/src/api/backend/(如 createProxyHost.ts、toggleProxyHost.ts)。
  • 测试验证:Cypress 端到端测试对 Proxy Host 的创建、转发、SSL 等行为做了完整覆盖,见 test/cypress/e2e/api/ProxyHosts.cy.js。

总结

一句话概括 Proxy Host:它是 Nginx Proxy Manager 里"域名入口 + 反向代理 + 可选 SSL 终止"三位一体的核心资源,也是该项目最常见的应用方式。在数据层它是一张proxy_host表;在界面层它是四个标签页的表单;在 Nginx 层它最终渲染为一个包含server_namelisten 443 sslssl_certificateproxy_pass的 server 块。理解了这三层映射,你就掌握了 Nginx Proxy Manager 反向代理与 HTTPS 终止的全部关键机制,可以据此规划自己的域名转发方案。

【免费下载链接】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),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询