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.
- You can redirect connections on port 80 to some other port using iptables. Place the line
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.
- Use authbind, for example modify an application server startup script to contain
authbind --deep
prefix. Install and configure authbind:
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
- [Obsolete] If your system supports capabilities and is old enough you can try to achieve the goal with CAP_NET_RAW, CAP_NET_BIND_SERVICE. See
man capabilities
.
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.
- [Least secure] Run
java
as root either directly or from a user account with sudo (you need to edit/etc/sudoers
in the latter case).