Port forwarding with iptables

Normally, in order to listen on a port less than 1024, an app needs to be running as root or have elevated capabilities. That's a security problem waiting to happen, though. We run the app on a normal port, e.g. 4000, and redirect traffic in the firewall from port 80 to 4000 using an iptables rule.

iptables -t nat -A PREROUTING -i eth0 -p tcp --dport 80 -j REDIRECT --to-port 4000

We need to open up access to the app port:

iptables -A INPUT -p tcp --dport 4000 -j ACCEPT

We can also open the port with rate limiting, useful for dealing with DDOS attacks:

iptables -A INPUT -p tcp --dport 4000 -m state --state NEW \
    -m hashlimit --hashlimit-name HTTP --hashlimit 5/minute \
    --hashlimit-burst 10 --hashlimit-mode srcip --hashlimit-htable-expire 300000 -j ACCEPT

Configuring Ubuntu ufw for port forwarding

If you are using Ubuntu's ufw, you can open the port with:

ufw allow 4000/tcp

You need to add raw iptables commands, though, to do the forwarding. Edit /etc/ufw/before.rules and add the following commands:

*nat
:PREROUTING ACCEPT [0:0]
-A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 4000
COMMIT

Configuring iptables with Ansible for port forwarding

This example project for deploying Phoenix apps has Ansible tasks to set up iptables with do port forwarding.