Running Tomcat on Privileged Ports

goober99

Matthew D. Miller

Posted on June 6, 2022

Running Tomcat on Privileged Ports

By default, Tomcat listens on port 8080 for HTTP and 8443 for HTTPS. If you want Tomcat to listen on the standard HTTP (80) and HTTPS (443) ports, it’s not easy, because ports below 1024 are considered privileged ports on Linux and only available to processes running as root. It’s a very (very!) bad idea to run Tomcat as root.

Reverse Proxy

You can configure a reverse proxy or load balancer like HAProxy to proxy port 443 to 8443.

  1. Install HAProxy (sudo yum install haproxy on Red Hat-derived distros and sudo apt install haproxy on Debian-derived distros).

  2. Start HAProxy and configure it to restart at boot.

    $ sudo systemctl start haproxy
    $ sudo systemctl enable haproxy
    
  3. Edit /etc/haproxy/haproxy.cfg and add:

    # Enable Access on 443 (SSL Passthrough)
    frontend tomcat-proxy
        mode            tcp
        bind            :443
        timeout client  5s
        default_backend tomcat
    
    backend tomcat
        mode            tcp
        timeout connect 5s
        timeout server  5s
        server          tomcat server.example.com:8443
    
  4. Modify the Tomcat server.xml and add proxyPort=443 to the <Connector>. The proxyPort attribute is used when Tomcat is run behind a proxy server. This attribute modifies the value returned to web applications that call the request.getServerPort() method, which is often used to construct absolute URLs for redirects. Without configuring this attribute, the value returned would reflect the port on which the connection from the proxy server was received, rather than the port to whom the client directed the original request. See Proxy Support in the Tomcat documentation for more info.

Authbind

The authbind utility allows a program that would normally require superuser privileges to access privileged ports to run as a non-privileged user. It allows a system administrator to permit specific users and groups access to bind to TCP and UDP ports below 1024.

  1. Install authbind. On Debian-derived distros, you can do this with sudo apt install authbind. It's not available in the repos of Red Hat-derived distros, but there is a pre-rolled RPM available. Download it and install with sudo yum *.rpm.

  2. Authorize the non-privileged user to access port 443. If you installed Tomcat from your distro's repos, it is probably run by the tomcat user.

    $ sudo touch /etc/authbind/byport/443
    $ sudo chmod 500 /etc/authbind/byport/443
    $ sudo chown tomcat /etc/authbind/byport/443
    
  3. Modify the Tomcat server.xml and configure Tomcat to listen to port 443.

  4. Prefix the command to start Tomcat with /usr/bin/authbind --deep. If you are using systemd to start Tomcat, your ExecStart would look something like this:

    ExecStart=/usr/bin/authbind --deep /opt/apache-tomcat-8.5.30/bin/startup.sh
    

    Normally authbind arranges for only the program which it directly invokes to be affected by its special version of bind. If you specify --deep, then all programs which that program invokes directly or indirectly will be affected, so long as they do not unset the environment variables set up by authbind.

Jsvc

Jsvc is a set of libraries and applications for making Java applications run on Unix more easily. According to the documentation, "Jsvc allows the application (e.g. Tomcat) to perform some privileged operations as root (e.g. bind to a port < 1024), and then switch identity to a non-privileged user." I tried it but was never able to get it to work, and documentation and examples online seem sparse, so I abandoned it.

💖 💪 🙅 🚩
goober99
Matthew D. Miller

Posted on June 6, 2022

Join Our Newsletter. No Spam, Only the good stuff.

Sign up to receive the latest update from our blog.

Related