Вам нужны отдельные директивы для прослушивания IPv4 и IPv6 в nginx?

Я видел различные примеры конфигурации для работы с виртуальными хостами с двумя стеками IPv4 и IPv6 на nginx. Многие предлагают эту модель:

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

Насколько я вижу, это достигается точно так же, как:

listen [::]:80 ipv6only=off;

Зачем тебе использовать первое? Единственная причина, о которой я могу подумать, - это если вам нужны дополнительные параметры, специфичные для каждого протокола, например, если вы хотите установить deferred на IPv4.

4 ответа

Решение

Вероятно, это единственная причина, по которой вы бы использовали прежнюю конструкцию в наши дни.

Причина, по которой вы это видите, заключается в том, что по умолчанию ipv6only изменено в nginx 1.3.4. До этого он по умолчанию off; в новых версиях по умолчанию on,

Это происходит во взаимодействии с опцией сокета IPV6_V6ONLY в Linux и аналогичными опциями в других операционных системах, значения по умолчанию которых не всегда предсказуемы. Таким образом, прежняя конструкция требовалась до 1.3.4, чтобы убедиться, что вы действительно прослушиваете соединения как на IPv4, так и на IPv6.

Изменение в nginx по умолчанию для ipv6only гарантирует, что операционная система по умолчанию для сокетов с двумя стеками не имеет значения. Теперь nginx либо явно привязывается к IPv4, IPv6, либо к обоим, независимо от того, какая ОС по умолчанию создает сокет с двумя стеками.

Действительно, мои стандартные конфигурации nginx для версии до 1.3.4 имеют первую конфигурацию, а все версии после 1.3.4 имеют вторую конфигурацию.

Хотя, поскольку привязка сокета с двумя стеками предназначена только для Linux, мои текущие конфигурации теперь больше похожи на первый пример, но без ipv6only установить, чтобы остроумно:

listen [::]:80;
listen 80;

Если вы размещаете несколько доменов vhost с одним экземпляром Nginx, вы не можете использовать одну объединенную директиву listen

listen [::]:80 ipv6only=off;

для каждого из них. Nginx имеет странную причуду, где вы можете указать только ipv6only параметр один раз для каждого порта, иначе он не запустится. Это означает, что вы не можете указать его для каждого блока сервера домена vhost.

Как упоминал Майкл, начиная с Nginx 1.3.4, ipv6only параметр по умолчанию равен on,

Поэтому, если вы хотите разместить несколько доменов на IPv4 и IPv6 на одном сервере Nginx, вы вынуждены использовать две директивы listen для каждого блока сервера домена:

listen 80;
listen [::]:80; 

Кроме того, как упомянул Сандер, используя ipv6only=off недостатком является то, что адреса IPv4 переводятся в IPv6. Это может вызвать проблемы, если ваше приложение выполняет проверку IP по черным спискам, таким как Akismet или StopForumSpam, потому что, если вы не создадите слой обратного перевода, ваше приложение будет проверять трансляцию IPv6 IPv4-адреса спаммера, который не будет совпадать ни с одним из IPv4-адресов в черный список.

С ipv6only=off В стиле конфигурации IPv4-адреса могут отображаться как IPv6-адреса с использованием (только программных) IPv4-сопоставленных IPv6-адресов, например, в файлах журналов, переменных среды (REMOTE_ADDR) и т. д.

Насколько я понимаю (и в соответствии с документами на http://nginx.org/en/docs/http/ngx_http_core_module.html), используя только

listen 80;

... достаточно, если вы хотите направить трафик IPv4 и IPv6 на один и тот же порт.

Одна неприятная проблема, с которой я столкнулся при добавлении поддержки IPv6 на сайт с listen [::]:80 ipv6only=off; фрагмент, был, когда я добавил его к vhost, а default_server уже был настроен для прослушивания обоих 80 и [::]:80.

nginx отказался запускаться, жалуясь, что адрес уже занят!

Замена магии listen [::]:80 ipv6only=off; с двумя традиционными listen линии позволяет nginx для начала просто отлично.

Так как listen [::]:80 ipv6only=off; может быть удобен при ручной настройке, может вызвать неприятные проблемы при использовании в системах автоматической настройки.

Другие вопросы по тегам