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