Running Tomcat on a privileged port used to be as simple as modifying the connector in Tomcat’s server.xml file. However, that meant running Tomcat as root — leaving open the possibility of privilege escalation and system compromise should exploitable vulnerabilities exist. As of Tomcat 6.0.24, the Debian/Ubuntu package includes some changes in the way Tomcat starts, including how it binds to privileged ports.
The installation of the tomcat6 package also creates the tomcat6 user and group. The user runs tomcat, and both the user and group own portions of the CATALINA_BASE directory tree. This is an unprivileged user, and so it cannot bind to privileged (aka well-known) ports. Many daemons start as root, bind to a privileged port and perform other setup work, then drop privileges and run as another user. Tomcat 6, however, now uses authbind(1) for this purpose. Authbind provides access control as follows, from the authbind(1) manpage:
Access to low numbered ports is controlled by permissions and contents of files in a configuration area, /etc/authbind.
Firstly, /etc/authbind/byport/port is tested. If this file is accessible for execution to the calling user, according to access(2), then binding to the port is authorised. If the file can be seen not to exist (the existence check returns ENOENT) then further tests will be used to find authorisation; otherwise, binding is not authorised, and the bind call will return with the errno value from the access(2) call, usually EACCES (Permission denied).
Secondly, if that test fails to resolve the matter, /etc/authbind/byaddr/addr:port is tested, in the same manner as above.
Thirdly, if the question is still unresolved, the file /etc/authbind/byuid/uid will be opened and read. If the file does not exist then the binding is not authorised and bind will return EPERM (Operation not permitted, or Not owner). If the file does exist it will be searched for a line of the form addr/length:min-port,max-port matching the request (ie, the initial length bits of addr match those in the proposed bind call, and the proposed port number lies is in the inclusive range specified. If such a line is found then the binding is authorised. Otherwise it is not, and bind will fail with ENOENT (No such file or directory).
In our case, the tomcat6 package creates a small file in /etc/authbind/byuid named with the UID of the tomcat6 user, and containing the line:
0.0.0.0/32:1,1023
This allows the tomcat6 user to bind to any IP address with any low-numbered port, TCP or UDP.
So why does an attempt to start after having modified /etc/tomcat6/server.xml to start on TCP/80 fail with an error like the following?
SEVERE: Error starting endpoint java.net.BindException: Permission denied <null>:80
One piece is still missing! Authbind is not enabled by default. You will find the following section in the /etc/default/tomcat6 file:
# If you run Tomcat on port numbers that are all higher than 1023, then you # do not need authbind. It is used for binding Tomcat to lower port numbers. # NOTE: authbind works only with IPv4. Do not enable it when using IPv6. # (yes/no, default: no) #AUTHBIND=no
Uncomment the last line, and change ‘no’ to ‘yes’ and tomcat6 will start as you expect! Kudos to the package maintainers for being security conscious, although I’ll admit finding all of the clues to make this work was a bit of a chore.
October 11, 2010 at 15:48
Thank you! You saved my sleepless night!
December 13, 2010 at 16:59
Very nice explanation. Really good.
Thanks a lot!
December 20, 2010 at 06:10
Fantastic I not make the section of /etc/authbind/byuid
I only change #AUTHBIND=no to yes and work perfect
April 22, 2011 at 16:20
thx for the explanation, helped me a lot
June 9, 2011 at 09:25
Great post! Very heplful.
June 19, 2011 at 03:26
Thanks for taking the time to write this article. Saved me a lot of time thanks.
June 29, 2011 at 08:02
Hello,
thank you very very much!
It solved all my problems with tomcat, really!
August 17, 2011 at 22:41
Many thanks! You saved my day!
August 24, 2011 at 08:02
This is f***ing great! Thanks!
September 8, 2011 at 08:24
Thanks a ton! This one is a saver.
October 3, 2011 at 22:57
thanks a lot… just a simple question — now should I start tomcat6 as user “tomcat6” or use sudo?
* if sudo, it’d be: sudo /etc/init.d/tomcat6 start
* if run as tomcat6, I’m not sure about how…
TIA
November 3, 2011 at 03:52
Thanks. Really helped. Great tip.
February 13, 2012 at 14:11
Thanks, it´s great!
April 25, 2012 at 12:06
thanks a lot
June 15, 2012 at 18:35
Thank you: good tip.
October 31, 2012 at 03:22
Hello! Do you know if they make any plugins to protect against hackers?
I’m kinda paranoid about losing everything I’ve worked hard on.
Any tips?
March 5, 2013 at 05:46
Thank you very much, Great post you saved my day.
December 11, 2013 at 14:37
Yeah!! Thank you from Spain!.
September 14, 2015 at 18:33
Note that authbind only works with IPv4, so you need to tell your app to use that instead of IPv6