Nginx Proxy Manager 端口转发(Stream)功能详解:TCP/UDP 流量转发实战

Nginx Proxy Manager 端口转发(Stream)功能详解:TCP/UDP 流量转发实战 Nginx Proxy Manager 端口转发Stream功能详解TCP/UDP 流量转发实战【免费下载链接】nginx-proxy-managerDocker container for managing Nginx proxy hosts with a simple, powerful interface项目地址: https://gitcode.com/GitHub_Trending/ng/nginx-proxy-manager导读本文围绕 Nginx Proxy Manager 的Stream端口转发功能展开。Stream 基于 Nginx 的流模块能够将 TCP/UDP 流量直接转发到网络上的另一台计算机适用于游戏服务器、FTP、SSH 等非 HTTP 协议的代理场景。读完本文你将掌握端口转发的适用场景、配置字段含义、SSL 终止支持、底层 Nginx 配置生成原理以及如何通过 API 或源码理解其完整工作链路。什么是端口转发Stream在 Nginx Proxy Manager 中Stream端口转发是一个相对较新的功能它的核心作用是把 TCP/UDP 流量直接转发到网络中的另一台计算机。与 HTTP/HTTPS 反向代理Proxy Host不同Stream 不关心应用层协议而是在**传输层Layer 4**按 IP 和端口转发原始数据流。因此凡是基于 TCP 或 UDP 的协议都可以通过 Stream 暴露到公网游戏服务器如 Minecraft、CS 等需要固定端口直连的游戏服务FTP 服务传统 FTP 使用 21 端口控制连接主动/被动模式下还需要转发数据端口SSH 服务将内网主机的 SSH 端口映射到公网方便远程管理数据库连接MySQL3306、PostgreSQL5432等其他自定义 TCP/UDP 服务。如果你正在运行上述服务端口转发功能就能派上用场。它的价值在于你可以用一台部署了 Nginx Proxy Manager 的公网主机统一收口所有内网服务的入站流量无需为每个服务单独购买公网 IP 或调整路由器端口映射。端口转发与 HTTP 代理的区别在 Nginx Proxy Manager 的管理界面中Stream 与 Proxy HostHTTP 代理是两类独立的资源理解它们的差异有助于选对功能维度Proxy HostHTTP 代理Stream端口转发工作层级应用层HTTP/HTTPS传输层TCP/UDP路由依据域名 Host 头IP 端口典型协议HTTP、HTTPS、WebSocketSSH、FTP、游戏协议、数据库是否支持 SSL支持且通常是核心诉求支持 TCP 上的 SSL流式透传域名配置必须配置domain_names不按域名路由这一区别在源码中也有明确体现在 backend/internal/stream.js 的create流程里有一段注释写道streams arent routed by domain name so dont store domain names in the DBStream 不按域名路由因此不在数据库中存储域名并在入库前通过delete data_no_domains.domain_names把domain_names字段移除。这说明 Stream 从数据模型层面就与域名解耦纯粹以端口为核心标识。核心概念入站端口与转发目标一个 Stream 配置本质上只回答两个问题监听哪个入站端口incoming_port把流量转发到哪里forwarding_host forwarding_port。在管理界面中创建 Stream 时需要在Details详细信息标签页填写以下核心字段对应前端弹窗 frontend/src/modals/StreamModal.tsx 中的表单Incoming Port入站端口Nginx 监听的公网端口取值范围 165535。前端通过validateNumber(1, 65535)校验见 frontend/src/modals/StreamModal.tsxOpenAPI 规范同样约束为 165535见 backend/schema/components/stream-object.json。Forward Host / IP转发目标主机目标计算机的域名、IPv4 或 IPv6 地址。OpenAPI 规范允许域名如example.com、IPv40.0.0.0255.255.255.255格式或 IPv6见 backend/schema/components/stream-object.json。Forward Port转发端口目标主机上服务的真实端口同样取值 165535。TCP ForwardingTCP 转发布尔开关是否转发 TCP 流量。UDP ForwardingUDP 转发布尔开关是否转发 UDP 流量。SSL CertificateSSL 证书可选用于对入站 TCP 连接启用 SSL 终止/透传详见下文。Enabled启用是否立即生效。从数据库模型看tcp_forwarding与udp_forwarding是独立的布尔字段见 backend/models/stream.js二者可以同时开启也可以只开其一。若同时开启Nginx 会为同一入站端口生成 TCP 与 UDP 两套server块见下文模板分析。在管理界面中Stream 列表默认按incoming_port升序排列见 backend/internal/stream.js 与 backend/models/stream.js方便运维人员快速定位端口占用情况。生成的真实 Nginx 配置解析Nginx Proxy Manager 的本质是「配置生成器」你在界面上填写的表单最终会被渲染成一段标准 Nginx 配置。Stream 的配置模板位于 backend/templates/stream.conf其核心逻辑如下# ------------------------------------------------------------ # {{ incoming_port }} TCP: {{ tcp_forwarding }} UDP: {{ udp_forwarding }} # ------------------------------------------------------------ {% if enabled %} {% if tcp_forwarding 1 or tcp_forwarding true -%} server { listen {{ incoming_port }} reuseport {%- if certificate %} ssl {%- endif %}; {% unless ipv6 -%} # {%- endunless -%} listen [::]:{{ incoming_port }} reuseport {%- if certificate %} ssl {%- endif %}; {%- include _certificates_stream.conf %} proxy_pass {{ forwarding_host }}:{{ forwarding_port }}; access_log /data/logs/stream-{{ id }}_access.log stream; error_log /data/logs/stream-{{ id }}_error.log warn; # Custom include /data/nginx/custom/server_stream[.]conf; include /data/nginx/custom/server_stream_tcp[.]conf; } {% endif %} {% if udp_forwarding 1 or udp_forwarding true -%} server { listen {{ incoming_port }} udp reuseport; {% unless ipv6 -%} # {%- endunless -%} listen [::]:{{ incoming_port }} udp reuseport; proxy_pass {{ forwarding_host }}:{{ forwarding_port }}; access_log /data/logs/stream-{{ id }}_access.log stream; error_log /data/logs/stream-{{ id }}_error.log warn; # Custom include /data/nginx/custom/server_stream[.]conf; include /data/nginx/custom/server_stream_udp[.]conf; } {% endif %} {% endif %}这段模板揭示了几个关键实现细节条件渲染由enabled开关控制{% if enabled %}保证禁用disabled的 Stream 不会生成任何server块这正是「启用/禁用」功能的底层实现原理——见 backend/internal/stream.jsenable会调用internalNginx.configure重新生成配置而disable会调用internalNginx.deleteConfig删除配置并reload。TCP 与 UDP 是两套独立的server块TCP 块使用listen {{ incoming_port }} reuseport可选追加sslUDP 块使用listen {{ incoming_port }} udp reuseport。reuseport指令允许多个 socket 绑定同一端口提升多核场景下的分发性能。IPv6 双栈支持每套server块都会尝试监听[::]:{{ incoming_port }}当项目未启用 IPv6 时ipv6为假模板通过{% unless ipv6 -%} # {%- endunless -%}输出#注释掉该行实现优雅降级。流式访问日志每个 Stream 生成独立的访问/错误日志文件/data/logs/stream-{{ id }}_access.log与stream-{{ id }}_error.log方便按 Stream 维度排查流量。自定义配置钩子模板末尾 include 了/data/nginx/custom/server_stream[.]conf、server_stream_tcp[.]conf、server_stream_udp[.]conf三个可选文件方括号.写法保证文件不存在时不报错高级用户可以写入额外的 Nginx 指令。SSL 只在 TCP 块生效{%- if certificate %} ssl {%- endif %}表明当为该 Stream 绑定证书时TCP 监听会启用ssl指令证书相关配置由_certificates_stream.conf子模板注入见 backend/templates/_certificates_stream.conf。SSL 支持为 TCP 流量启用加密虽然 Stream 面向的是非 HTTP 协议但 Nginx Proxy Manager 仍允许为 TCP 转发绑定SSL 证书实现「入站加密 → 内网明文」或「入站加密 → 内网同样加密」的透传模式。配置方式与 Proxy Host 类似在 Stream 弹窗的SSL 标签页见 frontend/src/modals/StreamModal.tsx中通过SSLCertificateField选择一个已有证书或选择「新建证书」快捷创建certificate_id new。在 API 层当提交certificate_id: new时backend/internal/stream.js 会调用internalCertificate.createQuickCertificate(access, data)先快速签发证书再回填certificate_id完成创建更新update流程同样支持这一快捷路径见 backend/internal/stream.js。这表明 Stream 与证书模块是深度集成的而不是简单的字段挂载。需要说明的是Stream 的 SSL 是流式透传/终止于 Nginx 层与 HTTP 代理的证书续期、HSTS 等 Web 特性无关——因为 Nginx 的stream模块工作在传输层_certificates_stream.conf只注入ssl_certificate、ssl_certificate_key等与 TCP 加密直接相关的指令。Stream 的完整生命周期从 API 到 Nginx 配置理解一个 Stream 从创建到生效的完整链路有助于在生产环境中排查问题。整个过程由 backend/internal/stream.js 驱动分为以下步骤权限校验调用access.can(streams:create, data)检查当前用户是否具备创建权限。权限模型定义在 backend/lib/access/streams-create.json管理员可直接操作普通用户则需要permission_streams具备 manage 权限。数据入库通过streamModel.query().insertAndFetch(data)写入stream表backend/models/stream.js。模型层会自动维护created_on/modified_on时间戳并把enabled、tcp_forwarding、udp_forwarding等布尔字段与整数在数据库层面互相转换见 backend/models/stream.js。可选快速签发证书若选择新建证书会先调用证书模块再把certificate_id回填。生成并应用 Nginx 配置调用internalNginx.configure(streamModel, stream, row)用 backend/templates/stream.conf 渲染出实际配置并触发 Nginx reload。写入审计日志调用internalAuditLog.add记录created/updated/deleted/enabled/disabled等动作见 backend/internal/stream.js所有操作均可追溯。更新update流程同样遵循「权限校验 → 入库 → 重新生成配置 → 审计」的链路而删除delete与禁用disable则调用internalNginx.deleteConfig(stream, row)移除配置文件并reload见 backend/internal/stream.js。从源码结构看enable/disable被实现为独立操作而非字段编辑便于在审计日志中区分操作类型。列表查询getAll则按is_deleted 0过滤默认关联加载certificate与owner关系见 backend/models/stream.js并支持通过expand参数按需展开关联数据见 backend/internal/stream.js这也是前端 Stream 列表页展示证书与所有者信息的底层来源。通过 REST API 管理 StreamNginx Proxy Manager 提供了完整的 REST API 来管理端口转发OpenAPI 规范中的 Stream 对象定义在 backend/schema/components/stream-object.json核心字段如下字段类型说明idinteger主键incoming_portinteger (1–65535)入站监听端口必填forwarding_hoststring转发目标域名/IPv4/IPv6必填forwarding_portinteger (1–65535)转发目标端口必填tcp_forwardingboolean是否启用 TCP 转发必填udp_forwardingboolean是否启用 UDP 转发必填enabledboolean是否启用必填certificate_idinteger可选绑定的 SSL 证书 IDmetaobject扩展元数据默认为{}owner_user_idinteger归属用户必填对应的 API 端点包括定义见 backend/schema/paths/nginx/streams 与 backend/routes/nginx/streams.jsGET /api/nginx/streams—— 列出所有 StreamPOST /api/nginx/streams—— 新建 StreamGET /api/nginx/streams/{streamID}—— 获取单个 StreamPUT /api/nginx/streams/{streamID}—— 更新 StreamDELETE /api/nginx/streams/{streamID}—— 删除 StreamPOST /api/nginx/streams/{streamID}/enable与POST /api/nginx/streams/{streamID}/disable—— 启用/禁用。例如创建一个「将公网 2222 端口转发到内网192.168.1.10的 22 端口SSH」的 Stream{ incoming_port: 2222, forwarding_host: 192.168.1.10, forwarding_port: 22, tcp_forwarding: true, udp_forwarding: false, enabled: true }提交后后端会按照上文的生命周期流程生成配置并立即生效。前端通过 frontend/src/api/backend/createStream.ts、updateStream.ts 等封装调用这些端点管理界面与 API 完全等价。端口冲突与运维注意事项从源码实现看Stream 功能在端口管理上有一个值得注意的点在 backend/internal/stream.js 的create与 backend/internal/stream.js 的update中均存在TODO: At this point the existing ports should have been checked此处应检查已有端口占用的注释。也就是说当前版本在后端并未显式校验入站端口是否已被其他 Stream 或系统服务占用依赖 Nginx 配置 reload 阶段自行报错。因此在生产环境中建议运维人员注意入站端口需全局唯一同一个incoming_port不要重复用于多个 Stream否则生成的 Nginx 配置会产生listen冲突reload 时报错导致配置不生效。避开宿主已占用端口入站端口会绑定在运行 Nginx Proxy Manager 的主机上请勿与 SSH22、Web 管理端口81等系统端口冲突。关注防火墙/安全组Stream 监听的是原始 TCP/UDP 端口需在云厂商安全组与系统防火墙中放行对应入站流量这与 HTTP 代理走 80/443 的情形不同。TCP/UDP 同开时注意协议差异同一端口同时开启 TCP 与 UDP 转发是允许的会生成两套server块但目标服务必须分别监听对应协议否则会有一侧连接失败。通过自定义配置钩子做精细控制如需要额外指令如proxy_timeout、proxy_buffer_size等可挂载到/data/nginx/custom/server_stream_tcp[.]conf或server_stream_udp[.]conf避免直接改动生成的配置。从源码进一步学习如果你想深入了解 Stream 的实现细节可以从以下文件入手均在当前仓库内backend/templates/stream.conf —— 端口转发最终的 Nginx 配置模板是理解全部行为的最佳起点backend/internal/stream.js —— Stream 的完整 CRUD、启停与审计逻辑backend/models/stream.js —— 数据模型、布尔字段转换与关联关系owner / certificatebackend/schema/components/stream-object.json —— OpenAPI 字段定义与取值范围backend/routes/nginx/streams.js —— REST API 路由层frontend/src/modals/StreamModal.tsx —— 前端创建/编辑表单与校验规则frontend/src/pages/Nginx/Streams —— 前端列表页实现backend/schema/paths/nginx/streams —— API 路径规范含 enable/disable 等操作。总结端口转发Stream是 Nginx Proxy Manager 中面向非 HTTP 流量的核心能力它以入站端口 转发目标为模型利用 Nginxstream模块在传输层完成 TCP/UDP 数据的透明转发天然适用于 SSH、FTP、游戏服务器等场景。在实现上Stream 与证书模块深度集成支持 TCP SSL配置通过 backend/templates/stream.conf 模板渲染生成具备 IPv6 双栈、独立日志、自定义配置钩子与完整审计能力同时提供了与界面等价的 REST API便于自动化管理。使用时只需注意入站端口的唯一性与防火墙放行即可快速将内网任意 TCP/UDP 服务安全地暴露到公网。【免费下载链接】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),仅供参考