更新:

更新:

我有一个 nginx 和不同的子域:

a.mydomain.com
b.mydomain.com
c.mydomain.com

Nginx 有 4 条规则:

1)重写规则:

server {
  listen 80
  server_name gl.udesk.org;

  root /nowhere;
  rewrite ^ https://a.mydomain.com$request_uri permanent;
}

2)https规则:

server {

  listen 443;
  server_name a.mydomain.com;

  root /home/a/a/public;

  ssl on;
  ssl_certificate conf.d/ssl/a.crt;
  ssl_certificate_key conf.d/ssl/a.key;
  ssl_protocols ...
  ssl_ciphers ...
  ssl_prefer_server_ciphers on;

  location ...
}

3)http默认规则:

server {
  listen 80 default_server;
  return 444;
}

4)https默认规则:

server {
  listen 443 default_server;
  return 444;
}

如果我启动 nginx 并且:

那么为什么 https 规则nginx配置起来非常棘手,我应该如何正确配置它们才能获得与 http 版本相同的行为?

更新:

创建新证书并添加:

ssl on;
ssl_certificate conf.d/ssl/default.crt;
ssl_certificate_key conf.d/ssl/default.key;

现在可以使用,但我有一个不需要任何 SSL 证书的解决方案。只需重置所有 https(端口 443)子域的所有连接,但https://a.mydomain.com 无需提供证书。

答案1

不要将端口 443 与 SSL 混淆!Nginx 完全与端口无关。您也可以通过端口 80 提供 https。现代 nginx 版本允许

listen 1234 ssl;

那么你就不需要这ssl on;条线了。

但是如果你想提供 https,你需要指定一个证书。当你的服务器将 http 请求重写为 https 请求时,它就会进入 https。

您收到协议错误,因为 SSL 握手是在任何其他操作之前完成的。因此return 444未达到目的。并且任何 SSL 握手都需要证书和私钥,以便将证书/私钥对提供给加密算法。

答案2

return指令是重写模块的一部分。如果你检查文档,您可能会看到它适用于请求。在 HTTPS 中,只有在握手完成后才能发出请求。

有一个功能请求:https://trac.nginx.org/nginx/ticket/195并提供了解决方法。

server {
    listen 443 ssl;
    server_name bbb.example.com;
    ssl_ciphers aNULL;
    ssl_certificate /path/to/dummy.crt;
    ssl_certificate_key /path/to/dummy.key;
    return 444;
}

答案3

我找到了答案Nginx 文档

SSL 连接是在浏览器发送 HTTP 请求之前建立的,nginx 并不知道所请求的服务器名称。因此,它可能只提供默认服务器的证书。

因此,您必须将 SSL 连接的默认证书配置为将首先用于请求的 default_server。之后,nginx 将搜索最佳匹配的 server_name 虚拟服务器并使用其配置。

此外,即使支持 SNI,您可能也需要为 default_server 设置 SSL 连接设置,因为匹配的服务器配置中的某些 SSL 设置将被忽略。我还不明白它是如何工作的,但 nginxssl_certificate从匹配的服务器配置和ssl_protocolsdefault_server 配置接收到客户端。

从 Nginx 1.19.4 开始,你可以使用ssl_reject_handshake指示:

server {
  listen               443 ssl;
  ssl_reject_handshake on;
}

相关内容