Я видел различные примеры конфигурации для обработки виртуальных хостов IPv4 и IPv6 с двойным стеком на nginx. Многие предлагают такую закономерность:
listen 80;
listen [::]:80 ipv6only=on;
Насколько я понимаю, это дает то же самое, что и:
listen [::]:80 ipv6only=off;
Зачем вам использовать первое? Единственная причина, по которой я могу думать, это то, что вам нужны дополнительные параметры, специфичные для каждого протокола, например, если вы хотите только установить deferred
на IPv4.
Если вы размещаете несколько доменов vhost с одним экземпляром Nginx, вы не можете использовать единую комбинированную директиву прослушивания
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
изменено в 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;
С ipv6only=off
стиль конфигурации: IPv4-адреса могут отображаться как IPv6-адреса с помощью (только программно) IPv4-сопоставленные адреса IPv6 в, например, файлах журнала, переменных среды (REMOTE_ADDR) и т. д.
Насколько я понимаю (и согласно документам на http://nginx.org/en/docs/http/ngx_http_core_module.html#listen), используя только
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;
может быть удобен при ручной настройке, может вызвать неприятные проблемы при использовании в системах автоматической настройки.