hosts virtuales basados ​​en nombres nginx en IPv6

44

Tengo un servidor nginx que sirve casi media docena de sitios web diferentes. Se ejecuta en un Linode que acaba de recibir soporte nativo de IPv6 (centro de datos de Dallas), y estoy tratando de configurar la mayoría de mis sitios para la operación de doble pila. Obtuve el primero en funcionamiento usando un subdominio solo IPv6 como este:

server {
    listen [::]:80 ipv6only=on;
    listen 80;

    server_name example.com ipv6.example.com;

    root /var/www/example.com/htdocs;

    #More stuff, including PHP, WordPress
}

Esto funciona muy bien: example.com es solo IPv4 (por ahora), e ipv6.example.com es solo IPv6 (principalmente allí para fines de prueba). Puedo ping6 ipv6.example.com, e incluso wget ipv6.example.comsin sudar, esto fue agradablemente indoloro (después de encontrar el "problema" con la forma en que nginx une a los hosts virtuales, lo que requiere el ipv6only=onargumento y las listendirectivas duales ).

Sin embargo, ahora estoy tratando de expandir esto para admitir mis otros dominios, comenzando con static.example.com; Sin embargo, cuando adopto el mismo enfoque que el anterior (las listendirectivas duales , incluido el ipv6only=onargumento), aparece el siguiente error al reiniciar nginx:

* Starting Nginx Server...
nginx: [emerg] a duplicate listen options for [::]:80 in /etc/nginx/sites-enabled/example.com.conf:3

Parece que quizás el método de enlace de nginx para IPv6 no permite hosts virtuales basados ​​en nombres. ¿Tendré que obtener direcciones IPv6 adicionales de mi host (no es un problema) y usar un alojamiento virtual basado en IP en IPv6 con un alojamiento virtual basado en nombre sobre IPv4? ¿O me falta una solución que permita que mis configuraciones permanezcan consistentes en ambas pilas?

Esperaba tener mi sitio completamente en la pila de IPv6 a tiempo para el Día Mundial de IPv6 , pero a menos que pueda aclarar esto rápidamente, es posible que no esté listo. No es un gran problema desde un punto de vista práctico, ninguno de mis sitios califica como una "organización importante" por ningún tramo de la imaginación, ¡pero ayúdame a salvar mi crédito geek!

Editado para agregar:

Gracias a la respuesta de @kolbyjack, ahora tengo un servidor web de doble pila totalmente funcional. Solo por razones de claridad, estoy editando la solución que me dio para que todos puedan ver claramente cuál es la respuesta.

Mi catchall vhost predeterminado tiene las siguientes listendirectivas:

listen 80 default_server;
listen 8080 default_server;
listen [::]:80 default_server ipv6only=on;
listen [::]:8080 default_server ipv6only=on;

No sé si el orden importa, pero ahí está. Luego, cada vhost adicional tiene las siguientes listendirectivas:

listen 80;
listen [::]:80;

(O 8080 para el que escucha en ese puerto en su lugar.) La parte importante aquí parece ser la falta total de argumentos adicionales en todas las listendirectivas de vhost por defecto, excepto las repeticiones ipv6only=on.

Nuevamente, ¡muchas gracias a @kolbyjack por la solución aquí!

Kromey
fuente
Con nginx 1.2.1 no tuve que especificar ipv6only=on. Sin embargo, todo lo demás permaneció igual, ¡gracias por esto!
BeepDog

Respuestas:

46

Solo necesita opciones de escucha en una declaración para un socket. En general, los pondría en la declaración que también incluye el indicador default_server, pero para algunas opciones, creo que puede configurarlos en cualquier directiva de escucha. Simplemente elimine ipv6only = on de todas las escuchas, excepto una.

kolbyjack
fuente
2
Espera, estoy confundido. Pensé que se requería al menos una directiva de escucha por declaración de servidor; de lo contrario, ¿cómo sabría nginx con qué bloque de servidor debe responder en qué puerto (s)? No lo mencioné anteriormente porque no lo creía relevante, pero tengo un servidor en 8080, el resto en 80, y tengo la intención de ofrecer 443 para una pareja tan pronto como termine de solucionarlo y luego obtener un certificado SSL.
Kromey
Bien, volviendo a mirar la documentación, parece que los sitios que se encuentran en el puerto 80 no necesitarán una directiva de escucha, solo una con la bandera default_server en mi servidor virtual de catchall. Sin embargo, esto sigue fallando para mi servidor en 8080, para el cual también uso un catchall predeterminado (el catchall está escrito simplemente para ignorar cualquier solicitud de un nombre de host que no haya configurado explícitamente en otro vhost).
Kromey
1
No estoy diciendo que elimine todas sus directivas de escucha. Simplemente elimine el indicador ipv6only = on de todos menos uno de ellos. Sin una directiva de escucha en cada servidor, por defecto solo escucharán 80; que puede o no incluir ipv6. Creo que el enfoque correcto es incluir ambas directivas de escucha en cada servidor, pero solo poner ipv6only = on en solo uno de los servidores.
kolbyjack
44
Ah, ahora veo a qué te refieres. Leí mal tu publicación originalmente. Esto me ha funcionado: ipv6only=onsolo aparece en la lista (para cada puerto en el que escucho) en mi vhost predeterminado (junto a default_server); cada vhost simplemente especifica listen 80;y listen [::]:80(sin parámetros adicionales) para funcionar tanto en IPv4 como en IPv6. Ahora todo lo que tengo que hacer es terminar de agregar los registros AAAA para mis dominios de doble pila, y debería ser bueno ir aquí. ¡Gracias!
Kromey
1
También funcionó para mí, pero no entiendo por qué nginx puede escuchar en ipv4 durante varios bloques, pero no ipv6. . puedes explicar ?
Adeerlike