1. Overview
In this tutorial, we’ll learn how to bind a non-root process to a privileged port on Linux.
We’ll begin by reviewing what privileged ports are and understanding how to define them. Then, we’ll look at a few methods to bind a regular process to a privileged port without running as root.
2. Binding Non-root Process to Privileged Port
In Linux, a privileged port is a port in the range 1-1023. By default, privileged ports can’t be bound to non-root processes.
Let’s see this in action by trying to listen on port 80 using netcat:
$ netcat -l -p 80
Error: Couldn't setup listening socket (err=-3)
In this example, we use netcat with the -l flag to listen for inbound connections and -p to specify the port we want to listen on (port 80). However, since this is a privileged port and we ran our command as a regular user, our command wasn’t successful.
There are methods that allow us to bind a regular process to a privileged port. Let’s look at them next.
2.1. By Program
To allow a specific program to bind to a privileged port, we’ll need to modify our program’s capabilities.
To accomplish this, let’s use the setcap command:
$ sudo setcap 'CAP_NET_BIND_SERVICE+ep' /usr/bin/netcat
In this example, we use the setcap command, with the first argument being the capability we want to modify and how we want to modify it.
In this case, the capability is CAP_NET_BIND_SERVICE, which is the capability allowing for a process to be bound to a privileged port. The next part of the string is +*ep which indicates we want to raise the capability to “*effective” and “permitted“. The last argument is the file we want to change capabilities for. For this example, we modify netcat.
Now we can bind netcat to a privileged port:
$ netcat -l -p 80
Our netcat command should now be listening on port 80 for incoming connections. To exit netcat, we can press Ctrl-c (^C).
If we want to disable /usr/bin/netcat from binding to a privileged port, we can re-run the setcap command:
$ sudo setcap 'CAP_NET_BIND_SERVICE' /usr/bin/netcat
In this example, we run the same setcap command as before, but we remove +ep so that our CAP_NET_BIND_SERVICE capability for /usr/bin/netcat is reset.
2.2. By Port
To allow a specific privileged port to be bound to by a user, we can use the authbind command. Since this program doesn’t come by default in most distributions, we’ll need to install it. We can do this using a package manager or by building from source.
After ensuring we have authbind installed, we can begin:
$ sudo touch /etc/authbind/byport/80
In this example, using the touch command, we create a file within the /etc/authbind/byport directory. Files created within this directory should correspond to the port number we want to allow access to, in this case, 80.
Any user with execute permissions on /etc/authbind/byport/80 will be able to use authbind to bind a program to port 80.
To change execute permissions on a file, we can use the chmod command:
$ sudo chmod +x /etc/authbind/byport/80
To give all users execute permissions for a file, we use chmod+x with the corresponding file we want to modify.
Now that we’ve created and modified the file, we can bind our program to the privileged port:
$ authbind netcat -l -p 80
All we have to do to use our program now is preface it with authbind. If we want to disable the use of a privileged port with authbind, we can remove the /etc/authbind/byport/80 file or remove its execute permissions.
3. Conclusion
In this article, we learned what a privileged port is. Then, we saw how to bind a non-root process to a privileged port.