Running Web Services on Non-Standard Ports

Working in the world of systems administration has taught me a lot, especially in regards to security. One thing I hope to never take for granted is the seemingly endless pool of knowledge there is in IT departments. There's almost always something new to learn from someone.

Since I have been learning so much from other people, I decided to rebuild my web server in an attempt to harden it a bit and to practice building stuff (who doesn't like building stuff, I mean come on...Legos anyone?). One of the things I changed in my process was building everything from source with non-privileged users rather than installing it from repos. One of the advantages to doing this is that each of your services will be running as users that have no access to the rest of the system if their accounts are set up right (ie: no sudo, ssh, or cross service access). The one disadvantage to this is that the services can't bind to ports 1024 and below. For web servers, this really only affects apache, nginx, light httpd, or whatever web server you are using since most other software (ie: php, mysql, etc) runs on ports higher than 1024.

With that, people don't visit our websites on some randomly selected port for a web server, do they?

Nope

So how do we allow them to visit our web server running on a different port other than 80?

The answer is iptables using NAT. Basically what we need to do is take incoming traffic to port 80 and route it to our web server port (in my case, this is 8080). This of course can work for other services as well, but for the purposes of this post, we'll simply translate port 80 traffic.

The iptables commands you'll need for this are as follows:

iptables -A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080

What we've got here is not super hard. Basically, before we do anything else (PREROUTING chain) with our port 80 (--dport 80) tcp (-p tcp -m tcp) network traffic, we want to redirect (-j REDIRECT) the traffic to port 8080 (--to-ports 8080). You can of course do this with https traffic as well. Here's another example using that one.

iptables -A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 8443

Pretty handy, huh?

One note on this before signing off. If you have your input table set to drop all, you need to add an accept rule for tcp port 80 and your web server port (8080 and 8443 in the examples).