35

How do I reserve a list of ports for my custom applications?

To be specific, the product I'm creating has a lot of processes and a lot of intercommunication between them.

The problem I'm having is that - every once in a while - the OS steals my ports. It's rare, but it happens.

This could be because a different application has used "::bind" with no port specified.

Or sometimes my own applications steal the port when I call "::connect" with an unbound socket. As seen from the man page:

If the socket has not already been bound to a local address, connect() shall bind it to an address which, unless the socket's address family is AF_UNIX, is an unused local address.

So my question is, can I reserve the ports that I need so the OS doesn't use them? Can this be accomplished with /etc/services? Or is there a different way?

  • 1
    Can you use AF_UNIX sockets instead? – alex Jun 23 '11 at 16:46
  • 2
    More worried why your own application is 'stealing ports'? – EightBitTony Jun 23 '11 at 17:04
  • I was debating if I need to go through my software and bind the client side of each connection to a specific port. It's quite the job for me to update this as there are a lot of connection paths in my applications. Reserving ports in the OS would have been a good stop gap solution until I found time to do this. – Michael Baker Jun 23 '11 at 21:31
  • I'm not sure if SELinux in Enforcing mode can meet your requirement, I'm still learning on it. So just a guess, maybe you can define your own policy for SELinux to reserve yours ports, such as my_server_port_t tcp 1111, 2222, 3333, 4444-4600. If your application will run everywhere (not a server application), I'm afraid you can't control whether SELinux is ON or OFF. – LiuYan 刘研 Jun 24 '11 at 01:58
  • By "stealing" I assume you mean that the 3rd party app is binding to your chosen port number before you application gets a chance, because the 3rd party app has requested to bind to 0 and the OS has randomly assigned your chosen port number to the 3rd party app. If so, see http://unix.stackexchange.com/a/38724/27865 – Mark Lakata Oct 16 '15 at 01:05

3 Answers3

28

To ensure the kernel won't give out 49000 and 49001 to clients as you wish to use them for your servers on linux.

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

drop it in /etc/sysctl.conf, and then run sysctl -p.

Note that this is untested.

References

slm
  • 369,824
  • 1
    I tried this, but it also prevented my own application from using the ports! What about defining the port numbers with names in /etc/services? –  Sep 14 '15 at 23:59
  • @user134197 This should not prevent your own application from using those ports if you explicitly use a non zero port number in your bind request. It works for me. – Mark Lakata Oct 16 '15 at 01:03
18

Technically, there's no such thing as a "reserved port".

In TCP/UDP, the only way to "reserve" a port is to actually bind() a socket to it. A bound port will not be used by other applications; an unused port is, well, unused so other applications are free to use it.

If you are writing server software, then you can bind your sockets to specific ports as early as you want in the application code. Make the port numbers configurable, or at least clearly state them in the documentation, so that a systems administrator can quickly identify clashes and move conflicting applications to separate servers.

16

Actually, the above answer is not entirely accurate. The sysctls net.inet.ip.portrange.first and net.inet.ip.portrange.last specify the range of ports the OS can allocate for random ports. You would want to make sure that the range of reserved ports for your application does not fall within these variables.

Take a look in the FreeBSD Handbook, section: 12.14. Tuning Kernel Limits. But the same basic premise should apply to Linux as well.

slm
  • 369,824
MattK
  • 286
  • Also, this link may be of assistance: http://stackoverflow.com/questions/913501/how-to-let-kernel-choose-a-port-number-in-the-range-1024-5000-in-tcp-socket-pr – MattK May 15 '12 at 19:51
  • 4
    I think in Linux it's called net.ipv4.ip_local_port_range – Rag Nov 06 '14 at 21:20