private support for your internal/customer projects ... custom extensions and distributions ... versioned snapshots for indefinite support ... scalability guidance for your apps and Ajax/Comet projects ... development services from 1 day to full product delivery
On Unix-based systems, port 80 is protected; typically only the superuser root can open it. For security reasons, it is not desirable to run the server as root. This page presents several options to access port 80 as a non-root user, including using ipchains, iptables, Jetty's SetUID feature, xinetd, and the Solaris 10 User Rights Management Framework.
On some Linux systems you can use the ipchains REDIRECT mechanism to redirect from one port to another inside the kernel (if ipchains is not available, then usually iptables is):
# /sbin/ipchains -I input --proto TCP --dport 80 -j REDIRECT 8080
This command instructs the system as follows: "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". Be aware that your kernel must be compiled with support for ipchains (virtually all stock kernels are). You must also have the ipchains command-line utility installed. You can run this command at any time, preferably just once, since it inserts another copy of the rule every time you run it.
On many Linux systems you can use the iptables REDIRECT mechanism to redirect from one port to another inside the kernel (if iptables is not available, then usually ipchains is).
You need to add something like the following to the startup scripts or your firewall rules:
# /sbin/iptables -t nat -I PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
The underlying model of iptables is different from ipchains, so the forwarding normally happens only to packets originating off-box. You 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 accepts the packet, otherwise the redirection won't occur. You can insert as many rules as required if your server needs to listen on multiple ports, as for HTTPS.
SetUID is a technique that uses Unix-like file system access right to allow users to run an executable that would otherwise require higher privileges.
Jetty's SetUID module allows you to run Jetty as a normal user even when you need to run Jetty on port 80 or 443. The module is hosted as part of the Jetty ToolChain project and it is released independently from Jetty itself (and as such it has a different version than Jetty releases). You can find the source code here, while the Maven coordinates are:
<dependency> <groupId>org.eclipse.jetty.toolchain.setuid</groupId> <artifactId>jetty-setuid-java</artifactId> </dependency>
Jetty's SetUID module provides an implementation for Linux and OSX.
Since the SetUID feature requires native code, you may need to build it for your environment.
In order to use Jetty's SetUID module, you need to copy file
jetty-setuid-java-<version>.jar
into
$jetty.home/lib
, and make sure that the native library file
(for Linux this file is called libsetuid-linux.so
) is present
in the native library path of the JVM (see also Configuring Jetty for SetUID).
Jetty's SetUID module also provides a default configuration file in the Jetty
XML format, in file jetty-setuid-java-<version>-config.jar
.
This file can be unjarred in $jetty.home/lib
and it will provide
a $jetty.home/etc/jetty-setuid.xml
file that you can customize.
Alternatively, follow the next section that specifies how to create a Jetty XML config
file for Jetty's SetUID.
Jetty SetUID module works by replacing the usual org.eclipse.jetty.server.Server
instance with a org.eclipse.jetty.setuid.SetUIDServer
instance.
Create a Jetty config file as follows:
<?xml version="1.0"?> <!DOCTYPE Configure PUBLIC "-//Mort Bay Consulting//DTD Configure//EN" "http://jetty.mortbay.org/jetty/configure_9_0.dtd"> <Configure id="Server" class="org.eclipse.jetty.setuid.SetUIDServer"> <Set name="umask">UMASK</Set> <Set name="uid">USERID</Set> </Configure>
where you replace:
UMASK with the umask
setting you want the process to have.
You must enter it in decimal. That is, if you want the effect of umask 022, you must enter
<Set name="umask">18</Set>
If you prefer octal, enter
<Set name="umaskOctal">022</Set>
You can remove this line if you don't want to change this the umask
at runtime.
Set it to 002 if you get an error to the effect that root does not have permission to write to the log file.
USERID with the ID of the user you want the process to execute as once the ports have been opened.
The easiest way to do this is to edit the
$jetty.home/start.ini
file:
uncomment --exec
add -Djava.library.path=lib/setuid
,
the path where the native library can be found
add an option for SetUID:
OPTIONS=Server,jsp,jmx,resources,websocket,ext,jta,plus,jdbc,annotations,setuid
add etc/jetty-setuid.xml
as the first
file in the configuration file section. This allows the Server
instance to be created
as org.eclipse.jetty.setuid.SetUIDServer
You must ensure that the
etc/jetty-setuid.xml
file is first in the list of
config files.
With modern Linux flavours, inetd
has a newer, better big brother
xinetd
, that you can use to redirect network traffic.
Since xinetd
is driven by text files, all you need is a text editor. For
detailed information, see http://www.xinetd.org/.
There are two ways to give xinetd
instructions:
Add a new service to etc/xinetd.conf
Add a new file to the directory
etc/xinetd.d
The format is the same; if you have a look at the file/directory, you will get the picture.
The following entry redirects all inward TCP traffic on port 80 to port 8888 on the local machine. You can also redirect to other machines for gimp proxying:
service my_redirector { type = UNLISTED disable = no socket_type = stream protocol = tcp user = root wait = no port = 80 redirect = 127.0.0.1 8888 log_type = FILE /tmp/somefile.log }
Be aware of the following:
Include a space on either side of the '=' or it is ignored.
type = UNLISTED
means that the name of the
service does not have to be listed in /etc/services
,
but then you have to specify port and protocol. If you want to do use an
existing service name, for example, http:
service http { disable = no socket_type = stream user = root wait = no redirect = 127.0.0.1 8888 log_type = FILE /tmp/somefile.log }
Have a browse in /etc/services
and it will all become
clear.
Logging might present certain security problems, so you might want to leave that out.
xinetd
is a hugely powerful and configurable system, so expect to
do some reading.
Solaris 10 provides a User Rights Management framework that can permit users and processes superuser-like abilities:
usermod -K defaultpriv=basic,net_privaddr myself
Now the myself
user can bind to port 80.
Refer to the Solaris 10 and Solaris 11 Security Services documentation for more information.
See an error or something missing? Contribute to this documentation at Github!