为什么nginx响应任何域名? [英] Why is nginx responding to any domain name?

查看:28
本文介绍了为什么nginx响应任何域名?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 Ruby/Sinatra 应用程序启动并运行了 nginx,一切正常.但是,我现在尝试在同一台服务器上运行第二个应用程序,我注意到一些奇怪的事情.首先,这是我的 nginx.conf:

I have nginx up and running with a Ruby/Sinatra app and all is well. However, I'm now trying to have a second application running from the same server and I noticed something weird. First, here's my nginx.conf:

pid /tmp/nginx.pid;
error_log /tmp/nginx.error.log;

events {
  worker_connections 1024;
  accept_mutex off;
}

http {
  default_type application/octet-stream;
  access_log /tmp/nginx.access.log combined;

  sendfile on;
  tcp_nopush on;
  tcp_nodelay off;

  gzip on;
  gzip_http_version 1.0;
  gzip_proxied any;
  gzip_min_length 500;
  gzip_disable "MSIE [1-6].";
  gzip_types text/plain text/xml text/css
             text/comma-separated-values
             text/javascript application/x-javascript
             application/atom+xml;

  upstream app {
    server unix:/var/www/app/tmp/sockets/unicorn.sock fail_timeout=0;
  }

  server {
    listen 80;
    client_max_body_size 4G;
    server_name FAKE.COM;

    keepalive_timeout 5;

    root /var/www/app/public;

    location / {
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header Host $http_host;
      proxy_redirect off;

      if (!-f $request_filename) {
        proxy_pass http://app;
        break;
      }
    }

    error_page 500 502 503 504 /500.html;
    location = /500.html {
      root /var/www/app/public;
    }
  }
}
                                                          68,0-1        B

注意如何将 server_name 设置为 FAKE.COM 而服务器正在响应通过其他域名访问该服务器的所有主机.我怎样才能让那个特定的服务器只响应对 FAKE.COM 的请求?

Notice how server_name is set to FAKE.COM yet the server is responding to all hosts that hit that server via other domain names. How can I make that particular server respond only to requests for FAKE.COM?

推荐答案

nginx 配置中的第一个服务器块是所有到达没有特定服务器块的服务器的请求的默认设置.

The first server block in the nginx config is the default for all requests that hit the server for which there is no specific server block.

因此在您的配置中,假设您的真实域是 REAL.COM,当用户输入时,它将解析到您的服务器,并且由于此设置没有服务器块,FAKE.COM 的服务器块,作为第一个服务器块(在您的情况下仅是服务器块),将处理该请求.

So in your config, assuming your real domain is REAL.COM, when a user types that in, it will resolve to your server, and since there is no server block for this setup, the server block for FAKE.COM, being the first server block (only server block in your case), will process that request.

这就是为什么正确的 Nginx 配置有一个特定的服务器块作为默认值,然后再跟随其他特定域的配置.

This is why proper Nginx configs have a specific server block for defaults before following with others for specific domains.

# Default server
server {
    return 404;
}

server {
    server_name domain_1;
    [...]
}

server {
    server_name domain_2;
    [...]
}

似乎有些用户对这个例子有点困惑,认为它仅限于单个 conf 文件等.

It seems some users are a bit confused by this example and think it is limited to a single conf file etc.

请注意,以上是OP根据需要进行开发的简单示例.

Please note that the above is a simple example for the OP to develop as required.

我个人使用单独的 vhost conf 文件(CentOS/RHEL):

I personally use separate vhost conf files with this as so (CentOS/RHEL):

http {
    [...]
    # Default server
    server {
        return 404;
    }
    # Other servers
    include /etc/nginx/conf.d/*.conf;
}

/etc/nginx/conf.d/ 将包含 domain_1.conf, domain_2.conf... domain_n.conf 将包含在主 nginx.conf 文件中的 server 块之后将始终是第一个并且始终是默认值,除非它在其他地方被 default_server 指令覆盖.

/etc/nginx/conf.d/ will contain domain_1.conf, domain_2.conf... domain_n.conf which will be included after the server block in the main nginx.conf file which will always be the first and will always be the default unless it is overridden it with the default_server directive elsewhere.

在这种情况下,其他服务器的 conf 文件的文件名的字母顺序变得无关紧要.

The alphabetical order of the file names of the conf files for the other servers becomes irrelevant in this case.

此外,这种安排提供了很大的灵活性,因为可以定义多个默认值.

In addition, this arrangement gives a lot of flexibility in that it is possible to define multiple defaults.

在我的特定情况下,我让 Apache 仅在内部接口上侦听端口 8080,并将 PHP 和 Perl 脚本代理到 Apache.

In my specific case, I have Apache listening on Port 8080 on the internal interface only and I proxy PHP and Perl scripts to Apache.

但是,我运行了两个单独的应用程序,它们都在附加的输出 html 中返回带有:8080"的链接,因为它们检测到 Apache 没有在标准端口 80 上运行并尝试帮助"我.

However, I run two separate applications that both return links with ":8080" in the output html attached as they detect that Apache is not running on the standard Port 80 and try to "help" me out.

这会导致链接失效的问题,因为无法从外部接口访问 Apache,链接应指向端口 80.

This causes an issue in that the links become invalid as Apache cannot be reached from the external interface and the links should point at Port 80.

我通过为端口 8080 创建默认服务器来重定向此类请求来解决此问题.

I resolve this by creating a default server for Port 8080 to redirect such requests.

http {
    [...]
    # Default server block for undefined domains
    server {
        listen 80;
        return 404;
    }
    # Default server block to redirect Port 8080 for all domains
    server {
        listen my.external.ip.addr:8080;
        return 301 http://$host$request_uri;
    }
    # Other servers
    include /etc/nginx/conf.d/*.conf;
}

由于常规服务器块中没有任何内容侦听端口 8080,重定向默认服务器块凭借其在 nginx.conf 中的位置透明地处理此类请求.

As nothing in the regular server blocks listens on Port 8080, the redirect default server block transparently handles such requests by virtue of its position in nginx.conf.

我实际上有四个这样的服务器块,这是一个简化的用例.

I actually have four of such server blocks and this is a simplified use case.

这篇关于为什么nginx响应任何域名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆