Jak zarezerwować porty dla mojej aplikacji?

29

Jak zarezerwować listę portów dla własnych aplikacji?

Mówiąc ściślej, produkt, który tworzę, ma wiele procesów i dużo komunikacji między nimi.

Problemem jest to, że - od czasu do czasu - system operacyjny kradnie moje porty. To rzadkie, ale się zdarza.

Może to być spowodowane tym, że inna aplikacja użyła „:: bind” bez określonego portu.

A czasem moje własne aplikacje kradną port, gdy wywołuję „:: connect” z niezwiązanym gniazdem. Jak widać ze strony podręcznika:

Jeśli gniazdo nie zostało już powiązane z adresem lokalnym, funkcja connect () powiąże go z adresem, który, chyba że rodziną adresów gniazda jest AF_UNIX, jest nieużywanym adresem lokalnym.

Więc moje pytanie brzmi: czy mogę zarezerwować porty, których potrzebuję, aby system operacyjny ich nie używał? Czy można tego dokonać za pomocą / etc / services? A może jest inny sposób?

Michael Baker
źródło
1
Czy zamiast tego można użyć gniazd AF_UNIX?
Alex
2
Bardziej martwi Cię, dlaczego Twoja aplikacja „kradnie porty”?
EightBitTony,
Zastanawiałem się, czy muszę przejść przez moje oprogramowanie i powiązać stronę klienta każdego połączenia z określonym portem. Aktualizowanie tego jest dla mnie zadaniem, ponieważ w moich aplikacjach jest wiele ścieżek połączeń. Zastrzeganie portów w systemie operacyjnym byłoby dobrym rozwiązaniem zatrzymania przerwy, dopóki nie znalazłem czasu, aby to zrobić.
Michael Baker
Nie jestem pewien, czy SELinuxw trybie wymuszania może spełnić twoje wymagania, wciąż się tego uczę. Więc tylko domyślać, może można zdefiniować własną politykę SELinuxdo rezerwy Twoi portów, takich jak my_server_port_t tcp 1111, 2222, 3333, 4444-4600. Jeśli Twoja aplikacja będzie działać wszędzie (nie aplikacja serwera), obawiam się, że nie możesz kontrolować, czy SELinuxjest WŁĄCZONA, czy WYŁĄCZONA.
LiuYan
Przez „kradzież” zakładam, że masz na myśli, że aplikacja innej firmy wiąże się z wybranym numerem portu, zanim aplikacja uzyska szansę, ponieważ aplikacja innej firmy zażądała powiązania z 0, a system operacyjny losowo przypisał wybrany numer portu do Aplikacja innej firmy. Jeśli tak, zobacz unix.stackexchange.com/a/38724/27865
Mark Lakata

Odpowiedzi:

14

Technicznie nie ma czegoś takiego jak „zarezerwowany port”.

W TCP / UDP jedynym sposobem na „zarezerwowanie” portu jest w rzeczywistości bind()gniazdo do niego. Powiązany port nie będzie używany przez inne aplikacje; nieużywany port jest, no cóż, nieużywany, więc inne aplikacje mogą z niego korzystać.

Jeśli piszesz oprogramowanie serwera, możesz powiązać gniazda z określonymi portami tak wcześnie, jak chcesz w kodzie aplikacji. Skonfiguruj numery portów lub przynajmniej wyraźnie je podaj w dokumentacji, aby administrator systemu mógł szybko zidentyfikować kolizje i przenieść sprzeczne aplikacje na osobne serwery.

Riccardo Murri
źródło
1
Ponadto, jeśli to możliwe, unikaj używania dobrze znanych / zarezerwowanych portów.
EightBitTony,
Czasami są zarezerwowane porty. To dobra ogólna rada, ale niepoprawna odpowiedź w systemie Linux.
Jason Newton
18

Aby upewnić się, że jądro nie przekaże 49000 i 49001 klientom, ponieważ chcesz ich używać na swoich serwerach w systemie Linux.

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

upuść to /etc/sysctl.conf , a następnie uruchom sysctl -p.

Pamiętaj, że jest to niesprawdzone.

Referencje

Hal Ashburner
źródło
Próbowałem tego, ale to również uniemożliwiło mojej aplikacji korzystanie z portów! Co z definiowaniem numerów portów z nazwami w /etc/services?
@ user134197 Nie powinno to uniemożliwiać Twojej aplikacji korzystania z tych portów, jeśli jawnie użyjesz niezerowego numeru portu w żądaniu powiązania. Mi to pasuje.
Mark Lakata
15

W rzeczywistości powyższa odpowiedź nie jest całkowicie dokładna. Sysctls net.inet.ip.portrange.first i net.inet.ip.portrange.last określają zakres portów, które system operacyjny może przydzielić dla portów losowych. Chcesz się upewnić, że zakres zarezerwowanych portów dla twojej aplikacji nie mieści się w tych zmiennych.

Zajrzyj do Podręcznika FreeBSD, sekcja: 12.14. Strojenie limitów jądra . Ale ta sama podstawowa przesłanka powinna dotyczyć również Linuksa.

MattK
źródło
Również ten link może być
pomocny
3
Myślę, że w Linuksie nazywa sięnet.ipv4.ip_local_port_range
Brian Gordon