Port numbers below 1024 are reserved for superuser i.e. root so a normal user cannot bind to ports in this range. Privileged port ranges are defined in kernel source code file include/net/sock.h: #define PORT_SOCK 1024. Let’s understand the concept more in detail in the solution section.
- How to bind a privileged port below 1024 from a non-root user account?
- How to open ports below 1024 by a regular non-root user?
- How to start an application with a TCP/UDP port below 1024 by a non-root user?
- How to start HTTPD service by a non-root user?
- How to open TCP/UDP port 80/443 by a non-root account?
- Open network TCP/UDP ports below 1024 by non-root account.
- Getting permission denied while opening a port below 1024.
$ nc -l 80 Ncat: bind to 0.0.0.0:80: Permission denied. QUITTING.
There are two methods to open a privileged ports below 1024 by non-root user account.
- SetUID Bit
- Linux capabilities
Let’s understand the both methods in detail with the following exercises. In this article we’ll use netcat(NC) library for testing. You can replace any binary of your choice i.e. httpd, ftp, ssh, etc for testing.
Method 1: SetUID Bit
setuid and setgid are Unix access rights flags that allow users to run an executable C program or binary with the permissions of the executable binary’s original owner or group respectively instead of the user or account actually executing the program.
For example, /usr/bin/ncat is the executable binary and is owned by root account and user1 is the user who wants to execute that binary. After applying setuid bit to /usr/bin/ncat program file, if the user user1 executes /usr/bin/ncat program, that will run from the root users’s ownership instead of user1.
For security reason, Linux kernel has disabled setuid feature for shell scripts and this feature only works for C programs.
Execute the following command to apply setuid bit to /usr/bin/ncat program.
Make sure root user is the owner of /usr/bin/ncat program. If not found execute the following command. # chown root /usr/bin/ncat Execute the following command to set setuid bit. # chmod u+s /usr/bin/ncat List permission and ownership: # ls -l /usr/bin/ncat rwsr-xr-x. 1 root root 380184 Aug 9 06:46 /usr/bin/ncat
- Now execute the following command by the non-root user to open privileged TCP/UDP port below 1024. Here we’ll open TCP port 80 by a test user called test.
- Above output shows that program nc has opened TCP port 80 by root account instead of test user account. This is because SETUID bit allows the application to be executed with original user or owner’s privilege instead of the user executing the program.
Method 2: Linux capabilities
Starting with kernel 2.2, Linux divides the privileges traditionally associated with superuser into distinct units, known as capabilities, which can be independently enabled and disabled. Capabilities are a per-thread attribute.
Refer to the following upstream manual for the complete documentation on capabilities.
In order to allow a non-root account to open a privileged port, CAP_NET_BIND_SERVICE capability can be set to the executable program. Execute the following command to set cap_net_bind_service capability to /usr/bin/ncat binary.
Set capability # setcap cap_net_bind_service=+epi /usr/bin/ncat Get capability # getcap /usr/bin/ncat /usr/bin/ncat = cap_net_bind_service+eip
In the above command meaning of:
e: Effective: This means the capability is activated.
p: Permitted: This means the capability can be permitted.
i: Inherited: The capability is kept by child/sub-processes upon execve().
For more information refer to:
Now run the following command to open TCP port 80 by non-root user account test.