Hai bisogno di direttive di ascolto IPv4 e IPv6 separate in nginx?


72

Ho visto vari esempi di configurazione per la gestione di host virtuali IPv4 e IPv6 dual stack su nginx. Molti suggeriscono questo modello:

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

Per quanto posso vedere, questo raggiunge esattamente la stessa cosa di:

listen [::]:80 ipv6only=off;

Perché dovresti usare il primo? L'unico motivo che mi viene in mente è se hai bisogno di parametri aggiuntivi specifici per ciascun protocollo, ad esempio se volevi impostare solo deferredsu IPv4.


Considerato come nulla a che fare con la versione dello stack IP, è un'opzione TCP.
Xavier Lucas,

1
Certo, ma lo si imposta nelle listendirettive e le opzioni vengono applicate per host: coppia di porte.
Synchro,

Hum, non riesco davvero a immaginare un caso in cui vorresti farlo. Penso che l'unica ragione sia storica e Michael Hampton lo abbia inchiodato.
Xavier Lucas,

Risposte:


48

Questo è probabilmente l'unico motivo per cui potresti usare il precedente costrutto, in questi giorni.

La ragione per cui stai vedendo questo è probabilmente che il valore predefinito è ipv6onlycambiato in nginx 1.3.4. Prima di ciò, è fallito off; nelle nuove versioni di default on.

Questo accade interagire con l'opzione socket IPV6_V6ONLY su Linux e opzioni simili su altri sistemi operativi, i cui valori predefiniti non sono necessariamente prevedibili. Pertanto, prima del 1.3.4 era richiesto il costrutto precedente per assicurarsi che si stessero effettivamente ascoltando le connessioni su IPv4 e IPv6.

La modifica del valore predefinito di nginx ipv6onlygarantisce che il valore predefinito del sistema operativo per socket dual stack sia irrilevante. Ora, nginx si collega esplicitamente a IPv4, IPv6 o entrambi, senza mai dipendere dal sistema operativo per creare un socket dual stack per impostazione predefinita.

In effetti, le mie configurazioni standard nginx per la pre-1.3.4 hanno la prima configurazione e tutte le post-1.3.4 hanno la seconda configurazione.

Tuttavia, poiché associare un socket dual stack è una cosa solo per Linux, le mie configurazioni attuali ora assomigliano più al primo esempio, ma senza ipv6onlyset, per intenderci:

listen [::]:80;
listen 80;

4
Alcuni sistemi operativi non eseguono affatto doppi socket ipv4 e ipv6, come OpenBSD, quindi dovrai ascoltare due volte.
Justin Cormack,

@JustinCormack Sì, hai ragione, e l'ho preso in considerazione per un po 'di tempo. Non avevo aggiornato questo post fino ad ora.
Michael Hampton

1
listen localhost:8080;sembra ascoltare entrambi (1.12.2) e l'utilizzo proxy_pass http://localhost:8080equivarrebbe a bilanciare il carico tra :: 1 e 127.0.0.1 - Ho dovuto aggiungere una riga per ipv6 per ottenere l'ip reale nei registriset_real_ip_from 127.0.0.1; set_real_ip_from ::1; real_ip_header X-Forwarded-For;
Antony Gibbs

65

Se si ospitano più domini vhost con un'unica istanza Nginx, non è possibile utilizzare la singola direttiva di ascolto combinata

listen [::]:80 ipv6only=off;

per ciascuno di essi. Nginx ha una strana stranezza in cui è possibile specificare il ipv6onlyparametro una sola volta per ogni porta, altrimenti non si avvia. Ciò significa che non è possibile specificarlo per ciascun blocco del server di dominio vhost.

Come menzionato da Michael, a partire da Nginx 1.3.4, il ipv6onlyparametro viene impostato per default on.

Pertanto, se si desidera ospitare più domini su IPv4 e IPv6 con un singolo server Nginx, si è costretti a utilizzare due direttive di ascolto per ciascun blocco del server di dominio:

listen 80;
listen [::]:80; 

Inoltre, come menzionato Sander, l'utilizzo ipv6only=offha lo svantaggio che gli indirizzi IPv4 vengono tradotti in IPv6. Ciò può causare problemi se l'app esegue il controllo IP su blacklist come Akismet o StopForumSpam perché, a meno che non si compili in un livello di traduzione inversa, l'app controllerà la traduzione IPv6 dell'indirizzo IPv4 dello spammer, che non corrisponderà a nessuno degli indirizzi IPv4 in la lista nera.


2
Sì, è lo stesso di cui ho parlato deferrede altre direttive per protocollo. Sarebbe utile se potessero essere specificati separatamente dalla direttiva hear per il motivo che dici.
Synchro,

1
E il nocciolo della questione è che è necessario specificare la direttiva Listen per ciascun dominio separatamente. Altrimenti cosa succederebbe? sito funzionerebbe bene tramite ipv4 e tramite ipv6 mostrerebbe la pagina di benvenuto di nginx. ROFL
Silver Moon,

2
Grazie per la spiegazione approfondita! Stavo ottenendo un errore di confusione quando ho specificato ipv6only=offdue volte per la stessa porta. La tua risposta ha risolto il problema!

1
Inoltre, se si desidera utilizzare 2 vhosts entrambi ascoltando 443: listen 443; listen [::]:443;. L'utilizzo listen [::]:80 ipv6only=off;genererà un errore nginx che porta è già in uso
lukeaus

16

Con lo ipv6only=offstile di configurazione, gli indirizzi IPv4 potrebbero essere visualizzati come indirizzi IPv6 utilizzando gli indirizzi IPv6 mappati IPv4 (solo software), ad esempio in file di registro, variabili di ambiente (REMOTE_ADDR) ecc.


3
Sì, sono mostrati in questo modo.
Michael Hampton

2

Per quanto ne so (e secondo i documenti su http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), usando solo

listen 80;

... è sufficiente se si desidera canalizzare il traffico IPv4 e IPv6 sulla stessa porta.


1
Ciò è già stato stabilito e menzionato nella domanda. Si prega di vedere le altre risposte per la differenza.
Synchro

3
Non è stato per me, avevo bisogno di entrambi. wget e curl in caso di errore quando si utilizza ipv6 fino a quando non ho aggiunto la riga "hear [::]: 80 ipv6only = on;"
Basilio A
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.