Назад | Перейти на главную страницу

Виртуальные хосты nginx на основе имен на IPv6

У меня есть сервер 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 не вспотев - это было приятно безболезненно (после того, как мы обнаружили "ошибку" в том, как 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 у меня теперь есть полнофункциональный веб-сервер с двойным стеком. Для ясности я редактирую решение, которое он мне дал, чтобы все могли ясно увидеть ответ.

У моего кошачьего хоста по умолчанию есть следующие listen директивы:

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

Не знаю, имеет ли значение порядок, но вот он. Тогда каждый дополнительный виртуальный хост будет иметь следующий listen директивы:

listen 80;
listen [::]:80;

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

Опять же, большое спасибо @kolbyjack за решение здесь!

Вам нужны только параметры прослушивания в одном объявлении сокета. Обычно вы помещаете их в объявление, которое также включает флаг default_server, но для некоторых параметров, я думаю, вы можете просто установить их в любой одной директиве listen. Просто удалите ipv6only = on из всех прослушиваний, кроме одного.