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

问题描述

我已经启动nginx并使其与Ruby/Sinatra应用程序一起运行,一切都很好.但是,我现在试图在同一台服务器上运行第二个应用程序,但我发现有些奇怪.首先,这是我的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文件中的服务器块之后,它将始终是第一个,并且始终是默认值,除非它被其他位置的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没有在标准Port 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为什么响应任何域名?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

10-17 01:33