I prefer to not run web applications as root. authbind allows you to run the application as a user other than root, but bind to ports 80 and 443.
Why not root?
In my code, I am as afraid of myself as I am a hacker. My code has bugs. Once I wrote an ant script that deleted *.java (the source code) instead of *.class (the compiled code).
Running the web application process as a non-root user is a good idea from a security perspective, but it also provides some level of protection against catastrophic coding mistakes.
However, by default non-root users cannot bind to ports less than 1024.
Why not iptables?
One way to solve this problem is to have the web application listen on port 8443. Then use an
iptables
rule to seamlessly redirect traffic from 443 to 8443. I don’t like this plan because it requires
leaving port 8443 open in the firewall and I like to leave as few ports open as possible.
Using authbind
I was using Ubuntu 14.04 LTS. To implement authbind
, I did the following to
allow user web
to listen on HTTPS port 443:
# sudo apt-get authbind
# sudo touch /etc/authbind/byport/443
# sudo chmod 500 /etc/authbind/byport/443
# sudo chown web /etc/authbind/byport/443
I did not use port 80 because this application is only a REST service and no unsecured access is allowed. In a regular website like this blog, port 80 should be open so users can be automatically redirected to the secure site.
My webapp was actually an executable script produced by the Maven plugin Appassembler. By default
authbind
only gives permission to the process it launches, not child processes, so I had to add
the argument –deep
. To test it I ran this:
# sudo -u web authbind --deep /opt/web/bin/web-server
To actually install the service, I used Upstart, as described here.