¿Por qué nginx responde a cualquier nombre de dominio?

Tengo nginx en funcionamiento con una aplicación Ruby / Sinatra y todo está bien. Sin embargo, ahora trato de tener una segunda aplicación ejecutándose desde el mismo servidor y noté algo raro. Primero, aquí está mi 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 

Observe cómo server_name está configurado en FAKE.COM pero el servidor está respondiendo a todos los hosts que aciertan a ese servidor a través de otros nombres de dominio. ¿Cómo puedo hacer que ese servidor en particular responda solo a las solicitudes de FAKE.COM ?

El primer bloque de servidor en la configuración de nginx es el predeterminado para todas las solicitudes que llegan al servidor para el que no hay un bloque de servidor específico.

Entonces, en su configuración, suponiendo que su dominio real es REAL.COM, cuando un usuario lo ingrese, se resolverá en su servidor, y dado que no hay un bloque de servidor para esta configuración, el bloque de servidores para FAKE.COM, siendo el primero bloque de servidor (solo bloque de servidor en su caso), procesará esa solicitud.

Esta es la razón por la cual las configuraciones apropiadas de Nginx tienen un bloque de servidor específico para los valores predeterminados antes de seguir con otros para dominios específicos.

 # Default server server { return 404; } server { server_name domain_1; [...] } server { server_name domain_2; [...] } 

etc

** EDIT **

Parece que algunos usuarios están un poco confundidos por este ejemplo y piensan que está limitado a un único archivo conf, etc.

Tenga en cuenta que lo anterior es un ejemplo simple para que el OP se desarrolle según sea necesario.

Yo personalmente utilizo archivos vhost conf separados con esto como tal (CentOS / RHEL):

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

/etc/nginx/conf.d/ contendrá domain_1.conf, domain_2.conf … domain_n.conf que se incluirá después del bloque de servidor en el archivo nginx.conf principal, que siempre será el primero y siempre será el predeterminado a menos que se lo invalide con la directiva default_server en otro lugar.

El orden alfabético de los nombres de archivo de los archivos conf para los otros servidores pasa a ser irrelevante en este caso.

Además, esta disposición ofrece mucha flexibilidad en el sentido de que es posible definir múltiples valores predeterminados.

En mi caso específico, tengo Apache escuchando en el puerto 8080 solo en la interfaz interna y proxy scripts de PHP y Perl para Apache.

Sin embargo, ejecuto dos aplicaciones separadas que devuelven enlaces con “: 8080” en el html de salida adjunto, ya que detectan que Apache no se está ejecutando en el puerto 80 estándar e intentan “ayudarme”.

Esto causa un problema porque los enlaces se vuelven inválidos ya que no se puede acceder a Apache desde la interfaz externa y los enlaces deben apuntar al Puerto 80.

Resuelvo esto creando un servidor predeterminado para el Puerto 8080 para redirigir tales solicitudes.

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

Como nada en los bloques de servidores normales escucha en el puerto 8080, el bloque de servidor predeterminado redirigir maneja transparentemente tales solicitudes en virtud de su posición en nginx.conf.

De hecho, tengo cuatro de tales bloques de servidores y este es un caso de uso simplificado.

Debería tener un servidor predeterminado para catch-all , puede devolver 404 o mejor para no responder en absoluto (se ahorrará algo de ancho de banda) al devolver 444 que es una respuesta HTTP específica de nginx que simplemente cierra la conexión y no devuelve nada

 server { listen 80 default_server; server_name _; # some invalid name that won't match anything return 444; } 

No pude resolver mi problema con ninguna de las otras respuestas. Resolví el problema al verificar si el host coincidía y devolvía un 403 si no lo hacía. (Tenía un sitio web al azar que apuntaba al contenido de mi servidor web. Supongo que secuestro el rango de búsqueda)

 server { listen 443; server_name example.com; if ($host != "example.com") { return 403; } ... } 

Hay pocas formas de especificar el servidor predeterminado.

Primera forma : especifique primero el servidor predeterminado en la lista, si mantiene las configuraciones de su servidor en un archivo de configuración, como Dayo mostró anteriormente.

Segunda forma (mejor) Más flexible: proporcione el parámetro default_server para listen instrucciones, por ejemplo:

 server { listen *:80 default_server; root /www/project/public/; } 

Más información aquí: Nginx doc / Listen

De esta forma, es más útil cuando mantiene las configuraciones del servidor en archivos separados y no quiere nombrar esos archivos alfabéticamente.

Pequeño comentario para responder:

si tiene varios hosts virtuales en varias IP en varios archivos de configuración en sites-available /, entonces el dominio “predeterminado” para IP se tomará del primer archivo por orden alfabético.

Y como dijo Pavel, existe el argumento “default_server” para la directiva “listen” http://nginx.org/en/docs/http/ngx_http_core_module.html#listen

Para responder a su pregunta, nginx elige el primer servidor si no hay coincidencia. Ver documentación :

Si su valor no coincide con ningún nombre de servidor, o la solicitud no contiene este campo de encabezado, entonces nginx enrutará la solicitud al servidor predeterminado para este puerto. En la configuración anterior, el servidor predeterminado es el primero …

Ahora, si desea tener un servidor catch-all predeterminado que, por ejemplo, responda con 404 a todas las solicitudes, aquí le mostramos cómo hacerlo:

 server { listen 80 default_server; listen 443 ssl default_server; server_name _; ssl_certificate  ssl_certificate_key  return 404; } 

Tenga en cuenta que debe especificar el certificado / clave (que puede ser autofirmado), de lo contrario, todas las conexiones SSL fallarán, ya que nginx intentará aceptar la conexión utilizando este servidor predeterminado y no encontrará el certificado / clave.