Any way to auto switch A port-forwarding's ip if the host is down?

Hi there!
I recently Installed OpenWrt and looks good so far!

Now the question is, if I have portforwarded port 101(example) to internal host 192.168.0.101, Is there any way to make OpenWrt auto-switch the host of the portforward to 192.168.0.102?

I use a TP-LINK Archer C6v2(EU) Running OpenWRT 21.02.0 r16279-5cc0535800(Kernel 5.4.143)

Sure, you can write a cron scrip to switch the IP in the firewall rule. Since, I'm not sure what "auto" switching you need or how you want it to know to do so...I hope this helps you (:spiral_notepad: I just picked time-based; but the script can be written to check other things, obviously too).

1 Like

Auto- Switch as in triggered when host 101 is down, execute task(switch forward to host 102)
Maybe detect it by pinging the host every 5 minutes or so?

Also, I cant seem to find a simple command to modify port-forwards

Run the following command replacing "Myrule" by your rule name and look for the value in the square brackets.

uci show firewall | grep "Myrule"

Replace the number in the brackets from the script below with the correct one.

#!/bin/sh

dst_addr=$(uci get firewall.@redirect[1].dest_ip);

if ! ping -c 3 -W 1 192.168.0.101 >/dev/null; then

	if [ "$dst_addr" == "192.168.0.101" ]; then
	uci set firewall.@redirect[1].dest_ip="192.168.0.102"
	fw3 -q reload
	else
	exit 0
	fi
else
	if [ "$dst_addr" == "192.168.0.102" ]; then
	uci revert firewall
	fw3 -q reload
	else
	exit 0
	fi
fi 

Create a cron job with a time interval of your choice. When 101 goes down, the requests will be forwarded to 102. If 101 goes up, the settings will be reverted.

2 Likes

Thanks a lot!
Just a few questions:
Can I scale it to multiple portforwards?
Can I also somehow add a 3rd fallback(i. e. 102 also goes down?)

A better solution is Nginx failover.

I am not hosting a webserver.

If you have multiple port redirects to the same internal IP address (because multiple disparate ports are not supported in redirect rules), you can list all the rules by numbers in the script.

uci set firewall.@redirect[1].dest_ip="192.168.0.102"
uci set firewall.@redirect[3].dest_ip="192.168.0.102"
uci set firewall.@redirect[5].dest_ip="192.168.0.102"
cat << "EOF" > /root/check_stat.scr
#!/bin/sh

dst_addr=$(uci get firewall.@redirect[1].dest_ip);

stat103=$(ping -q -c 3 -W 1 192.168.0.103  > /dev/null 2>&1 && echo "103up" || echo "103down")

if [ "$stat103" == "103up" ]; then
        if [ "$dst_addr" == "192.168.0.103" ]; then
        exit 0
        else
        uci set firewall.@redirect[1].dest_ip="192.168.0.103"
        fw3 -q reload
        exit 0
        fi
else
stat102=$(ping -q -c 3 -W 1 192.168.0.102  > /dev/null 2>&1 && echo "102up" || echo "102down")
        if [ "$stat102" == "102up" ]; then
                if [ "$dst_addr" == "192.168.0.102" ]; then
                exit 0
                else
                uci set firewall.@redirect[1].dest_ip="192.168.0.102"
                fw3 -q reload
                exit 0
                fi
        else
                if [ "$dst_addr" == "192.168.0.101" ]; then
                exit 0
                else
                uci set firewall.@redirect[1].dest_ip="192.168.0.101"
                fw3 -q reload
                exit 0
                fi
        fi
fi
EOF
chmod 755 /root/check_stat.scr
cat << "EOF" >> /etc/crontabs/root
*/5 * * * * . /root/check_stat.scr >/dev/null 2>&1 
EOF
uci set system.@system[0].cronloglevel="9"
uci commit system
/etc/init.d/cron restart

Nginx stream module offers L4 load-balancing, i.e. works on any TCP/UDP applications.