Published on Oct 21 2011 in Java

Another error message that can be found in logs when trying to bind to a non-privileged port is java.net.BindException: Operation not permitted.

On a shared server this is usually avoided by binding application servers to non-privileged ports and proxying from HTTP (80) and HTTPS (443) ports to specific appservers using virtual host configuration directives. Within a VPS your application server like Tomcat or JBoss usually runs also as unprivileged user. This is the default setup made by JVM Host on request and also a security-wise recommended one. But still you may want and be able to bind to port 80 (this is also technically possible on a shared server if you have a dedicated IP assigned there).

If you run Apache as frontend you usually use mod_proxy, mod_proxy_ajp or mod_jk. See more on this in Mapping Apache to Tomcat and other application servers at JVM Host. Otherwise, if you want to bind your application server to e.g. port 80 or 443 by only modifying its configuration file you may get java.net.BindException: Permission denied:80.

Why? Because ports below 1024 can be opened only by root. Possible solutions are shown below.

iptables -I PREROUTING -t nat -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 8080

in /etc/rc.local or other file that is run at the end of boot process.

apt-get install authbind
touch /etc/authbind/byport/80
chown tomcat:tomcat /etc/authbind/byport/80
chmod 755 /etc/authbind/byport/80

Start your appserver as regular user

su - tomcat
authbind --deep $JAVA_HOME/bin/java ...
authbind --deep appservers/apache-tomcat-6.0.32/bin/startup.sh
setcap cap_net_bind_service+eip /opt/jdk1.6.0_23/bin/java
setcap cap_net_raw+eip /opt/jdk1.6.0_23/bin/java

This method does not require an executable to be setgid/setuid but has become ineffective with recent glibc changes. See more in Why setuid java programs don't work? Its a feature not a bug. article.