nginx - 为什么nginx响应任意域名?

标签 nginx

我已经启动了 nginx,并使用 Ruby/Sinatra 应用程序运行,一切都很好。但是,我现在尝试从同一服务器运行第二个应用程序,我注意到一些奇怪的事情。首先,这是我的 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 的请求?

最佳答案

nginx 配置中的第一个服务器 block 是所有到达没有特定服务器 block 的服务器的请求的默认值。

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

这就是为什么正确的 Nginx 配置在遵循特定域的其他配置之前具有默认的特定服务器 block 。

# Default server
server {
    return 404;
}

server {
    server_name domain_1;
    [...]
}

server {
    server_name domain_2;
    [...]
}

等等

** 编辑 **

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

请注意,上面是一个简单的示例,供OP根据需要进行开发。

我个人使用单独的虚拟主机配置文件(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 文件中的服务器 block 之后,其中永远是第一个,并且永远是默认值,除非它被其他地方的 default_server 指令覆盖。

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

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

在我的具体情况下,我让 Apache 仅在内部接口(interface)上监听端口 8080,并将 PHP 和 Perl 脚本代理给 Apache。

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

这会导致链接无效,因为无法从外部接口(interface)访问 Apache,并且链接应指向端口 80。

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

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;
}

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

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

关于nginx - 为什么nginx响应任意域名?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9824328/

相关文章:

nginx - rtmp 流的 ffmpeg 覆盖,fname 为空

docker - 在生产环境中部署使用docker构建的laravel时找不到404

django - Django 在带有 nginx 的 docker 上未使用静态文件

linux - 在没有 IP SAN 的情况下使用带有 SSL 证书的 Docker 注册表

ubuntu - Nginx 重定向 https ://www to https://

django - 使用 Django 将旧 URL 重定向到新 URL

php - 如何使用 NGINX 在 docker 中设置动态子域

python - 无法在同一服务器上运行 2 个不同的 Flask 应用程序

nginx - 在 Docker compose 配置中覆盖 nginx html 目录

python - 如何使用 format() 转义 nginx 关键字