nginx віртуальних хостів на IPv6


44

У мене є сервер nginx, який обслуговує майже півдесятка різних веб-сайтів. Він працює на Linode, щойно отримав вбудовану підтримку IPv6 (центр даних Далласа), і я намагаюся налаштувати більшість моїх сайтів для роботи з двома стеками. Перший я запустився та запустив, використовуючи лише такий піддомен IPv6:

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
}

Це чудово працює - example.com призначений лише для IPv4 (поки що), а ipv6.example.com - лише для IPv6 (насамперед для тестування). Я можу ping6 ipv6.example.com, і навіть wget ipv6.example.comне порушуючи піт, - це було приємно безболісно (після знаходження "gotcha" з тим, як nginx зв'язує віртуальних хостів, необхідні ipv6only=onаргументи та подвійні listenдирективи).

Однак зараз я намагаюся розширити це для підтримки інших моїх доменів, починаючи з static.example.com; коли я використовую той же підхід, що і вище (подвійні listenдирективи, включаючи ipv6only=onаргумент), я отримую таку помилку при перезапуску nginx:

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

Здається, що, можливо, метод прив'язки nginx для IPv6 не дозволяє віртуальних хостів на основі імен? Чи доведеться мені отримувати додаткові адреси IPv6 від свого хоста (не проблема) та використовувати віртуальний хостинг на основі IP-адреси на IPv6 із віртуальним хостингом на основі іменованих даних через IPv4? Або я пропускаю рішення, яке дозволить моїм конфігураціям залишатися послідовними на обох стеках?

Я сподівався, що мій сайт буде повністю на стеку IPv6 вчасно до Всесвітнього дня IPv6 , але, якщо я не можу це швидко прояснити, можливо, я не буду готовий. Не велика справа з будь-якої практичної точки зору - жоден з моїх сайтів не розцінюється як "велика організація" з будь-якої ділянки уяви - але допоможіть мені зберегти мої рахунки на виглядів!

Відредаговано, щоб додати:

Завдяки відповіді від @kolbyjack, у мене є повністю функціональний веб-сервер з двома стеками. Просто задля ясності, я редагую рішення, яке він мені дав, щоб усі могли чітко бачити, що відповідає.

У моїй вигідній програмі catchall vhost є такі listenдирективи:

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

Я не знаю, чи має значення наказ, але є. Тоді кожен додатковий vhost має такі listenдирективи:

listen 80;
listen [::]:80;

(Або 8080 для того, хто слухає цей порт замість цього.) Важливою частиною тут є повна відсутність будь-яких додаткових аргументів для всіх, крім listenдиректив vhost за замовчуванням - тобто не повторення ipv6only=on.

Ще раз, велике спасибі @kolbyjack за рішення тут!


З nginx 1.2.1 не потрібно було вказувати ipv6only=on. Все інше залишилось колишнім, однак дякую за це!
BeepDog

Відповіді:


46

Вам потрібні лише варіанти прослуховування в одній декларації для сокета. Як правило, ви покладете їх на декларацію, яка також містить прапор default_server, але для деяких варіантів, я думаю, ви можете просто встановити їх на будь-яку директиву про прослуховування. Просто видаліть ipv6only = on зі всіх слухань, крім одного.


2
Зачекайте, я розгублений. Я подумав, що потрібно хоча б одна директива прослуховування на декларацію сервера - інакше як nginx дізнається, з яким блоком серверів потрібно відповідати на якому порту (портах)? Я не згадував це вище, тому що не вважав це актуальним, але у мене є один сервер на 8080, решта на 80, і я маю намір запропонувати 443 для пари так само, як тільки я отримаю це прасувати і то отримайте собі сертифікат SSL.
Kromey

Добре, ще раз переглянувши документацію, сайти, що перебувають на порту 80, виглядають так, що їм насправді взагалі не потрібна директива про прослуховування, лише один із прапором default_server на моїй програмі catchall vhost. Однак це все ще не вдається для мого сервера на 8080, для якого я також використовую catchall за замовчуванням (catchall написаний, щоб просто ігнорувати будь-які запити на ім’я хоста, я не налаштований явно в іншому vhost).
Кромей

1
Я не говорю видаляти всі ваші директиви про прослуховування. Просто видаліть прапор ipv6only = on з усіх, крім одного з них. Без директиви прослуховування на кожному сервері вони за замовчуванням просто прослуховують 80; який може включати або не включати ipv6. Я думаю, що правильний підхід полягає в тому, щоб включити обидві директиви прослуховування на кожному сервері, але лише поставити ipv6only = on лише на одному з серверів.
колб'як

4
А, я бачу, що ти маєш на увазі. Я спочатку неправильно прочитав вашу публікацію. Це спрацювало для мене: ipv6only=onвказано лише (для кожного порту, який я слухаю) у моєму vhost (поряд default_server); Кожен vhost потім просто вказує listen 80;та listen [::]:80(без додаткових параметрів взагалі) функціонувати як на IPv4, так і на IPv6. Тепер все, що мені потрібно зробити, це закінчити додавання записів AAAA для моїх доменів з двома стеками, і я повинен бути хорошим, щоб зайти сюди. Дякую!
Кромей

1
працював і для мене, але я не розумію, чому я nginx може слухати на ipv4 для декількох блоків, але не ipv6. . ти можеш пояснити ?
Adeerlike
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.