Eu já vi vários exemplos de configuração para lidar com hosts virtuais IPv4 e IPv6 de pilha dupla no nginx. Muitos sugerem esse padrão:
listen 80;
listen [::]:80 ipv6only=on;
Tanto quanto eu posso ver, isso alcança exatamente o mesmo que:
listen [::]:80 ipv6only=off;
Por que você usaria o primeiro? A única razão pela qual consigo pensar é se você precisa de parâmetros adicionais específicos para cada protocolo, por exemplo, se você deseja apenas configurar o deferred
IPv4.
listen
diretivas e as opções são aplicadas por host: par de portas.Respostas:
Provavelmente, esse é o único motivo pelo qual você usaria a construção anterior atualmente.
A razão pela qual você está vendo isso provavelmente é que o padrão foi
ipv6only
alterado no nginx 1.3.4. Antes disso, o padrão eraoff
; nas versões mais recentes, o padrão éon
.Isso acontece ao interagir com a opção de soquete IPV6_V6ONLY no Linux e opções semelhantes em outros sistemas operacionais, cujos padrões não são necessariamente previsíveis. Portanto, a construção anterior era necessária antes da 1.3.4 para garantir que você realmente estivesse ouvindo conexões no IPv4 e no IPv6.
A alteração no padrão nginx para
ipv6only
garante que o padrão do sistema operacional para soquetes de pilha dupla seja irrelevante. Agora, o nginx se liga explicitamente ao IPv4, IPv6 ou a ambos, nunca dependendo do sistema operacional para criar um soquete de pilha dupla por padrão.De fato, minhas configurações padrão do nginx para pré-1.3.4 têm a primeira configuração e pós-1.3.4 têm a segunda configuração.
Porém, como vincular um soquete de pilha dupla é apenas para Linux, minhas configurações atuais agora se parecem mais com o primeiro exemplo, mas sem
ipv6only
definir, com a saber:fonte
listen localhost:8080;
parece ouvir ambos (1.12.2) e usandoproxy_pass http://localhost:8080
iria carregar equilíbrio entre :: 1 e 127.0.0.1 - Eu tive que adicionar uma linha para o IPv6 para obter IP real nos logsset_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;
Se você hospedar vários domínios vhost com uma única instância Nginx, não poderá usar a diretiva de escuta combinada única
para cada um deles. O Nginx possui uma peculiaridade estranha, na qual você pode especificar o
ipv6only
parâmetro apenas uma vez para cada porta, ou ele falhará ao iniciar. Isso significa que você não pode especificá-lo para cada bloco de servidor de domínio vhost.Como Michael mencionou, começando com o Nginx 1.3.4, o
ipv6only
parâmetro padrão éon
.Portanto, se você deseja hospedar vários domínios no IPv4 e no IPv6 com um único servidor Nginx, será forçado a usar duas diretivas de escuta para cada bloco do servidor de domínio:
Além disso, como Sander mencionou, o uso
ipv6only=off
tem a desvantagem de que os endereços IPv4 são convertidos para IPv6. Isso pode causar problemas se seu aplicativo verificar IP em listas negras como Akismet ou StopForumSpam, porque, a menos que você crie uma camada de conversão reversa, o aplicativo verificará a tradução IPv6 do endereço IPv4 do remetente de spam, que não corresponderá a nenhum dos endereços IPv4 em a lista negra.fonte
deferred
, e outras diretivas por protocolo. Seria útil se eles pudessem ser especificados separadamente da diretiva listen pelo motivo que você diz.ipv6only=off
a mesma porta duas vezes. Sua resposta resolveu o problema!listen 443; listen [::]:443;
. Usandolisten [::]:80 ipv6only=off;
irá lançar um erro nginx essa porta já está em usoCom o
ipv6only=off
estilo de configuração, os endereços IPv4 podem ser mostrados como endereços IPv6 usando os endereços IPv6 mapeados para IPv4 (somente software), por exemplo, arquivos de log, variáveis de ambiente (REMOTE_ADDR) etc.fonte
Para meu entendimento (e de acordo com os documentos em http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), usando apenas
... é suficiente se você deseja canalizar o tráfego IPv4 e IPv6 na mesma porta.
fonte