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


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

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

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

listen [::]:80 ipv6only=off;

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


59
2017-10-20 16:26


Источник


Дефицит как ничего общего с версией IP-стека, это опция TCP. - Xavier Lucas
Конечно, но вы установили его в listen директивы и параметры применяются для пары хост: порт. - Synchro
Хм, я действительно не могу представить себе случая, в котором вы хотели бы это сделать. Я думаю, что единственная причина - историческая, и Майкл Хэмптон прибил ее. - Xavier Lucas


Ответы:


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

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

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

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

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

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

listen [::]:80;
listen 80;

35
2017-10-20 16:32



Некоторые операционные системы не используют двойные сокеты ipv4 и ipv6 вообще, как OpenBSD, поэтому для этого вам придется слушать дважды. - Justin Cormack
@JustinCormack Да, вы правы, и я принял это во внимание в течение некоторого времени. Просто не обновлял этот пост до сих пор. - Michael Hampton♦
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; - Antony Gibbs


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

listen [::]:80 ipv6only=off;

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

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

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

listen 80;
listen [::]:80; 

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


54
2018-04-24 10:10



Да, это то же самое, что я упоминал о deferred, и другие протоколы для протокола. Было бы полезно, если бы они могли быть указаны отдельно от директивы listen по причине, которую вы говорите. - Synchro
И суть в том, что вам нужно отдельно указывать директиву для каждого домена. Иначе что будет? сайт будет работать отлично через ipv4, и через ipv6 он отобразит страницу приветствия nginx. ROFL - Silver Moon
Спасибо за подробное объяснение! Я получал запутанную ошибку, когда я указал ipv6only=off для одного и того же порта дважды. Ваш ответ решил проблему! - Bruno Sutic
Также, если вы хотите использовать 2 vhosts, слушая 443: listen 443; listen [::]:443; , С помощью listen [::]:80 ipv6only=off; выдает ошибку nginx, что порт уже используется - luke_aus
Очень полезно, спасибо. - Basil A


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


12
2017-10-20 17:08



Да, они показаны таким образом. - Michael Hampton♦


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

listen 80;

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


1
2018-03-09 06:38



Это уже было установлено и упомянуто в вопросе. См. Другие ответы для разницы. - Synchro
Это не для меня, мне нужны были оба. wget и curl, где сбой при использовании ipv6 до тех пор, пока я не добавлю строку «listen [::]: 80 ipv6only = on;» - Basil A