Why run Tomcat on port 80?
description
Transcript of Why run Tomcat on port 80?
Running TomcatStand-alone on Port 80
Jason Brittain
Co-author of Tomcat: The Definitive Guide (O'Reilly)Software Architect, MuleSoft Tcat Server
Running Tomcat Stand-alone on Port 80: Reasons
- When you're not load balancing
- When you want Tomcat's full performance
- When you want straightforward easy configurations
- When the firewall needs it to actually be on port 80
(You can rename this presentation substituting any privileged port number, such as 443)
- When you need/want to serve directly from any port lower than 1024
Issues with running Java on privileged ports
- Windows: None. Windows works perfectly!
- Linux: Need special system user permission
- Solaris: Need special system user permission
- MacOS X: Need to be an administrator-class user (first user on the machine is the primary administrator)
Suboptimal Solutions
- Run Tomcat as root
- Run Tomcat "behind" Apache httpd or another web server, proxy everything
- Switch server operating systems to Windows
Generic Solutions- NAT port remapping: Map network packets
destined for 80 to Tomcat's unprivileged server port
- Superuser function overriding: Start the process as root, remap the server socket bind() function, then fork and setuid down to the Tomcat user
- Fine grained user permissions: Grant a fine-grained system user permission to allow the Tomcat user's JVM to open a privileged server port
Linux, Solaris, MacOS solution: jsvc
Starting:
# ./jsvc -user tomcat -home /usr/java/latest -wait 10 -pidfile /var/run/jsvc.pid -outfile /opt/tomcat/logs/catalina.out -errfile /opt/tomcat/logs/catalina.out -Dcatalina.base=/opt/tomcat -Dcatalina.home=/opt/tomcat -Dmore=props... org.apache.catalina.startup.Bootstrap start
Stopping:
# ./jsvc -stop -pidfile /var/run/jsvc.pid org.apache.catalina.startup.Bootstrap
Linux, Solaris, MacOS solution: jsvc Advantages
- Does not require any firewall rules to be changed
- Generic solution is multiplatform
- Zero server performance degredation
- Server lockup detection & auto JVM restarts
- Supports both IPv4 and IPv6
Linux, Solaris, MacOS solution: jsvc Disadvantages
- Requires starting Tomcat with sudo or as the root user
- Sometimes causes Tomcat JVM restart failures
- Can cause inadvertent/unintentional Tomcat JVM restarts
- Complicates Tomcat server startup scripting
- Native code, can't tar it up and move it to a different OS/architecture
Linux port 80 solution: iptables
# Remap packets coming from outside the machine.
iptables -t nat -I PREROUTING -p tcp --dst 192.168.1.100 --dport 80 -j REDIRECT --to-ports 8080
# Remap packets coming from inside the machine.
iptables -t nat -I OUTPUT -p tcp --dst 192.168.1.100 --dport 80 -j REDIRECT --to-ports 8080
Linux port 80 solution: iptables
- Happens in Linux Kernel space, not user space
- Highly efficient
- Layer 4 switching: Transport Layer of OSI model
- Does not require starting Tomcat with sudo nor as root
- Generic solution is multiplatform
- Well supported across Linux distributions
- Supports both IPv4 and IPv6
- Almost always preinstalled
Linux port 80 solution: iptables Disadvantages
- Requires sudo privilege or root to add the iptables rule(s)
- iptables is Linux-only, but similar tools exist on the other OSs
- Requires dealing with iptables "firewall" rules syntax
- Difficult to troubleshoot (network engineering)
Linux port 80 solution: authbind
# authbind --deep /bin/bash -c 'set -a; source "$DEFAULT"; $CATALINA_HOME/bin/catalina.sh start'
- Yet unassessed / unbenchmarked performance penalty
- On Debian and Ubuntu: Can be installed along with Tomcat as part of the OS
Linux port 80 solution: authbind Disadvantages
- GPL'd, and usually not preinstalled as part of the OS
- Requires starting Tomcat with sudo or as the root user
- Not a multiplatform solution, Linux-only
- IPv4 only
- APR connector doesn't necessarily work with it
- Ports from 512 to 1023 inclusive cannot be used
Linux port 80 solution: POSIX Capabilities
$ sudo -s
# yum install patchelf # Or download from http://nixos.org/patchelf.html
# export JAVA_HOME=/usr/java/jdk1.7.0
# patchelf --set-rpath $JAVA_HOME/jre/lib/i386/jli $JAVA_HOME/bin/java
# setcap 'cap_net_bind_service=+ep' $JAVA_HOME/bin/java
.. then run Tomcat as any user!
Linux port 80 solution: POSIX Capabilities
- Fine grained user permission for binding to privileged ports
- Seems like the "right way"
- Zero server performance degredation
- Does not require starting Tomcat with sudo nor as root
- Generic solution is multiplatform
- Well supported across Linux distributions
- Supports both IPv4 and IPv6
Linux port 80 solution: POSIX Capabilities Disadvantages
- Java 1.7 only (OpenJDK 1.7.0 EA works), 1.6 is broken http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6919633
- Doesn't work with alternate JVMs (JRockit & J9)
- Requires sudo privilege or root to enable bind capability via setcap
- Must install patchelf, or deploy only the patchelf-patched JDK binary
- JDK binaries not path movable after the change
Solaris port 80 solution: ipf
Edit ipnat.conf and add:
# Redirect port 80 to 8080
rdr eri0 1.2.3.4/32 port 80 -> 1.2.3.4 port 8080 tcp
Then run:
# ipfboot reload
Solaris port 80 solution: ipf Advantages
- Same as those of Linux iptables, but Solaris-only implementation
Solaris port 80 solution: ipf Disadvantages
- Requires sudo privilege or root to add the ipf rule(s)
- ipf is Solaris-only, but similar tools exist on the other OSs
- Requires dealing with ipf firewall rules syntax
- Difficult to troubleshoot (network engineering)
Solaris port 80 solution: User Privileges
# usermod -K defaultpriv=basic,net_privadd tomcat
.. then run Tomcat as user 'tomcat'.
- Same advantages as POSIX capabilities
Solaris port 80 solution: User Privileges Disadvantages
- Requires sudo privilege or root to enable bind capability via usermod
MacOS X port 80 solution: ipfw
$ sudo ipfw add 100 fwd 127.0.0.1,8080 tcp from any to any 80 in
- Same advantages as Linux iptables and Solaris ipf
- Same disadvantages as Linux iptables and Solaris ipf
LinksMuleSoft Tcat Server: Enterprise Tomcat Made Simple
http://www.mulesoft.com/tcat-server-enterprise-tomcat-application-server
Apache Commons Daemon: jsvc
http://commons.apache.org/daemon
privbind: Run unprivileged processes that can bind to privileged TCP/UDP ports
http://sf.net/projects/privbind
Links (continued)Is there a way for non-root processes to bind to privileged ports
lower than 1024 on Linux?
http://stackoverflow.com/questions/413807/is-there-a-way-for-non-root-processes-to-bind-to-privileged-ports-1024-on-linux
Using IPTables to Redirect Port 80 to Port 8080
http://rifers.org/wiki/display/RIFE/Installing+Tomcat+on+port+80+with+iptables
Bind ports below 1024 without root on GNU/Linux
http://www.wensley.org.uk/info#setpcaps
Links (continued)
Java doesn't support POSIX File Capabilities (A.K.A. Linux Capabilities)
http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=6919633
patchelf
http://nixos.org/patchelf.html