我已经将我的个人网站重建为 Dockerized 链以及同事的 Web 应用程序。这两个项目都是使用容器构建的,显示在两个单独的端口上,一个在端口 80 上,一个在端口 2019 上。每个都运行单独的 Certbot 容器以保持 SSL 加密。我还没有将 Nginx 作为主机的一部分运行,我只是将主机上的端口映射到运行每个应用程序的 Nginx 容器。
我想要的是,example.com
作为我的个人网站,显示端口 80 上显示的内容,并作为application.example.com
Web 应用程序的代理。就上下文而言,每个 Docker 链都是一个 Django 项目,分别使用独立的 PostgreSQL、Certbot 和 Nginx 链来处理数据库、SSL 和托管。
我需要在主机上设置 Nginx 来处理路由吗?如果是这样,我该怎么做才能保持每个应用程序的 SSL 保护?
答案1
我是否需要在主机上设置 Nginx 来处理路由?
听起来您希望所有域都使用相同的标准 HTTP(S) 端口。在这种情况下,是的,您需要一个充当“反向代理”的中央 Nginx(或 Apache 或 HAproxy)实例。(最简单的方法是将其放在主机上,但它可以是自己的容器。)
- “中央” nginx 监听端口 80(用于 HTTP)和 443(用于 HTTPS)
- 用户访问时
https://foo.example.com
无需指定自定义端口,直接连接到“中央”nginx 实例 Nginx 根据
proxy_pass
配置连接到适当的 Docker 容器的地址:端口:server { server_name foo.example.com; listen ...; ssl_certificate ...; location / { proxy_pass http://<docker_ip>:2019; } } server { server_name bar.example.com; listen ...; ssl_certificate ...; location / { proxy_pass ...; } }
另一方面,如果您特别希望自定义端口出现在 URL 中(例如https://sub.example.com:2019
),则不需要 HTTP 代理 - 只需通过 iptables 进行 TCP 级别的“端口转发”,不同的域名根本不会影响任何内容。
我该如何做到这一点并保留每个应用程序的 SSL 保护?
在这种情况下,TLS 是逐跳的,即客户端→反向代理和反向代理→Web 服务器是两个单独的 TLS 连接。第一个需要 Certbot,因为它通过互联网传输。(然而,第二个是系统内部的,不需要太多 TLS。)
换句话说,您必须将 Certbot 证书移至“中央” nginx 实例。您可以通过两种方式进行配置:
Nginx 将所有请求代理到 Docker 容器。容器运行自己的 Certbot 实例,每次更新后,它们都会以某种方式将新证书和密钥复制到主机系统,以便“中央”Nginx 可以使用它。
Nginx 代理所有请求除了
/.well-known/acme-challenge/
。只有“中央” Nginx 系统运行 Certbot 并处理所有域的续订。容器不运行 Certbot;它们要么根本不使用 TLS,要么使用自颁发的证书。
尽管如此,还是可以实现端到端 TLS,其中主机路由连接完全基于 TLS“服务器名称指示”字段。可以使用 HAproxy 和 sniproxy 代替 Nginx 来实现这一点。