SSL & Ngnix:在 SSL 握手时监听 SSL 端口的服务器中没有定义“ssl_certificate”

Rém*_*émi 31 ssl nginx lets-encrypt

我已经成功地使用 LE 创建了我的证书,没有错误,我还设法将我的流量从端口 80 重定向到端口 443。但是当我重新加载我的 nginx 服务器时,我无法访问我的网站。Ngnix 错误日志显示这一行:

4 no "ssl_certificate" is defined in server listening on SSL port while SSL handshaking, client: 192.168.0.104, server: 0.0.0.0:443
Run Code Online (Sandbox Code Playgroud)

我认为这意味着它找不到我然后导航到证书路径的证书,它们都在那里,可能是什么问题?这是我的 Ngnix 配置的样子:

server {
       listen         80;
       server_name    pumaportal.com www.pumaportal.com;
       return         301 https://$server_name$request_uri;
}

server {
    listen 443 ssl;

    server_name pumaportal.com www.pumaportal.com;

    add_header Strict-Transport-Security "max-age=31536000";

    ssl_certificate /etc/letsencrypt/live/pumaportal.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/pumaportal.com/privkey.pem;

    ssl_stapling on;
    ssl_stapling_verify on;

    access_log /var/log/nginx/sub.log combined;

    location /.well-known {
       alias /[MY PATH]/.well-known;
    }

    location / {
        proxy_pass http://localhost:2000;
        proxy_http_version 1.1;
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection 'upgrade';
        proxy_set_header Host $host;
        proxy_cache_bypass $http_upgrade;
        proxy_set_header X-Forwarded-For $remote_addr;
    }

}
Run Code Online (Sandbox Code Playgroud)

这一切似乎很简单,我不明白问题出在哪里。

运行 nginx -t 后一切正常:

nginx: the configuration file /etc/nginx/nginx.conf syntax is ok
nginx: configuration file /etc/nginx/nginx.conf test is successful
Run Code Online (Sandbox Code Playgroud)

C.A*_*uyk 34

我的猜测是您有另一台服务器在侦听端口 443。该服务器没有定义 ssl_certificate,它是自动选择的 (SNI)。尝试从 /etc/nginx/sites-enabled 中删除所有符号链接,除了您要工作的这台服务器(如果可能,否则请检查所有服务器是否在未正确配置的情况下侦听 443)。

  • 答对了!就我而言,我为 vhost mail.mydomain 创建了配置文件,因此我可以为我的 dovecot 安装构建一个 LE 证书,但忘记添加配置文件。 (2认同)
  • 或者只是为所有使用 ssl 的服务器定义一个 ssl_certificate。 (2认同)

Rev*_*Tim 12

我今天早上早些时候解决了这个同样的问题,所以我在这里澄清 CA 的观点(现在我理解了这个问题,这是很好的),你很可能有两个服务器块:

# 默认
服务器 {
    听 443 default_server; # 注意缺少`ssl`
    服务器名称 _;
    #...
}

#真实网站
服务器 {
    听 443 ssl;
    服务器名称 ;
    #...
}

SNI只会匹配那些标有ssl侦听器的对象。但是,默认服务器将获取443 上的所有传入流量,无论是否使用 SSL。因此,它实际上是通过为自己囤积所有流量来阻止 SNI 实际工作,立即生效。

症状:

  • nginx 似乎没有加载您的配置(即使nginx -t重新加载和服务)
  • 错误说明“在服务器块中找不到 ssl_certificate”
  • nginx 只是将您的主机应用于默认的 443 侦听器。

解决方案:

我今天早上通过删除默认服务器块解决了这个问题,因此允许 SNI 匹配 SSL 侦听器。

替代解决方案是将ssl侦听器和ssl_certificate行添加到服务器块,以便在您的默认主机上基本上启用 SNI。您仍然会遇到 SSL 错误,所以这不是最好的解决方案,但它会让您的 SNI 工作:)


小智 7

您需要default_server在 nginx 配置中定义一个参数。

适用default_server于任何example.com或www.example.com。不是都。

因此,这将起作用:

server {
    listen 443 ssl;
    listen 80;

    server_name example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 80 default_server;

    server_name www.example.com;
    return 301 https://www.example.com$request_uri;
}

server {
    listen 443 ssl default_server;

    server_name www.example.com;
    root /var/www/example.com/public;
    index index.php index.html index.nginx-debian.html;

    ssl on;
    ssl_certificate /etc/ssl/chain.crt;
    ssl_certificate_key /etc/ssl/examplecom.key;

    (rest of your nginx config goes here....)
}
Run Code Online (Sandbox Code Playgroud)

关于虚拟主机的注意事项:确保该default_server参数未在其他任何地方定义 - 如果服务器上有多个主机。