Чи потрібні окремі директиви про прослуховування IPv4 та IPv6 у nginx?


71

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

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

Наскільки я бачу, це досягає точно такого ж, як:

listen [::]:80 ipv6only=off;

Для чого ти використовуєш колишнє? Єдина причина, про яку я можу подумати, - це якщо вам потрібні додаткові параметри, характерні для кожного протоколу, наприклад, якщо ви хотіли встановити deferredлише IPv4.


Запропонований як нічого спільного з версією стека IP - це варіант TCP.
Ксав'є Лукас

1
Звичайно, але ви встановлюєте це в listenдирективах, і параметри застосовуються на хост: пара портів.
Синхро

Хам, я справді не можу уявити собі випадок, коли ти хотів би це зробити. Я думаю, що єдина причина - це історична ситуація, і Майкл Гемптон прибив її.
Ксав'є Лукас

Відповіді:


48

Це, мабуть , стосується єдиної причини, по якій ти сьогодні використовуєш колишню конструкцію.

Причина, з якою ви це бачите, - це, ймовірно, у тому, що типова 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;

4
Деякі операційні системи взагалі не роблять подвійних сокетів ipv4 та ipv6, як OpenBSD, тому для цього вам доведеться прослуховувати двічі.
Джастін Кормак

@JustinCormack Так, ти маєш рацію, і я це враховував деякий час. Просто до цього часу не оновлювали цю публікацію.
Майкл Хемптон

1
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;
Ентоні Гіббс

65

Якщо ви розміщуєте кілька доменів 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-адрес у чорний список.


2
Так, це те саме, про що я згадував deferred, та інші директиви щодо протоколу. Було б корисно, якби вони могли вказати окремо від директиви про прослуховування з тієї причини, яку ви сказали.
Синхро

1
І суть справи полягає в тому, що вам потрібно вказати директиву прослуховування для кожного домену окремо. Інакше що б сталося? сайт буде добре працювати через ipv4, а через ipv6 він показуватиме сторінку вітання nginx. ROFL
Срібний Місяць

2
Дякую за ретельне пояснення! Я отримував заплутану помилку, коли ipv6only=offдва рази вказував на той самий порт. Ваша відповідь вирішила проблему!

1
Крім того, якщо ви хочете використовувати 2 ВХости слухають 443: listen 443; listen [::]:443;. Використання listen [::]:80 ipv6only=off;призведе до помилки nginx, що порт вже використовується
lukeaus

16

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


3
Так, вони показані таким чином.
Майкл Хемптон

2

Наскільки я розумію (і згідно з документами на веб-сторінці http://nginx.org/en/docs/http/ngx_http_core_module.html#listen ), використовуючи просто

listen 80;

... достатньо, якщо ви хочете каналізувати трафік IPv4 та IPv6 в одному порту.


1
Про це вже встановлено та згадувалося у питанні. Будь ласка, дивіться інші відповіді на різницю.
Синхро

3
Це не було для мене, мені потрібно було і те, і інше. wget and curl, де не вдалося використовувати ipv6, поки я не додав рядок "прослухати [::]: 80 ipv6only = on;"
Василь А
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.