Hôtes virtuels basés sur des noms nginx sur IPv6

44

J'ai un serveur Nginx servant près d'une demi-douzaine de sites Web différents. Il fonctionne sur un Linode qui vient de recevoir un support natif IPv6 (centre de données de Dallas), et j'essaie de configurer la plupart de mes sites pour un fonctionnement en double pile. J'ai démarré le premier en utilisant un sous-domaine IPv6 uniquement, comme ceci:

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
}

Cela fonctionne très bien - exemple.com est uniquement IPv4 (pour le moment) et ipv6.example.com est uniquement IPv6 (principalement à des fins de test). Je peux le faire ping6 ipv6.example.com, et même wget ipv6.example.comsans que cela transpire - tout cela était agréable et sans douleur (après avoir trouvé le "piège" avec la façon dont nginx lie les hôtes virtuels, nécessitant ainsi l’ ipv6only=onargument et les listendirectives doubles ).

Cependant, j'essaie maintenant de développer cela pour prendre en charge mes autres domaines, en commençant par static.example.com; cependant, lorsque je prends la même approche que ci-dessus (les listendirectives doubles , y compris l' ipv6only=onargument), l'erreur suivante apparaît lors du redémarrage de nginx:

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

Il semble que la méthode de liaison de nginx pour IPv6 n'autorise pas les hôtes virtuels nommés? Devrai-je obtenir des adresses IPv6 supplémentaires de mon hôte (ce qui n'est pas un problème) et utiliser un hébergement virtuel IP sur IPv6 avec un hébergement virtuel nommé sur IPv4? Ou manque-t-il une solution qui permettra à mes configurations de rester cohérentes sur les deux piles?

J'espérais avoir mon site entièrement sur la pile IPv6 à temps pour la Journée mondiale IPv6 , mais à moins que je ne puisse éclaircir cela rapidement, je ne serai peut-être pas prêt. Pas un gros problème du point de vue pratique - aucun de mes sites ne peut être considéré comme une "organisation majeure" par un effort d'imagination - mais aidez-moi à sauver mon crédit de geek!

Édité pour ajouter:

Grâce à la réponse de @kolbyjack, j'ai maintenant un serveur Web à double pile entièrement fonctionnel. Par souci de clarté, je modifie la solution qu'il m'a proposée afin que tout le monde puisse voir clairement quelle est la réponse.

Mon catalogue par défaut vhost a les listendirectives suivantes :

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

Je ne sais pas si l'ordre compte, mais le voilà. Ensuite, chaque vhost supplémentaire a les listendirectives suivantes :

listen 80;
listen [::]:80;

(Ou 8080 pour celui qui écoute sur ce port à la place.) La partie importante ici semble être l'absence totale d'arguments supplémentaires sur toutes les listendirectives, à l'exception des directives par défaut de vhost - c'est-à-dire, aucune répétition de ipv6only=on.

Encore merci beaucoup à @kolbyjack pour la solution ici!

Kromey
la source
Avec nginx 1.2.1, je n'avais pas à spécifier ipv6only=on. Tout le reste est resté le même cependant, merci pour cela!
BeepDog

Réponses:

46

Vous n’avez besoin d’options d’écoute que sur une déclaration pour un socket. Généralement, vous les placeriez dans la déclaration qui inclut également l'indicateur default_server, mais pour certaines options, je pense que vous pouvez simplement les définir dans n'importe quelle directive d'écoute. Supprimez simplement ipv6only = on de toutes les écoutes sauf une.

kolbyjack
la source
2
Attends, je suis confus. Je pensais qu'au moins une directive d'écoute par serveur était requise - sinon, comment nginx saurait-il avec quel bloc de serveur est destiné à répondre sur quel (s) port (s)? Je n’en ai pas parlé plus haut parce que je ne pensais pas que ce soit pertinent, mais j’ai un serveur sur 8080, le reste sur 80, et j’ai l’intention d’offrir 443 pour un couple aussi dès que j’aurai réglé ce problème et puis me procurer un certificat SSL.
Kromey
Examinons à nouveau la documentation. Les sites qui se trouvent sur le port 80 ont l’impression qu’ils n’auront pas besoin d’une directive d’écoute, mais seulement d’une directive portant le drapeau default_server sur mon serveur incontrôlable. Cependant, cela échoue toujours pour mon serveur 8080, pour lequel j’utilise également un catchall par défaut (le catchall est écrit pour ignorer simplement les demandes de nom d’hôte que je n’ai pas explicitement configurées dans un autre vhost).
Kromey
1
Je ne dis pas de supprimer toutes vos directives d'écoute. Supprimez simplement le drapeau ipv6only = on de tous sauf un. Sans directive d’écoute sur chaque serveur, la valeur par défaut sera d’écouter 80; qui peut ou non inclure ipv6. Je pense que la bonne approche consiste à inclure les deux directives d'écoute sur chaque serveur, mais de ne mettre ipv6only = que dans un seul des serveurs.
Kolbyjack
4
Ah, je vois maintenant ce que vous voulez dire. J'ai mal lu votre message à l'origine. Cela a fonctionné pour moi: ipv6only=onest uniquement répertorié (pour chaque port sur lequel j'écoute) dans mon vhost par défaut (à côté default_server); chaque vhost spécifie alors simplement listen 80;et listen [::]:80(sans aucun paramètre supplémentaire) de fonctionner à la fois sur IPv4 et IPv6. Tout ce que j'ai à faire, c'est de finir d'ajouter les enregistrements AAAA pour mes domaines à double pile, et je devrais pouvoir y aller. Merci!
Kromey
1
a également fonctionné pour moi, mais je ne comprends pas pourquoi nginx peut écouter sur ipv4 plusieurs blocs, mais pas sur ipv6. . peux-tu expliquer ?
Adeerlike