How do I use port 80 as a non root user?
On Unix based systems, port 80 is protected and can only be opened by
the superuser root. As it is not desirable to run the server as root (for
security reasons), the solution options are as follows
- Start Jetty as the root user, and use Jetty's setuid mechanism to switch to a non-root user after startup.
- Configure the server to run as a normal user on port 8080 (or some other non protected port).Then, configure the operating system to redirect port 80 to 8080 using ipchains, iptables, ipfw or a similar mechanism.
The latter has traditionally been the solution, however Jetty 6.1 has added the new setuid feature.
Using Jetty's setuid (and setumask) feature
Create a jetty config file like so:
Where you replace:
- UMASK with the umask setting you want the process to have, or optionally remove this line if you don't want to change this at runtime
- USERID with the id of the user you want the process to execute as once the ports have been opened.
Then, you need to build the setuid feature for your operating system, as it requires native libraries. Go to the $jetty.home/extras/setuid directory and follow the instructions in the README.txt file, summarized here as: Where:
For your convenience, you'll find one of these ready made in the $jetty.home/extras/setuid/etc/jetty-setuid.xml.
- $JDK_HOME is same as $JAVA_HOME
- linux should be replaced by the name of your operating system.
Then to run jetty as the root user, switching to the userid of your choice (and setting the umask of your choice if you chose to do that) you do:
Leave out the -shared argument.
You must ensure that the etc/jetty-setuid.xml file is first in the list of config files.
On some Linux systems the ipchains REDIRECT mechanism can be used to redirect from one port to another inside the kernel:
This basically means, "Insert into the kernel's packet filtering the following as the first rule to check on incoming packets: If the protocol is TCP and the destination port is 80, redirect the packet to port 8080." Your kernel must be compiled with support for ipchains. (virtually all stock kernels are.) You must have the "ipchains" command-line utility installed. (On RedHat the package is aptly named "ipchains".) You can run this command at any time, preferably just once since it inserts another copy of the rule every time you run it.
Once this rule is set up, a Linux 2.2 kernel will redirect all data addressed to port 80 to a server such as Jetty running on port 8080.This includes all RedHat 6.x distros. Linux 2.4 kernels, e.g. RedHat 7.1+, have a similar "iptables" facility.
You need to add something like the following to the startup scripts or your firewall rules:
The underlying model of iptables is different to that of ipchains so the forwarding normally only happens to packets originating off-box. You will also need to allow incoming packets to port 8080 if you use iptables as a local firewall.
Be careful to place rules like this one early in your "input" chain. Such rules must precede any rule that would accept the packet, otherwise the redirection won't occur. You can insert as many rules as needed if your server needs to listen on multiple ports, as for HTTPS.
On Solaris 10 (maybe earlier versions too) the OS allows you to grant privileged ports binding to "normal" users:
myself user will be able to bind to port 80.