[HOWTO] Persistent port forward with iptables

This will describe how to create persistent rules to forward the HTTP/S ports on a local server.

There is a couple of ways to make the port forward rules persistent correctly. With “correctly” I mean that the implementation follows the network (interface) service instead of a crontab or rc.local that only runs on a reboot.

This example should be generic enough to work on any modern Linux distribution that’s not otherwise configured with exotic firewall settings and rules. Those setting up their own FW will probably not need this guide anyhow :stuck_out_tongue:

Do everything as root or use sudo. This guide assumes no rules are previously set/active.

Create the rules via the CLI:

iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 9443

Create an empty file that will hold the rules:

touch /etc/iptables.blynk.rules

Create a script that will run when the network is connected called iptables. Once the network is up, the rules saved in iptables.blynk.rules will be restored with the command iptables-restore (kinda self-explanatory). Make the file executable:

echo '#!/bin/sh' > /etc/network/if-up.d/iptables
echo "iptables-restore < /etc/iptables.blynk.rules" >> /etc/network/if-up.d/iptables
chmod +x /etc/network/if-up.d/iptables

Create a similar script that saves the current rules when the network disconnects:

echo '#!/bin/sh' > /etc/network/if-down.d/iptables
echo "iptables-save > /etc/iptables.blynk.rules" >> /etc/network/if-down.d/iptables
chmod +x /etc/network/if-down.d/iptables

To save the rules to iptables.blynk.rules, just restart the network service (or reboot the computer):

service networking restart

The file should now be populated and look something like this:

# Generated by iptables-save v1.6.0 on Tue Jan 23 01:00:00 2018
*nat
:PREROUTING ACCEPT [1:36]
:INPUT ACCEPT [1:36]
:OUTPUT ACCEPT [1:76]
:POSTROUTING ACCEPT [1:76]
-A PREROUTING -p tcp -m tcp --dport 80 -j REDIRECT --to-ports 8080
-A PREROUTING -p tcp -m tcp --dport 443 -j REDIRECT --to-ports 9443
COMMIT
# Completed on Tue Jan 23 01:00:00 2018

Check that the rules are applied with iptables -L -t nat

Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:http redir ports 8080
REDIRECT   tcp  --  anywhere             anywhere             tcp dpt:https redir ports 9443

Chain INPUT (policy ACCEPT)
target     prot opt source               destination

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination

That’s it! :slight_smile:


If you run the Blynk server with root privileges, change the settings in server.properties so it will listen on the default ports for HTTP/S instead and forget everything I said about iptables :wink:

#http and web sockets port
http.port=80

#https and web sockets port
https.port=443

I see no reason for this to not work on Raspbian, but I haven’t tested it!

2 Likes

I’ve used iptables quite a bit. Moved to shorewall which is a very neat iptables preprocessor from config files. Runs them for every boot thus providing persistence.

Thanks :smiley:

There is one more simple tool.

  1. Add your ip forwarding rule;
  2. Run sudo apt-get install iptables-persistent;

That’s it. forwarding rules will be persistent.

2 Likes

@Dmitriy would be a welcome addition to the server docs as it’s something many people don’t do.

There is a couple of reasons why I tried to keep the “simple way” a secret. I’m not trying to make this a contest where we meet up in the shower with a measuring tape deciding who’s senior to whom, because both solutions works. But as everyone can see, mine is both bigger AND longer :rofl:

I don’t call this pros & cons because how you configure and run a server is highly individual. Different people have different needs!

My aim was:

  1. Rules to follow the state of the network interface.
  2. Changes to the rule set (not only Blynk) will automatically be saved.
  3. Not to use extra software/packages.
  4. Simple

With iptables-persistent you miss out on 1 and 2 because it doesn’t work that way, and 3 for obvious reasons.

On item 4, simplicity - Once it’s set up, it does what it should (as per my liking).

For a one-time-never-look-back-solution, installing iptables-persistent is easier, but… (there is always a ‘but’ :smiley: ) Nowadays iptables-persistent is replaced by netfilter-persistent (which is automatically installed as a dependency).

For inexperienced users this might be a problem if they ever have to reconfigure iptables-persistent, the command itself doesn’t exist anymore. And since g**gle doesn’t work for Blynk newbies, they’ll start asking about it here instead :wink:

If you’re going to add the one-time-never-look-back-solution, just change the package. Perhaps something like this:

  1. Add your rules:
    sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
    sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 9443

  2. Install netfilter-persistent:
    sudo install netfilter-persistent

  3. Answer “Yes” when asked to save your current IPv4 (and IPv6 if applicable) rules.

  4. Make sure your rules got sticky: Reboot, log on and run sudo iptables -L -t nat. They output should contain the previously added rules.

2 Likes

I don’t know about that… I have a couple of really big and long tape measures, one is even bright yellow and orange and I believe around 30M… and fully waterproof for extensive show & tell, even in showers (what a silly place to examine measuring tapes… but each to their own) :rofl: