Você precisa de diretivas de escuta IPv4 e IPv6 separadas no nginx?


72

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 deferredIPv4.


Defendido como nada a ver com a versão da pilha IP, é uma opção TCP.
Xavier Lucas

11
Claro, mas você o define nas listendiretivas e as opções são aplicadas por host: par de portas.
Synchro 20/10

Hum, eu realmente não consigo imaginar um caso em que você queira fazer isso. Eu acho que a única razão é histórica e Michael Hampton acertou em cheio.
Xavier Lucas

Respostas:


48

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 ipv6onlyalterado no nginx 1.3.4. Antes disso, o padrão era off; 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 ipv6onlygarante 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 ipv6onlydefinir, com a saber:

listen [::]:80;
listen 80;

4
Alguns sistemas operacionais não executam soquetes duplos ipv4 e ipv6, como o OpenBSD, portanto, você precisará ouvir duas vezes.
Justin Cormack

@JustinCormack Sim, você está certo, e eu levo isso em conta há algum tempo. Só não tinha atualizado este post até agora.
Michael Hampton

11
listen localhost:8080;parece ouvir ambos (1.12.2) e usando proxy_pass http://localhost:8080iria 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;
Antony Gibbs

65

Se você hospedar vários domínios vhost com uma única instância Nginx, não poderá usar a diretiva de escuta combinada única

listen [::]:80 ipv6only=off;

para cada um deles. O Nginx possui uma peculiaridade estranha, na qual você pode especificar o ipv6onlyparâ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 ipv6onlyparâ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:

listen 80;
listen [::]:80; 

Além disso, como Sander mencionou, o uso ipv6only=offtem 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.


2
Sim, é o mesmo que mencionei deferred, e outras diretivas por protocolo. Seria útil se eles pudessem ser especificados separadamente da diretiva listen pelo motivo que você diz.
Synchro

11
E o cerne da questão é que você precisa especificar a diretiva de escuta para cada domínio separadamente. Caso contrário, o que aconteceria? o site funcionaria bem via ipv4 e via ipv6 mostraria a página de boas-vindas do nginx. ROFL
Silver Moon

2
Obrigado pela explicação completa! Eu estava recebendo um erro confuso quando especifiquei ipv6only=offa mesma porta duas vezes. Sua resposta resolveu o problema!

11
Além disso, se você quiser usar 2 vhosts ambos ouvindo 443: listen 443; listen [::]:443;. Usando listen [::]:80 ipv6only=off;irá lançar um erro nginx essa porta já está em uso
lukeaus


2

Para meu entendimento (e de acordo com os documentos em http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), usando apenas

listen 80;

... é suficiente se você deseja canalizar o tráfego IPv4 e IPv6 na mesma porta.


11
Isso já foi estabelecido e mencionado na pergunta. Por favor, veja as outras respostas para a diferença.
Synchro

3
Não era para mim, eu precisava dos dois. wget e curl em que falha ao usar o ipv6 até adicionar a linha "listen [::]: 80 ipv6only = on;"
Basil A
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.