Wie reserviere ich Ports für meine Anwendung?

29

Wie reserviere ich eine Liste von Ports für meine benutzerdefinierten Anwendungen?

Um genau zu sein, das Produkt, das ich erstelle, hat viele Prozesse und eine Menge Interkommunikation zwischen ihnen.

Das Problem, das ich habe, ist, dass das Betriebssystem von Zeit zu Zeit meine Ports stiehlt. Es ist selten, aber es passiert.

Dies kann daran liegen, dass eine andere Anwendung ":: bind" verwendet hat, ohne dass ein Port angegeben wurde.

Oder manchmal stehlen meine eigenen Anwendungen den Port, wenn ich ":: connect" mit einem ungebundenen Socket aufrufe. Wie aus der Manpage ersichtlich:

Wenn der Socket noch nicht an eine lokale Adresse gebunden wurde, bindet connect () ihn an eine Adresse, die, sofern die Adressfamilie des Sockets nicht AF_UNIX ist, eine nicht verwendete lokale Adresse ist.

Meine Frage ist also, kann ich die benötigten Ports reservieren, damit das Betriebssystem sie nicht verwendet? Kann dies mit / etc / services erreicht werden? Oder gibt es einen anderen Weg?

Michael Baker
quelle
1
Können Sie stattdessen AF_UNIX-Sockets verwenden?
Alex
2
Noch besorgter, warum Ihre eigene Anwendung "Ports stiehlt"?
EightBitTony
Ich habe überlegt, ob ich meine Software durchgehen und die Clientseite jeder Verbindung an einen bestimmten Port binden muss. Es ist ziemlich meine Aufgabe, dies zu aktualisieren, da in meinen Anwendungen viele Verbindungspfade vorhanden sind. Das Reservieren von Ports im Betriebssystem wäre eine gute Zwischenlösung gewesen, bis ich Zeit gefunden hätte, dies zu tun.
Michael Baker
Ich bin mir nicht sicher, ob der SELinuxDurchsetzungsmodus Ihre Anforderungen erfüllen kann. Ich lerne immer noch dazu. Also nur eine Vermutung, vielleicht können Sie Ihre eigene Richtlinie definieren, um Ihre Ports SELinuxzu reservieren , wie z my_server_port_t tcp 1111, 2222, 3333, 4444-4600. Wenn Ihre Anwendung überall ausgeführt wird (keine Serveranwendung), können Sie leider nicht steuern, ob sie SELinuxaktiviert oder deaktiviert ist.
LiuYan 刘 研
Mit "stehlen" meine ich, dass die Drittanbieter-App an die von Ihnen gewählte Portnummer gebunden ist, bevor Ihre Anwendung eine Chance erhält, da die Drittanbieter-App eine Bindung an 0 angefordert hat und das Betriebssystem die von Ihnen gewählte Portnummer zufällig der zugewiesen hat Drittanbieter-App. Wenn ja, siehe unix.stackexchange.com/a/38724/27865
Mark Lakata,

Antworten:

14

Technisch gibt es keinen "reservierten Port".

In TCP / UDP besteht die einzige Möglichkeit, einen Port zu "reservieren", darin, tatsächlich bind()einen Socket dafür einzurichten. Ein gebundener Port wird von anderen Anwendungen nicht verwendet. Ein ungenutzter Port ist ungenutzt, so dass andere Anwendungen ihn verwenden können.

Wenn Sie Serversoftware schreiben, können Sie Ihre Sockets so früh wie im Anwendungscode gewünscht an bestimmte Ports binden. Machen Sie die Portnummern konfigurierbar oder geben Sie sie zumindest in der Dokumentation deutlich an, damit ein Systemadministrator Konflikte schnell identifizieren und widersprüchliche Anwendungen auf separate Server verschieben kann.

Riccardo Murri
quelle
1
Vermeiden Sie außerdem, wenn möglich, bekannte / reservierte Ports.
EightBitTony
Es gibt manchmal reservierte Ports. Dies ist ein guter allgemeiner Rat, aber unter Linux nicht die richtige Antwort.
Jason Newton
18

Um sicherzustellen, dass der Kernel keine 49000 und 49001 an Clients ausgibt, wie Sie sie für Ihre Server unter Linux verwenden möchten.

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

Lass es rein /etc/sysctl.confund renn dann los sysctl -p.

Beachten Sie, dass dies nicht getestet ist.

Verweise

Hal Ashburner
quelle
Ich habe es versucht, aber es hat auch verhindert, dass meine eigene Anwendung die Ports verwendet! Was ist mit der Definition der Portnummern mit Namen in /etc/services?
@ user134197 Dies sollte Ihre eigene Anwendung nicht daran hindern, diese Ports zu verwenden, wenn Sie in Ihrer Bindungsanforderung explizit eine Portnummer ungleich Null verwenden. Für mich geht das.
Mark Lakata
15

Tatsächlich ist die obige Antwort nicht ganz richtig. Die sysctls net.inet.ip.portrange.first und net.inet.ip.portrange.last geben den Bereich von Ports an, den das Betriebssystem für zufällige Ports zuweisen kann. Sie sollten sicherstellen, dass der Bereich der für Ihre Anwendung reservierten Ports nicht unter diese Variablen fällt.

Werfen Sie einen Blick in das FreeBSD-Handbuch, Abschnitt: 12.14. Optimieren der Kernel-Limits . Dieselbe Grundvoraussetzung sollte jedoch auch für Linux gelten.

MattK
quelle
Dieser Link kann auch hilfreich sein
MattK
3
Ich denke in Linux heißt esnet.ipv4.ip_local_port_range
Brian Gordon