nginx 重定向所有子域(不应该的时候)

问题描述 投票:0回答:4

我有一个正在运行的 nginx 服务器。我希望它将

http://www.example.com
重定向到
https://www.example.com
,但不要触及任何其他子域,例如
http://foo.example.com

由于某种原因,无论我在子域中添加什么,它仍然会被重新路由。我的网页显示在 www.example.com 上(理应如此),但也在 foo.example.com 和 example.com 上显示(理应如此)

这是我的 example.com 配置文件:

server {
  listen 80;
  server_name www.example.com;

  # For debug
  add_header X-debug-message "listen:80, server_name:www.example.com, redirect:https://$host$request_uri" always;

  # Riderect
  return 301 https://$host$request_uri;
}

server {
  listen 443 ssl;
  server_name www.example.com;

  # For debug
  add_header X-debug-message "listen:443, server_name:www.example.com, redirected:https://$host$request_uri" always;

  # SSL
  ssl_certificate /etc/letsencrypt/live/example.com/fullchain.pem;
  ssl_certificate_key /etc/letsencrypt/live/example.com/privkey.pem;
  include /etc/letsencrypt/options-ssl-nginx.conf;
  ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem;
  root /var/www/example.com;

  # Redirect
  location / {
    proxy_pass http://192.168.1.224:80;
  }
}

转到

www.example.com
会按预期显示我的网页。但是访问
foo.example.com
也会给我我的网页 - 但它不应该这样。
example.com
还给了我网页。

在浏览器中打开

www.example.com
,我看到以下 http 标头(如预期):

X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://www.example.com/

在浏览器中打开

foo.example.com
,我看到以下 http 标头(与预期不同):

X-debug-message: DEBUG: listen:443, server_name:www.example.com, redirected:https://foo.example.com/

我怎样才能让我的nginx只重定向

www.example.com

http nginx networking https nginx-reverse-proxy
4个回答
2
投票
  1. 确保 foo.yourdomain.com 的 dns 记录实际上是使用以下命令创建的 DNS 提供商

  2. 为子域“foo.example.com”创建第二个服务器块 否则所有请求都发送到端口 80 将被重定向到可用的服务器块,在您的情况下 www.example.com - 服务器块应如下所示:

         server {
            server_name foo.example.com;
            location / {
                 root path/to/foo/index.html;
                 index index.html index.htm;
                 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;
                 try_files $uri $uri/ /index.html;
            }
    
          listen 443 ssl; # managed by Certbot
          ssl_certificate 
          /etc/letsencrypt/live/example.com/fullchain.pem; # n 
            managed by Certbot
          ssl_certificate_key 
          /etc/letsencrypt/live/nextoma.com/privkey.pem; # managed by 
          Certbot
          include /etc/letsencrypt/options-ssl-nginx.conf; # managed by 
          Certbot
          ssl_dhparam /etc/letsencrypt/ssl-dhparams.pem; # managed by 
          Certbot
        }
    
  3. 使用以下命令将 ssl 证书添加到 foo.example.com:

    certbot --nginx -d foo.example.com
    
  4. 重新启动 nginx 并再次重新检查 foo.example.com


2
投票

您需要使第一个条目在 443 上监听 HTTPS 和服务器名称

_
并返回 404。

server {
        listen 443 ssl;
        server_name _;
        ssl_protocols       TLSv1 TLSv1.1 TLSv1.2;
        ssl_ciphers         HIGH:!aNULL:!MD5;
        ssl_certificate /etc/nginx/certs/nginx-selfsigned.crt;
        ssl_certificate_key /etc/nginx/certs/nginx-selfsigned.key;

        location / {
                return 404;
        }
}

通过在文件中使用典型的 HTTP 到 HTTPS 重定向(我将其作为最后一个条目):

server {
        listen 80 default_server;
        server_name _;
        return 301 https://$host$request_uri;
}

然后所有 HTTP 请求都会转换为 HTTPS 对应项。然后,如果您请求的子域尚未在 NGINX 配置文件中配置,它将默认为返回 404 的第一个条目。所有其他配置的子域和根域(如果您将其作为条目)将解析正确。

您还可以保留通配符 DNS,这比必须将每个子域添加为条目更实用,正如您在答案中指出的那样。


1
投票

谢谢大家的评论!

供其他读者和将来参考,这是我现在的开明理解。

nginx 将其启用站点配置中的第一个条目视为默认路由。因此,第一个条目

server {
    listen      80;
    server_name example.net www.example.net;
    ...
}

实际上被视为

server {
    listen      80 default_server;
    server_name example.net www.example.net;
    ...
}

所以,我的错误是将

*.example.com -> MyIP
添加到我的 DNS,并假设 nginx 只会
404
我没有明确定义的所有路由。事实上,它会查找与
foo.example.com
匹配的路由,如果不匹配,则将其路由到默认路由。

所以,我现在更改了 DNS 以显式处理我想要路由的所有子域,并在 nginx 中显式列出所有子域。

现在 - 我如何实现我最初的计划 - 将

*.example.com
路由到我的 IP,并让 nginx
404
除了我明确定义的请求之外的所有请求 - 我仍然不明白。

在 DNS 中显式路由所有子域的灵活性有点差,因为如果我想在内部测试新服务,我需要更新 DNS 并等待更改传播。但是,我想现在这样就可以了。


0
投票

要将除指定子域之外的所有子域路由到 404,您可以使用:

   server {
        listen 443 ssl http2;
        server_name *.domain.com;
        
        location / {
                return 404;
        }
  }
© www.soinside.com 2019 - 2024. All rights reserved.