Как зарезервировать порты для моего приложения?

29

Как зарезервировать список портов для моих пользовательских приложений?

Точнее говоря, продукт, который я создаю, имеет много процессов и много взаимосвязей между ними.

У меня проблема в том, что время от времени ОС крадет мои порты. Это редко, но это случается.

Это может быть потому, что другое приложение использовало ":: bind" без указания порта.

Или иногда мои собственные приложения крадут порт, когда я вызываю «:: connect» с несвязанным сокетом. Как видно из справочной страницы:

Если сокет еще не был привязан к локальному адресу, connect () должен связать его с адресом, который, если семейство адресов сокета не AF_UNIX, является неиспользуемым локальным адресом.

Поэтому мой вопрос: могу ли я зарезервировать нужные мне порты, чтобы ОС их не использовала? Можно ли это сделать с помощью / etc / services? Или есть другой способ?

Майкл Бейкер
источник
1
Вы можете использовать сокеты AF_UNIX вместо этого?
Алекс
2
Больше волнует, почему ваше собственное приложение «крадет порты»?
EightBitTony
Я спорил, нужно ли мне пройти через свое программное обеспечение и привязать клиентскую сторону каждого соединения к определенному порту. Я вполне могу обновить это, так как в моих приложениях много путей соединения. Резервирование портов в ОС было бы хорошим решением для остановки, пока я не нашел время для этого.
Майкл Бейкер
Я не уверен, что SELinuxв принудительном режиме может удовлетворить ваши требования, я все еще учусь на нем. Так только предположение, может быть , вы можете определить свою собственную политику 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.

MattK
источник
Кроме того, эта ссылка может быть
полезна
3
Я думаю, что в Linux это называетсяnet.ipv4.ip_local_port_range
Брайан Гордон