//
// ========================================================================
// Copyright (c) 1995-2020 Mort Bay Consulting Pty Ltd and others.
//
// This program and the accompanying materials are made available under
// the terms of the Eclipse Public License 2.0 which is available at
// https://www.eclipse.org/legal/epl-2.0
//
// This Source Code may also be made available under the following
// Secondary Licenses when the conditions for such availability set
// forth in the Eclipse Public License, v. 2.0 are satisfied:
// the Apache License v2.0 which is available at
// https://www.apache.org/licenses/LICENSE-2.0
//
// SPDX-License-Identifier: EPL-2.0 OR Apache-2.0
// ========================================================================
//

[[setting-port80-access]]
=== Setting Port 80 Access for a Non-Root User

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.

[[using-ipchains]]
==== Using ipchains

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 `iptables` usually is):

[source, screen, subs="{sub-order}"]
----
# /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.

[[using-iptables]]
==== Using iptables

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:

[source, screen, subs="{sub-order}"]
----
# /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 outside of the server itself.
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.

[[configuring-jetty-setuid-feature]]
==== Configuring Jetty's SetUID Feature

http://en.wikipedia.org/wiki/Setuid[SetUID] is a technique that uses Unix-like file system access rights 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.

To use it with the Jetty distribution:

.  Ensure that you have the `http.mod` (and link:#quickstart-starting-https[https.mod] if you are using SSL) link:#startup-modules[modules enabled] for the link:#creating-jetty-base[base] you are using.
The `http.mod` is enabled by default in the distribution, while the link:#quickstart-starting-https[https.mod] is only enabled in the link:#demo-webapps-base[demo-base] directory.
.  Ensure that you have link:#quickstart-changing-jetty-port[changed the http port] to 80 (and link:#quickstart-changing-https-port[changed the https port] to 443 if you are using SSL).
.  Enable the `setuid.mod` module:
+
[source, screen, subs="{sub-order}"]
----
# java -jar start.jar --add-to-start=setuid
----
+
____
[NOTE]
The --add-to-start command will enable the setuid module for this and all subsequent executions of jetty.
There are other ways to enable the module, such as for a single execution.
For more information on the alternatives see the section on link:#startup-modules[Managing Startup Modules].
____

.  Edit the configuration for the `setuid` module to substitute the `userid` and `groupid` of the user to switch to after starting.
If your server instance has a `${jetty.base/start.d}` directory, this configuration is in the `start.d/setuid.ini` file instead.
Otherwise. this configuration is in the `${jetty.base}start.ini` file.

  Below are the lines to configure:
+
[source, text, subs="{sub-order}"]]
----
jetty.startServerAsPrivileged=false
jetty.username=foo
jetty.groupname=bar
jetty.umask=002
----
+
____
[NOTE]
As well as opening the connectors as `root`, you can also have Jetty start the Server as `root` before changing to the non-`root` user.
____

.  A native code library is required to perform user switching.
This code is hosted as part of the Jetty ToolChain project and is released independently from Jetty itself.
You can find the source code https://github.com/eclipsejetty.toolchain[here] in the https://github.com/eclipse/jetty.toolchain/jetty-setuid[jetty-setuid] project.
Build it locally, which will produce a native library appropriate for the operating system:
+
[source, screen, subs="{sub-order}"]
----
# mvn clean install
----
+
If you built on a linux machine you will find the native library in `jetty-setuid/libsetuid-linux/target/libsetuid-linux.so`.
If you built on a different operating system you will find the library in a different subdirectory, with the name containing the name of the operating system.
You may want copy this file into your Jetty distribution's lib directory.

.  Start Jetty as the `root` user in your base directory, providing the location of the native library to Java.
Below is an example of how to do it from the command line, assuming you are in the link:#demo-webapps-base[demo-base] directory:
+
[source, screen, subs="{sub-order}"]
----
# sudo java -Djava.library.path=libsetuid-linux -jar $JETTY_HOME/start.jar
----

[[using-solaris10-user-rights-management-framework]]

==== Using the Solaris 10 User Rights Management Framework

Solaris 10 provides a User Rights Management framework that can permit users and processes superuser-like abilities:

[source, screen, subs="{sub-order}"]
----
usermod -K defaultpriv=basic,net_privaddr myself
----

Now the `myself` user can bind to port 80.

Refer to the http://docs.oracle.com/cd/E23823_01/html/816-4557/prbactm-1.html#scrolltoc[Solaris 10] and http://docs.oracle.com/cd/E23824_01/html/821-1456/prbactm-1.html#scrolltoc[Solaris 11 Security Services documentation] for more information.
