前提
在过去的几天里,我设置了一个使用 Docker 运行 Mastodon 的家庭服务器。我已经有一个在 Raspberry 上运行的 Nextcloud 实例,所以现在我尝试通过专用子域(我正在使用免费的 DDNS)使这两个实例可用。
我设置了两个子域(都明显指向我的家庭路由器),如下所示:
- 乳齿象.example.com
- nextcloud.example.com
然后,我在路由器中设置端口转发,将端口 80、443 上的 TCP/UDP 流量发送到 Mastodon 服务器的相同端口,而自定义端口 3000、3001 上的 TCP/UDP 流量则映射到 Nexcloud 的端口 80、443服务器。
到这里为止都没有问题,如果我https://mastodon.example.com
在浏览器中输入内容,我就会进入 Mastodon 服务器,然后https://nextcloud.example.com:3001
我就会进入 Nextcloud 服务器。
问题
现在我正在尝试编辑 mastodon 服务器中 nginx-proxy 容器的配置,以便重定向每个请求,以避免nextcloud.example.com
必须nextcloud.example.com:3001
指定端口。
myadditions.conf
我在映射到容器卷的文件夹中创建了一个新文件/etc/nginx/conf.d
,重新启动服务器后,我可以确认 nginx 已正确加载它docker exec nginx-proxy nginx -T
。
我的问题是,我尝试放入文件中进行重定向的所有内容似乎都被忽略,我输入时得到的结果始终nextcloud.example.com
相同:错误MOZILLA_PKIX_ERROR_SELF_SIGNED_CERT
(我使用的是 Firefox)。我认为该错误是因为服务器没有尝试重定向调用,因此它提供的证书与 nextcloud 子域不匹配。我有什么遗漏的吗?
目前我的myadditions.conf
文件如下所示:
server {
server_name nextcloud.example.com;
return 301 $scheme://nextcloud.example.com:3001$request_uri;
}
但我尝试了很多设置,结果没有任何变化,所以我开始认为问题不在于我在文件中写入的内容。顺便说一句,如果我删除我的文件,错误也是一样的。
以下是我为解决问题所采取的步骤。
1. 获取附加证书
我创建了一个
letsencrypt_user_data
文件并将其映射到nginxproxy/acme-companion
容器,以指示它请求并不断更新nextcloud.example.com
子域的附加证书(请参阅容器文档中的独立证书)。这是我现在的文件:2.更正nginx重定向
我编辑了
myadditions.conf
在 Nginx 配置文件夹中创建的文件:我将重定向类型从 更改为return 301
,proxy_pass
并添加了一个server
上下文来重定向指定新证书的端口 443 上的流量。这就是文件现在的样子,请记住,我刚刚复制并编辑了它,它可以工作,但我并不真正知道它包含的大部分内容的含义,因此这可能是一个不好的例子:现在两个子域都可以工作。谢谢@u1686_grawity,你的回答包含了我需要的所有提示和解释。
您正在连接到 HTTPS URL,因此必须为该域的 HTTPS 设置应答服务器- 它不能在没有完全建立 TLS 连接的情况下仅提供纯文本重定向。(如果浏览器允许这样做,那么攻击者就很容易做同样的事情。)
您的服务器块没有指定它将侦听 TLS 端口,也没有定义任何证书,因此它甚至可能不会被选择用于请求 - Nginx 最终选择第一个标记为支持 TLS 的服务器块,并且使用那里定义的任何证书。
请记住,
30x
重定向是客户端的——服务器仅返回新的 URL,客户端即可访问该 URL。您不需要输入非标准端口,但它会在地址栏中可见;nginx-proxy 容器实际上不会执行任何代理。如果您想要代理,那么您需要使用
proxy_pass
而不是return
. 在这种情况下,Nginx 仍然需要有效的 HTTPS 设置。Nginx 在无法访问域的匹配证书的情况下处理此问题的唯一另一种方法是根据通过 TLS SNI 报告的主机名“盲目”代理所有数据(流代理模式),以便浏览器与以下命令进行 HTTPS 握手:而是后端服务器。我不确定 Nginx 是否具有该功能,尽管还有其他代理具有该功能。