He visto varios ejemplos de configuración para manejar hosts virtuales IPv4 e IPv6 de doble pila en nginx. Muchos sugieren este patrón:
listen 80;
listen [::]:80 ipv6only=on;
Hasta donde puedo ver, esto logra exactamente lo mismo que:
listen [::]:80 ipv6only=off;
¿Por qué usarías el primero? La única razón por la que puedo pensar es si necesita parámetros adicionales que sean específicos para cada protocolo, por ejemplo, si solo desea establecer deferred
IPv4.
listen
directivas, y las opciones se aplican por host: par de puertos.Respuestas:
Esa es probablemente la única razón por la que usaría la construcción anterior, en estos días.
La razón por la que está viendo esto es probablemente porque el valor predeterminado de
ipv6only
cambiado en nginx 1.3.4. Antes de eso, el valor predeterminado eraoff
; en versiones más nuevas por defectoon
.Esto sucede para interactuar con la opción de socket IPV6_V6ONLY en Linux y opciones similares en otros sistemas operativos, cuyos valores predeterminados no son necesariamente predecibles. Por lo tanto, la construcción anterior se requería antes de 1.3.4 para garantizar que realmente estaba escuchando conexiones tanto en IPv4 como en IPv6.
El cambio al valor predeterminado de nginx
ipv6only
garantiza que el valor predeterminado del sistema operativo para los sockets de doble pila es irrelevante. Ahora, nginx se vincula explícitamente a IPv4, IPv6 o ambos, y nunca depende del sistema operativo para crear un socket de doble pila de forma predeterminada.De hecho, mis configuraciones nginx estándar para pre-1.3.4 tienen la primera configuración, y después de 1.3.4 tienen la segunda configuración.
Sin embargo, dado que vincular un socket de doble pila es algo exclusivo de Linux, mis configuraciones actuales ahora se parecen más al primer ejemplo, pero sin
ipv6only
establecer, a saber:fuente
listen localhost:8080;
parece escuchar a ambos (1.12.2) y usarproxy_pass http://localhost:8080
balance de carga entre :: 1 y 127.0.0.1 - Tuve que agregar una línea para ipv6 para obtener una IP real en los registrosset_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;
Si aloja varios dominios vhost con una sola instancia de Nginx, no puede usar la única directiva de escucha combinada
para cada uno de ellos Nginx tiene una peculiaridad extraña en la que solo puede especificar el
ipv6only
parámetro una vez para cada puerto, o no se iniciará. Eso significa que no puede especificarlo para cada bloque de servidor de dominio vhost.Como Michael mencionó, comenzando con Nginx 1.3.4, el
ipv6only
parámetro predeterminado eson
.Por lo tanto, si desea alojar múltiples dominios en IPv4 e IPv6 con un solo servidor Nginx, se ve obligado a utilizar dos directivas de escucha para cada bloque de servidor de dominio:
Además, como mencionó Sander, el uso
ipv6only=off
tiene el inconveniente de que las direcciones IPv4 se traducen a IPv6. Esto puede causar problemas si su aplicación verifica IP en listas negras como Akismet o StopForumSpam porque a menos que construya en una capa de traducción inversa, su aplicación verificará la traducción IPv6 de la dirección IPv4 del spammer, que no coincidirá con ninguna de las direcciones IPv4 en la lista negra.fuente
deferred
y otras directivas por protocolo. Sería útil si pudieran especificarse por separado de la directiva de escucha por la razón que usted dice.ipv6only=off
para el mismo puerto dos veces. ¡Tu respuesta resolvió el problema!listen 443; listen [::]:443;
. Usarlisten [::]:80 ipv6only=off;
arrojará un error nginx de que el puerto ya está en usoCon el
ipv6only=off
estilo de configuración, las direcciones IPv4 pueden mostrarse como direcciones IPv6 utilizando las direcciones IPv6 asignadas por IPv4 (solo software) en, por ejemplo, archivos de registro, variables de entorno (REMOTE_ADDR), etc.fuente
A mi entender (y de acuerdo con los documentos en http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), usando solo
... es suficiente si desea canalizar el tráfico IPv4 e IPv6 en el mismo puerto.
fuente