我有两个位于同一 IP 的站点,配置如下:
- 网站1.com
- 多个子域名(例如:foo.site1.com、bar.site1.com)
- 所有内容都在 80 端口上监听,443 端口上没有任何内容
- site2WithSSL.com
- 监听端口 80 和 443 (SSL)
我可以访问https://site2WithSSL.com并http://site1.com 没有问题。当有人想访问https://site1.com,nginx 使用 site2WithSSL.com 进行响应,我想避免这种情况。我的意思是,每当有人访问https://site1.com 无需返回任何内容,或者只需重定向到https://
配置如下:
server {
listen 80;
server_name *.site1.com;
// ...
}
server {
server_name www.site2WithSSL.com;
return 301 $scheme://site2WithSSL.com$request_uri;
}
server {
listen 80;
listen 443 ssl;
server_name site2WithSSL.com;
ssl_certificate site2WithSSL.crt;
ssl_certificate_key site2WithSSL.key;
// ...
}
已解决:每个网站使用不同的 IP
答案1
您的问题是 SSL 不支持同一 IP 上的多个虚拟主机。
当 NGINX 通过 HTTP/1.1 接收到新的连接时,请求包含一个 HOST 标头,指定要服务的虚拟主机(这是 1.1 中的重大变化,允许我们今天所知的虚拟主机)。
但是使用 HTTPS,标头是加密的,并且必须先建立密钥交换和 TLS 层才能解密。换句话说,nginx 无法选择正确的 SSL 服务器块,直到它发送了 SSL 证书之后。
您可以在 site2 的配置下添加与 site1 的域名匹配的重定向,但用户仍然会收到一条提示证书无效的消息,所以这不是很可接受的。
您可以使用一些多域证书,但这需要花费一些费用。
最简单、也是最适合您配置的选择是,为每个站点使用不同的 IP 地址。不同的 NGINX 服务器配置可以绑定到不同的地址,这样就永远不会有哪个是哪个的问题了。大多数提供商可以为您提供多个 IP 地址,有些甚至可以提供多个块,当然,在云端,您可以配置更多。
更新:SNI 通过将 Host 标头移到加密有效负载之外来解决此问题,并且受到现代浏览器的支持。
答案2
无法在同一 IP 上的端口 443 上只监听一个站点,因为它仅从 SSL 客户端 Hello 中知道客户端想要访问哪个站点。收到 Hello 后,客户端可以选择完成 SSL 握手或切断连接。在第一种情况下,您需要提供证书,在后一种情况下,客户端将收到有关 SSL 连接中断的一些无用错误。
最后可以归结为以下选项:
- 切断连接并在客户端导致一些奇怪的错误消息(我不知道是否可以使用 nginx 启用此行为)。
- 提供与 site2WithSSL.com 相同的证书,并将客户端重定向到 http-only。不幸的是,重定向将在 SSL 握手之后完成,并且此 SSL 握手将导致客户端出现错误,因为主机名与证书不匹配。
- 对 site1 使用自签名证书并重定向到 http-only:同样的问题,因为客户端不会接受该证书。
- 对 site1 使用真实的证书,即使您仅使用它来重定向到 http-only。
只有最后一个选项才可以在客户端正常运行且不会出现任何错误。
答案3
我正在考虑为 site1.com 配置监听 443 端口,不使用 SSL,只重定向到http://site1.com。我认为它应该可以工作而不需要新的 IP 地址。