¿Cómo reservo puertos para mi aplicación?

29

¿Cómo reservo una lista de puertos para mis aplicaciones personalizadas?

Para ser específicos, el producto que estoy creando tiene muchos procesos y mucha intercomunicación entre ellos.

El problema que tengo es que, de vez en cuando, el sistema operativo me roba los puertos. Es raro, pero sucede.

Esto podría deberse a que una aplicación diferente ha usado ":: bind" sin ningún puerto especificado.

O, a veces, mis propias aplicaciones roban el puerto cuando llamo ":: connect" con un socket independiente. Como se ve desde la página del manual:

Si el socket no se ha vinculado a una dirección local, connect () lo vinculará a una dirección que, a menos que la familia de direcciones del socket sea AF_UNIX, sea una dirección local no utilizada.

Entonces mi pregunta es, ¿puedo reservar los puertos que necesito para que el sistema operativo no los use? ¿Se puede lograr esto con / etc / services? ¿O hay una manera diferente?

Michael Baker
fuente
1
¿Se pueden utilizar sockets AF_UNIX en su lugar?
alex
2
¿Más preocupado por qué su propia aplicación está 'robando puertos'?
EightBitTony
Estaba debatiendo si necesito revisar mi software y vincular el lado del cliente de cada conexión a un puerto específico. Es un buen trabajo para mí actualizar esto, ya que hay muchas rutas de conexión en mis aplicaciones. Reservar puertos en el sistema operativo habría sido una buena solución provisional hasta que encontré tiempo para hacerlo.
Michael Baker
No estoy seguro si SELinuxen el modo de cumplimiento puede cumplir con sus requisitos, todavía estoy aprendiendo sobre ello. Así que sólo una suposición, tal vez usted puede definir su propia política para SELinuxque encaje puertos suyo, tales como my_server_port_t tcp 1111, 2222, 3333, 4444-4600. Si su aplicación se ejecutará en todas partes (no en una aplicación de servidor), me temo que no puede controlar si SELinuxestá activada o desactivada.
LiuYan 刘 研
Al "robar" supongo que quiere decir que la aplicación de terceros se vincula al número de puerto elegido antes de que su aplicación tenga una oportunidad, porque la aplicación de terceros ha solicitado vincularse a 0 y el sistema operativo ha asignado aleatoriamente su número de puerto elegido al Aplicación de terceros. Si es así, consulte unix.stackexchange.com/a/38724/27865
Mark Lakata

Respuestas:

14

Técnicamente, no existe un "puerto reservado".

En TCP / UDP, la única forma de "reservar" un puerto es en realidad bind()un zócalo. Un puerto vinculado no será utilizado por otras aplicaciones; un puerto no utilizado es, bueno, no utilizado, por lo que otras aplicaciones pueden usarlo libremente.

Si está escribiendo software de servidor, puede vincular sus sockets a puertos específicos tan pronto como lo desee en el código de la aplicación. Haga que los números de puerto sean configurables, o al menos indíquelos claramente en la documentación, para que un administrador de sistemas pueda identificar rápidamente conflictos y mover aplicaciones en conflicto a servidores separados.

Riccardo Murri
fuente
1
Además, evite usar puertos conocidos / reservados si es posible.
EightBitTony
Hay puertos reservados a veces. Este es un buen consejo general, pero no es la respuesta correcta en Linux.
Jason Newton
18

Para garantizar que el kernel no distribuya 49000 y 49001 a los clientes, ya que desea utilizarlos para sus servidores en Linux.

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

déjalo caer /etc/sysctl.confy luego corre sysctl -p.

Tenga en cuenta que esto no se ha probado.

Referencias

Hal Ashburner
fuente
Intenté esto, ¡pero también impidió que mi propia aplicación usara los puertos! ¿Qué pasa con la definición de los números de puerto con nombres en /etc/services?
@ user134197 Esto no debería impedir que su propia aplicación use esos puertos si utiliza explícitamente un número de puerto distinto de cero en su solicitud de enlace. Esto funciona para mi.
Mark Lakata
15

En realidad, la respuesta anterior no es del todo precisa. Los sysctls net.inet.ip.portrange.first y net.inet.ip.portrange.last especifican el rango de puertos que el sistema operativo puede asignar para puertos aleatorios. Debería asegurarse de que el rango de puertos reservados para su aplicación no se encuentre dentro de estas variables.

Eche un vistazo en el Manual de FreeBSD, sección: 12.14. Tuning Kernel Limits . Pero la misma premisa básica debería aplicarse también a Linux.

MattK
fuente
Además, este enlace puede ser de ayuda: stackoverflow.com/questions/913501/…
MattK
3
Creo que en Linux que se llamanet.ipv4.ip_local_port_range
Brian Gordon