NGINX 默认使用其能找到的第一个 SSL server_block

NGINX 默认使用其能找到的第一个 SSL server_block

因此,我从中删除了默认的 vhost 配置/etc/nginx/sites-available/,因为我不需要捕获访问不存在的子域的用户(Debian 9)。

问题:当使用 https 调用随机子域时https://abc.example.com,nginx 将应用其默认行为并使用在我的配置文件中可以找到的第一个listen 443服务器块。这意味着,当用户错误地使用 https 访问虚假子域时,它不会收到 404 错误(就像调用时一样)abc.amazon.com或者abc.google.com),则会显示一个红色感叹号和certificate name missmatch错误(chrome ( NET::ERR_CERT_COMMON_NAME_INVALID)),这比可以理解的 404 错误要可怕得多。
问题:有没有办法禁用 nginx 使用它能找到的第一个 ssl 服务器块的默认行为?
哦,还有:即使重新创建默认虚拟主机(我复制了它的备份),NGINX 在使用 https 访问随机子域时也表现出相同的行为。此外,Firefox 将使用我的端口80服务器块将任何流量从 http 重定向到。Chrome 在调用随机子域时会将 http 重定向到 https,但保留子域(我从未指定过的规则)。以下是我目前使用的https://www.example.com$request_uri;2 个配置文件。/etc/nginx/sites-available/
默认(配置,更新

server {
    listen 80 default_server;
    listen [::]:80 default_server;
    server_name _;
    return 404;
}
server {
    listen 443 ssl default_server;
    server_name _;
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    return 444;
}

www.example.com(配置)

server {
    listen 80;
    listen [::]:80;
    server_name example.com www.example.com;
    include /etc/nginx/snippets/letsencrypt.conf;
    return 301 https://www.example.com$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_dhparam /etc/letsencrypt/live/example.com/dh.pem;
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header x-xss-protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    return 301 https://www.example.com$request_uri;
}
server {
    listen 443 ssl http2;
    listen [::]:443 ssl http2;
    server_name www.example.com;

    ssl on;
    ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
    ssl_session_timeout 1d;
    ssl_session_cache shared:SSL:50m;
    ssl_session_tickets off;
    ssl_dhparam /etc/letsencrypt/live/example.com/dh.pem;
    ssl_protocols TLSv1.2;
    ssl_ciphers 'ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256';
    ssl_prefer_server_ciphers on;
    ssl_stapling on;
    ssl_stapling_verify on;
    ssl_trusted_certificate /etc/letsencrypt/live/example.com/chain.pem;
    resolver 8.8.8.8;

    add_header X-Frame-Options "SAMEORIGIN";
    add_header x-xss-protection "1; mode=block" always;
    add_header X-Content-Type-Options "nosniff" always;
    add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

    root /var/www/www.example.com;
    index index.php;
    location ~ \.php$ {
            include snippets/fastcgi-php.conf;
            fastcgi_pass unix:/run/php/php7.0-fpm.sock;
    }

    location / {
            try_files $uri $uri/ =404;
    }
}

编辑:这些是我的 DNS 记录:

(HOST) *   (TYPE) A   (DESTINATION) MYIP
(HOST) @  (TYPE) A   (DESTINATION) MYIP
and some more for ftp, mail etc

我必须如何更改上述 DNS 才能仅包含我的子域(imap、webmail、www、smtp)?另外,以下预配置行的用途是什么?我必须将其更改为 imap.example.com 才能正常工作吗?(我没有邮件子域)

(HOST) @ (TYPE) MX (MX) 10 (DESTINATION) mail.example.com

答案1

... 用户错误地使用 https 访问了错误的子域...他将收到一个红色感叹号和一个证书名称不匹配错误(chrome(NET::ERR_CERT_COMMON_NAME_INVALID)),这比可以理解的 404 错误更可怕。
问题:有没有办法禁用这种默认的 nginx 行为,即使用它能找到的第一个 ssl 服务器块?

您尝试解决的问题实际上并不是由 nginx 默认使用第一个服务器块引起的。

问题在于,您没有与客户端请求的(子)域匹配的证书,或者您没有配置 nginx 在客户端访问此特定子域时提供此证书。这意味着 nginx 将无法向客户端提供与客户端访问的(子)域实际匹配的证书。

由于服务器证书必须与 URL 匹配是一项基本要求,因此客户端在所有情况下都会失败并显示一些可怕的错误消息:要么是因为证书中的主题与 URL 不匹配,要么是因为证书不是由受信任的 CA 颁发的(例如在默认块中使用自签名证书的情况下),或者是因为如果客户端尝试访问未配置的域(例如其他 Web 服务器可能出现的情况),服务器就会关闭连接。

答案2

我对 SSL 默认虚拟主机使用以下配置:

server {
    listen 443 ssl default_server;

    ssl_certificate /path/to/self-signed.crt;
    ssl_certificate_key /path/to/key;

    return 444;
}

return 444是特殊的 nginx 返回代码,会立即关闭连接。

客户端将看到有关连接问题的错误消息。当域没有合适的证书时,这是最好的办法。

相关内容