十九个子域名,一个允许 IP
通配符 DNS 记录通过自动将任意子域名解析到单个 IP 地址,实现了服务的便捷发布。Nginx Proxy Manager(NPM)进一步简化了发布流程,仅需填写少量字段即可安全地以 HTTPS 方式暴露服务。这种自动化导致了十九个代理主机的创建,它们均运行自托管软件,并采用不同的认证方法。识别出的核心问题是:便捷的发布机制绕过了关于访问控制的关键安全决策。作者的目标并非完全隐藏服务,而是使其仅可通过构建在公共基础设施之上的私有网络进行访问。通配符 DNS 记录虽然简化了设置,但其本身并不提供安全性。NPM 使用 HTTP-01 挑战来获取 Let's Encrypt 证书,这需要保持 80 端口开放,从而构成一个安全漏洞。通过 DNS-01 获取通配符证书可以关闭 80 端口,但需要授予 DNS 区域的写入权限。服务通过将容器置于共享 Docker 网络上来发布,允许 NPM 在内部代理请求。这意味着服务无需直接向主机暴露端口,从而增强了安全性。位于同一 VPS 上的自托管代理网关将流量路由回 NPM,表现为来自 VPS 公网 IP 的入站 HTTPS 流量。该网关的行为最初被误认为是路由故障,实则是安全设计的关键组成部分。NPM 使用 Nginx 配置块强制执行访问控制,仅允许来自网关内部 Docker IP 或 VPS 公网 IP 的请求,随后进行基本 HTTP 身份验证。这确保了即使服务可公开解析且拥有有效证书,访问仍受到限制。用于 Let's Encrypt 挑战的特定位置保持对互联网开放,以满足证书验证要求。两个关键主机——网关的管理面板和配置分发端点——是严格访问控制的例外,因为它们需要在完全集成网关之前即可访问。出现了一个重大问题:某项服务将其服务器地址硬编码到用户连接配置文件中,错误地通告了错误的地址。由于 NPM 通过 X-Forwarded-For 头转发真实客户端 IP,该服务将该头解释为其自身的公网地址,导致客户端连接到错误的服务器。此缺陷之所以未被发现,是因为作者使用网关进行的自身测试始终呈现了预期的正确地址。TLS 终止发生在 NPM 处,NPM 与后端容器之间的流量通过 Docker 网络以未加密的 HTTP 形式传输。