Comment réserver des ports pour mon application?

29

Comment réserver une liste de ports pour mes applications personnalisées?

Pour être précis, le produit que je crée a beaucoup de processus et beaucoup d'intercommunication entre eux.

Le problème que j'ai, c'est que - de temps en temps - le système d'exploitation vole mes ports. C'est rare, mais ça arrive.

Cela peut être dû au fait qu'une autre application a utilisé ":: bind" sans aucun port spécifié.

Ou parfois mes propres applications volent le port lorsque j'appelle ":: connect" avec un socket non lié. Comme vu sur la page de manuel:

Si le socket n'a pas déjà été lié à une adresse locale, connect () le liera à une adresse qui, à moins que la famille d'adresses du socket ne soit AF_UNIX, est une adresse locale non utilisée.

Ma question est donc la suivante: puis-je réserver les ports dont j'ai besoin pour que le système d'exploitation ne les utilise pas? Cela peut-il être accompli avec / etc / services? Ou existe-t-il une manière différente?

Michael Baker
la source
1
Pouvez-vous utiliser des sockets AF_UNIX à la place?
alex
2
Plus inquiet pourquoi votre propre application «vole des ports»?
EightBitTony
Je me demandais si je devais passer par mon logiciel et lier le côté client de chaque connexion à un port spécifique. C'est tout à fait le travail pour moi de mettre à jour cela car il y a beaucoup de chemins de connexion dans mes applications. Réserver des ports dans le système d'exploitation aurait été une bonne solution pour combler l'écart jusqu'à ce que je trouve le temps de le faire.
Michael Baker
Je ne sais pas si SELinuxen mode Enforcing peut répondre à vos besoins, j'apprends toujours dessus. Alors , juste une supposition, peut - être vous pouvez définir votre propre politique SELinuxde réserve ports vôtre, comme my_server_port_t tcp 1111, 2222, 3333, 4444-4600. Si votre application s'exécute partout (pas une application serveur), je crains que vous ne puissiez pas contrôler si elle SELinuxest activée ou désactivée.
LiuYan 刘 研
Par «voler», je suppose que vous voulez dire que l'application tierce est liée au numéro de port que vous avez choisi avant que votre application ait une chance, car l'application tierce a demandé de se lier à 0 et le système d'exploitation a assigné au hasard le numéro de port que vous avez choisi au Application tierce. Si oui, voir unix.stackexchange.com/a/38724/27865
Mark Lakata

Réponses:

14

Techniquement, il n'y a pas de "port réservé".

Dans TCP / UDP, la seule façon de "réserver" un port est en fait bind()un socket. Un port lié ne sera pas utilisé par d'autres applications; un port inutilisé est, eh bien, inutilisé afin que d'autres applications soient libres de l'utiliser.

Si vous écrivez un logiciel serveur, vous pouvez lier vos sockets à des ports spécifiques dès que vous le souhaitez dans le code d'application. Rendez les numéros de port configurables, ou du moins indiquez-les clairement dans la documentation, afin qu'un administrateur système puisse rapidement identifier les conflits et déplacer les applications en conflit sur des serveurs distincts.

Riccardo Murri
la source
1
Évitez également d'utiliser des ports bien connus / réservés si possible.
EightBitTony
Il y a parfois des ports réservés. C'est un bon conseil général mais pas la bonne réponse sous Linux.
Jason Newton
18

Pour vous assurer que le noyau ne distribuera pas 49000 et 49001 aux clients comme vous souhaitez les utiliser pour vos serveurs sous Linux.

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

déposez-le /etc/sysctl.conf, puis exécutez sysctl -p.

Notez que cela n'a pas été testé.

Les références

Hal Ashburner
la source
J'ai essayé, mais cela a également empêché ma propre application d'utiliser les ports! Qu'en est-il de la définition des numéros de port avec des noms /etc/services?
@ user134197 Cela ne devrait pas empêcher votre propre application d'utiliser ces ports si vous utilisez explicitement un numéro de port non nul dans votre demande de liaison. Ça marche pour moi.
Mark Lakata
15

En fait, la réponse ci-dessus n'est pas entièrement exacte. Les sysctls net.inet.ip.portrange.first et net.inet.ip.portrange.last spécifient la plage de ports que le système d'exploitation peut allouer pour des ports aléatoires. Vous devez vous assurer que la plage de ports réservés pour votre application ne tombe pas dans ces variables.

Jetez un œil dans le manuel FreeBSD, section: 12.14. Réglage des limites du noyau . Mais le même principe de base devrait également s'appliquer à Linux.

MattK
la source
En outre, ce lien peut être utile: stackoverflow.com/questions/913501/…
MattK
3
Je pense que sous Linux ça s'appellenet.ipv4.ip_local_port_range
Brian Gordon