Using SELinux to force Linux to allow programs to bind to port numbers lower than 1024

11,512

Solution 1

Assuming you have a proper policy module for the application (let's call your app "foo") in place, you can do one of two things. You either define a foo_port_t type in the policy, allow you4 app access to it, like this:

allow foo_t foo_port_t:tcp_socket name_bind;

and the use something like this to label the actual port

semanage port -a -t foo_port_t -p tcp 803

This will claim TCP port 803 for your application. Most ports below 1023 already have labels on them though and you cannot label a port, file, whatever multiple times.

So option two: you can allow your app to bind to a port that has a different label, by putting lines like this into your policy module:

require { 
    type http_port_t;
}

allow foo_t http_port_t:tcp_socket name_bind;

This would allow you app to bind to any port that has http_port_t (meaning 80, 443, 488, 8008, 8009 and 8443). You can find what label the port (803 in this example) you want to use, has by this command:

semanage port -l | grep 803

Solution 2

It is not SELinux that does not allow your program to bind on privileged ports, it is the Linux kernel. More precisely CAP_NET_BIND_SERVICE capability.

You can do a port forwarding from the desired port to an unprivileged port and run the application on an unprivileged port. This is secure and allowed by SELinux.

Docker 20.3 updates kernel unprivileged port range to start at 0, as opposed to the default 1024. In this way CAP_NET_BIND_SERVICE is not required anymore to bind to ports less than 1024.

Solution 3

Run it as root or sudo it. You should only use root for testing, never in production. The kernel won't allow you to open a port below 1024 (well-known ports) without these permissions. It has nothing to do with SELinux but with the kernel.

Share:
11,512

Related videos on Youtube

PHGamer
Author by

PHGamer

Updated on September 17, 2022

Comments

  • PHGamer
    PHGamer almost 2 years

    Is there a way in SELinux to force linux to allow a program to be able to bind to a port number lower than 1024.

  • Mike
    Mike over 13 years
    You should never run processes as root if you can help it. This could lead to a much larger security issue than shutting down SELinux
  • Ignacio Vazquez-Abrams
    Ignacio Vazquez-Abrams over 13 years
    @Mike: Unless it's written to explicitly drop root privileges after startup.
  • Mike
    Mike over 13 years
    However if the process forks before it drops the root privileges, then you still have a security issue. Also what is the process going to do before it drops its privileges. Can you guarantee that it is going to do what you want? You are best to never run anything as the root user because you never know what the service is capable of.
  • Govindarajulu
    Govindarajulu about 13 years
    SELinux is very capable of blocking attempts of confined applications to bind to privileged ports. Yes, it can be the kernel, but it can be SELinux as well.
  • Bratchley
    Bratchley almost 11 years
    As an addendum on this point, you actually only need the binding program to have CAP_NET_BIND_SERVICE which is given its own capability to address the exact concern that you have with running a network program run as root
  • Brian
    Brian about 5 years
    These days, I recommend in Production to NOT disable SELinux due to security concerns. With RHEL, etc. now enable SELinux by default and it should not be disable so you have a new layer of protection.
  • Admin
    Admin about 2 years
    While it doesn't directly answer the OP's question, I think it's really what they want to achieve - the server (through a firewall rule) accepts connections at the low-numbered port and forwards to the internal high-numbered port that the unprivileged user account can use. It's a lot simpler than disabling stuff that should be left alone.
  • Admin
    Admin about 2 years
    Hi John. Thank you. I've updated the answer to reflect recent changes in Docker.