Host virtuali basati sul nome nginx su IPv6


44

Ho un server nginx che serve quasi mezza dozzina di siti Web diversi. Funziona su un Linode che ha appena ottenuto il supporto nativo IPv6 (Dallas Data Center) e sto cercando di configurare la maggior parte dei miei siti per operazioni dual-stack. Ho installato e funzionante il primo utilizzando un sottodominio solo IPv6 in questo modo:

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
}

Funziona benissimo: example.com è solo IPv4 (per ora) e ipv6.example.com è solo IPv6 (principalmente lì a scopo di test). Posso ping6 ipv6.example.com, e anche wget ipv6.example.comsenza sudare, questo è stato piacevolmente indolore (dopo aver trovato il "gotcha" con il modo in cui nginx lega gli host virtuali, richiedendo l' ipv6only=onargomento e le doppie listendirettive).

Tuttavia, ora sto cercando di espandere questo per supportare i miei altri domini, a partire da static.example.com; quando adotto lo stesso approccio di cui sopra, però (le doppie listendirettive, incluso l' ipv6only=onargomento), quando riavvio nginx ricevo il seguente errore:

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

Sembra che forse il metodo di nginx di associazione per IPv6 non consenta host virtuali basati sul nome? Dovrò ottenere ulteriori indirizzi IPv6 dal mio host (non un problema) e utilizzare l'hosting virtuale basato su IP su IPv6 con l'hosting virtuale basato su nomi su IPv4? O mi manca una soluzione che consenta alle mie configurazioni di rimanere coerenti su entrambi gli stack?

Speravo di avere il mio sito completamente sullo stack IPv6 in tempo per la Giornata mondiale IPv6 , ma a meno che non riesca a chiarire rapidamente ciò, potrei non essere pronto. Non è un grosso problema dal punto di vista pratico - nessuno dei miei siti si qualifica come una "grande organizzazione" da qualsiasi tratto dell'immaginazione - ma mi aiuta a salvare il mio credito geek!

Modificato per aggiungere:

Grazie alla risposta di @kolbyjack, ora ho un web server dual-stack perfettamente funzionante. Per motivi di chiarezza, sto modificando la soluzione che mi ha dato in modo che tutti possano vedere chiaramente quale sia la risposta.

Il mio vhost catchall predefinito ha le seguenti listendirettive:

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

Non so se l'ordine conta, ma è così. Quindi, ogni vhost aggiuntivo ha le seguenti listendirettive:

listen 80;
listen [::]:80;

(O 8080 per quello che invece ascolta su quella porta.) La parte importante qui sembra essere la totale mancanza di argomenti aggiuntivi su tutti tranne le listendirettive del vhost predefinito - cioè nessuna ripetizione di ipv6only=on.

Ancora una volta, grazie a @kolbyjack per la soluzione qui!


Con nginx 1.2.1 non ho dovuto specificare ipv6only=on. Tutto il resto è rimasto lo stesso, grazie per questo!
BeepDog,

Risposte:


46

Sono necessarie solo opzioni di ascolto su una dichiarazione per un socket. Generalmente li inseriresti nella dichiarazione che include anche il flag default_server, ma per alcune opzioni, penso che puoi semplicemente impostarli su una qualsiasi direttiva di ascolto. Basta rimuovere ipv6only = on da tutti gli ascoltatori tranne uno.


2
Aspetta, sono confuso. Ho pensato che fosse necessaria almeno una direttiva di ascolto per dichiarazione del server, altrimenti come farebbe nginx a sapere con quale blocco del server si intende rispondere su quale porta (e)? Non l'ho menzionato sopra perché non lo ritenevo rilevante, ma ho un server su 8080, il resto su 80 e intendo offrire 443 per una coppia, non appena lo avrò appianato e quindi procurami un certificato SSL.
Kromey,

Ok, guardando di nuovo la documentazione, i siti che si trovano sulla porta 80 sembrano non avere affatto bisogno di una direttiva di ascolto, solo uno con il flag default_server sul mio catchall vhost. Tuttavia, ciò non riesce ancora per il mio server su 8080, per il quale utilizzo anche un catchall predefinito (il catchall è scritto per ignorare semplicemente qualsiasi richiesta per un nome host che non ho configurato esplicitamente in un altro vhost).
Kromey,

1
Non sto dicendo di rimuovere tutte le direttive di ascolto. Basta rimuovere il flag ipv6only = on da tutti tranne uno. Senza una direttiva di ascolto in ciascun server, per impostazione predefinita saranno semplicemente in ascolto 80; che può includere o meno ipv6. Penso che l'approccio corretto sia quello di includere entrambe le direttive di ascolto in ciascun server, ma di inserire ipv6only = on solo in uno dei server.
kolbyjack,

4
Ah, capisco ora cosa intendi. Ho letto male il tuo post in origine. Questo ha funzionato per me: ipv6only=onè elencato (per ogni porta che ascolto) nel mio vhost predefinito (a fianco default_server); ogni vhost quindi specifica semplicemente listen 80;e listen [::]:80(nessun parametro aggiuntivo) funziona su IPv4 e IPv6. Ora tutto ciò che devo fare è terminare di aggiungere i record AAAA per i miei domini dual-stack e dovrei andare bene qui. Grazie!
Kromey,

1
ha funzionato anche per me, ma non capisco perché nginx possa ascoltare su ipv4 per più blocchi, ma non su ipv6. . Puoi spiegare ?
Adeerlike
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.