Чому я можу відкрити з'єднання на порту 80 для 0.0.0.0, але не для інших форм?


0

Моє розуміння Linux / MacOS (я думаю, що вони однакові в цьому плані) дозволів на порти полягає в тому, що порти 1-1024 доступні тільки для root, але вище, вони доступні для всіх.

Однак я зіткнувся з деякою несподіваною поведінкою під час відкриття портів на MacOS 10.14.2. Я використовую php -S(версія 7.3.0) для експерименту.

Коли я запускаю команду у таких випадках:

127.0.0.1:80
[::1]:80
mylocalipv4:80
mylocalipv6:80

він повертається Failed to listen on ::1:80 (reason: Permission denied)як очікувалося (де показано вказаний IP / порт).

Однак, якщо я запускаю його 0.0.0.0:80, він успішно починає прослуховувати, але я не можу з'єднатись із цим завитком, використовуючи 127.0.0.1 або власне IP моєї машини.

Якщо я запускаю PHP-сервер, [::0]:80він успішно починає прослуховувати, і я можу його curl [::1]згортати з моєю локальною адресою ipv6.

Я б очікував, що останні два випадки не зможуть розпочатися з відмови у дозволі. Чому вони не стають?


Якщо macOS та Linux в цьому плані (нібито) однакові, це лише тому, що вони є ОС Unix. macOS насправді (спочатку) базується на версії BSD з мікроядром, тому припущення, що macOS та Linux є однаковими, в будь-якому відношенні може бути неточним. Я б це підтвердив в Інтернеті.
Стів Чемберс

Відповіді:


3

З тестування я бачу, що користувачі настільних комп'ютерів macOS можуть прив'язувати () номери TCP-портів до 1024 (так звані відомі порти). Він працює як на IPv4 і IPv6, так і на localhost / не вказані адреси.

Вихідний код ядра Дарвіна доступний у вільному доступі - звідти я бачу, що він має вбудований функціонал для перевірки процесів, які намагаються зв’язати / прослухати на портах <1024 та заперечувати це. Це схоже на те, як працює Linux. Однак можна відключити цю перевірку під час компіляції ядра шляхом визначення "IPNOPRIVPORTS". Я припускаю, що це було зроблено з ядром, що постачається Mojave.

У Linux раніше було так, що не-root не міг прив'язувати низькі номери портів, але сьогодні у вас є різні варіанти дозволу користувачам, які не користуються коренем, прив'язуватися до портів з низьким числом. Наприклад, наприклад, використовуючи можливість NET_BIND_SERVICE.

На macOS у вас також є різні варіанти обмеження прив'язки портів з невеликим числом. Наприклад, через кексти, які роблять фільтрацію сокетів, або за допомогою інших засобів. Можливо, у вас встановлено програмне забезпечення, наприклад, Little Snitch, яке позбавляло вас дозволу під час тестування.

Зауважте, що різні IP-адреси, з якими ви намагалися, мають абсолютно різні значення:

 127.0.0.1 = IPv4 address that means the "localhost" (i.e. your own computer basically) - it is not available on the network
 [::1]     = the IPv6 equivalent of 127.0.0.1

 0.0.0.0   = IPv4 "unspecified address" - i.e. this is not an address in itself, rather it is a special value you give to bind() to let it know that you haven't specified a specific address that you want the port bind() on. Essentially this means that the port will be bound on all the IP-addresses you have.
 [::0]     = IPv6 equivalent of 0.0.0.0 (though usually written [::/128])

Це може пояснити, чому деякі речі провалилися, а деякі вдалися. Наприклад, ви не зможете прив’язати до 127.0.0.1, але 0.0.0.0 працює, оскільки він намагається прив’язати порт не тільки до 127.0.0.1, але і до інших ваших IP-адрес.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.