Як зарезервувати порти для свого додатка?


29

Як зарезервувати список портів для своїх спеціальних програм?

Якщо конкретніше, продукт, який я створюю, має багато процесів і багато взаємозв'язку між ними.

Проблема, яка у мене виникає, полягає в тому, що - раз у раз - ОС краде мої порти. Це рідко, але буває.

Це може бути тому, що інша програма використовувала ":: bind" без вказаного порту.

Або іноді мої власні програми вкрадають порт, коли я дзвоню ":: connect" з незв'язаним сокетом. Як видно зі сторінки man:

Якщо сокет ще не прив’язаний до локальної адреси, connect () прив'язує його до адреси, яка, якщо сімейство адрес сокета не є AF_UNIX, не є невикористаною локальною адресою.

Отже, моє запитання полягає в тому, чи можу я зарезервувати потрібні мені порти, щоб ОС їх не використовувала? Чи можна це досягти за допомогою / etc / services? Або є інший спосіб?


1
Чи можете ви замість цього використовувати сокети AF_UNIX?
алекс

2
Більше хвилюєтесь, чому ваша власна програма «краде порти»?
EightBitTony

Я обговорював питання, чи потрібно мені переглядати програмне забезпечення та прив'язувати клієнтську частину кожного з'єднання до певного порту. Для мене цілком завдання оновити це, оскільки в моїх програмах є багато шляхів підключення. Резервування портів в ОС було б гарним рішенням для зупинки розривів, поки я не знайшов час для цього.
Майкл Бейкер

Я не впевнений, чи SELinuxв режимі Enforcing може відповідати вашим вимогам, я все ще навчаюсь цьому. Так тільки припущення, може бути , ви можете визначити свою власну політику SELinuxв резервне Yours портів, такі як my_server_port_t tcp 1111, 2222, 3333, 4444-4600. Якщо ваша програма працюватиме скрізь (а не серверна програма), я боюся, що ви не можете контролювати, чи SELinuxввімкнено або вимкнено.
LiuYan 刘 研

Під "крадіжкою" я припускаю, що ви маєте на увазі, що стороннє додаток прив'язує до обраного номера порту, перш ніж ваша програма отримає шанс, тому що стороннє додаток попросило прив’язати до 0, а ОС випадково призначила вибраний номер порту Додаток третьої сторони Якщо так, дивіться unix.stackexchange.com/a/38724/27865
Марк Лаката

Відповіді:


14

Технічно немає такого поняття, як "зарезервований порт".

У TCP / UDP єдиний спосіб "зарезервувати" порт - це фактично bind()сокет до нього. Зв'язаний порт не буде використовуватися іншими програмами; невикористаний порт - це не використовується, тому інші програми можуть ним користуватися.

Якщо ви пишете серверне програмне забезпечення, тоді ви можете прив’язати свої сокети до певних портів уже в коді програми. Зробіть номери портів настроюваними або принаймні чітко їх у документації, щоб системний адміністратор міг швидко ідентифікувати сутички та переміщувати суперечливі програми на окремі сервери.


1
Крім того, уникайте використання відомих / зарезервованих портів, якщо це можливо.
EightBitTony

Іноді є зарезервовані порти. Це хороша загальна порада, але не правильна відповідь у Linux.
Джейсон Ньютон

18

Щоб ядро ​​не видало 49000 та 49001 клієнтам, як ви хочете використовувати їх для своїх серверів під Linux.

sysctl -w net.ipv4.ip_local_reserved_ports = 49000, 49001

опустіть його /etc/sysctl.conf, а потім запустіть sysctl -p.

Зауважте, що це не перевірено.

Список літератури


Я спробував це, але це також завадило моєму додатку використовувати порти! Як щодо визначення номерів портів з іменами в /etc/services?

@ user134197 Це не повинно заважати вашій власній програмі використовувати ці порти, якщо ви явно використовуєте нульовий номер порту у своєму запиті на прив'язку. Це працює для мене.
Марк Лаката

15

Власне, наведена відповідь не зовсім точна. Sysctls net.inet.ip.portrange.first і net.inet.ip.portrange.last задають діапазон портів, які ОС може виділити для випадкових портів. Ви хочете переконатися, що діапазон зарезервованих портів для вашої програми не підпадає під ці змінні.

Ознайомтеся з посібником FreeBSD, розділ: 12.14. Налаштування лімітів ядра . Але та ж основна передумова повинна застосовуватися і до Linux.


Крім того , ця посилання може допомогти: stackoverflow.com/questions/913501 / ...
MattK

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