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