What's new

Round Robin single port to multiple internal IPs

  • SNBForums Code of Conduct

    SNBForums is a community for everyone, no matter what their level of experience.

    Please be tolerant and patient of others, especially newcomers. We are all here to share and learn!

    The rules are simple: Be patient, be nice, be helpful or be gone!

trajano

New Around Here
Currently we can only port forward to a single internal IP. Is it possible to add the capability for portforwarding to multiple internal IPs given a port? Possibly add the capability of checking if there is something listening first before forwarding.
 
I can't see this being particularly useful, if indeed it's possible. Can you give us an example of a use case?
 
Technically not possible. A port can only be forwarded to a single destination. The process is a static one, it's not dynamic (i.e. it cannot do any check, the port is either forwarded or it's not).
 
You need 5 static IPs from your ISP. Then you can forward to 5 different IPs.

The other option is to pick another port. You can forward to multiple ports off 1 IP. They just cannot be the same port for the same IP.
 
Currently we can only port forward to a single internal IP. Is it possible to add the capability for portforwarding to multiple internal IPs given a port? Possibly add the capability of checking if there is something listening first before forwarding.
Could you manually exploit this extended match ?

Code:
iptables -m statistic -help

e.g. assuming 192.168.1.99 is capable of listening on all three ports 10001,10002 and 10003
Code:
iptables -A PREROUTING -p tcp -m tcp --dport 50000 -m statistic --mode nth --every 3 -j REDIRECT --to-ports 10001 -d 192.168.1.99
iptables -A PREROUTING -p tcp -m tcp --dport 50000 -m statistic --mode nth --every 2 -j REDIRECT --to-ports 10002 -d 192.168.1.99
iptables -A PREROUTING -p tcp -m tcp --dport 50000                                   -j REDIRECT --to-ports 10003 -d 192.168.1.99

so it may be possible to use 3 different IPs for each of the round robin matching for a Load-Balancing scenario?
 
so it may be possible to use 3 different IPs for each of the round robin matching for a Load-Balancing scenario?
Load balancing is doable (if that's what the OP was asking), but you have to count the packets also (--packet n).

https://www.webair.com/community/simple-stateful-load-balancer-with-iptables-and-nat/
This technique doesn't work anymore because the packet counter changed from global to per-rule when "nth" became part of the statistic module.

Still, I don't think it's something that enough people would use to justify it being a GUI option. Especially as they could just do it with a script.
 
Last edited:
Load balancing is doable (if that's what the OP was asking), but you have to count the packets also (--packet n)

Err the example rules I posted do count the packets (see the default value/meaning for the '--packet' directive), and personally I believe is much easier to read/understand than the link you posted where (at first glance) all four rules seemingly match on every 4th record.

However the following would indeed be mandatory to prevent issues.
Code:
-m state --state NEW
 
I don't mind a script option. The concept is to run multiple docker containers and rather than having a single node (internal machines) as the failure point to have multiple nodes serving the public IP and hosting the site.

So the concept would be

http://202.201.200.101:12345/ (external IP)

goes internally to

http://192.168.1.45:12345/
http://192.168.1.46:12345/
http://192.168.1.47:12345/
http://192.168.1.48:12345/

Each of them is basically running hosting the same content but 4 web server process.

Code:
iptables -A PREROUTING -p tcp -m tcp --dport 12345 -m statistic --mode nth --every 3 -j REDIRECT --to-ports 12345 -d 192.168.1.45
iptables -A PREROUTING -p tcp -m tcp --dport 12345 -m statistic --mode nth --every 2 -j REDIRECT --to-ports 12345 -d 192.168.1.46

would probably do the trick but where do I put this?
 
Last edited:
I don't mind a script option. The concept is to run multiple docker containers and rather than having a single node (internal machines) as the failure point to have multiple nodes serving the public IP and hosting the site.

So the concept would be?

Create something like this...

/jffs/scripts/PortForwardLoadBalance.sh
Code:
#!/bin/sh

NODES="45 46 47 48"                                 # List of Web server nodes
PORT_EXTERNAL="8080"                                # Public External Port
PORT_INTERNAL="80"                                  # Internal Port

LAN_PREFIX=$(nvram get lan_ipaddr | cut -d'.' -f1-3)
INDEX=1

for NODE in $NODES
    do
        iptables -t nat -D VSERVER -p tcp --dport $PORT_EXTERNAL -m state --state NEW -m statistic --mode nth --every $INDEX --packet 0 -j DNAT --to-destination ${LAN_PREFIX}.${NODE}:$PORT_INTERNAL 2>/dev/null
        iptables -t nat -I VSERVER -p tcp --dport $PORT_EXTERNAL -m state --state NEW -m statistic --mode nth --every $INDEX --packet 0 -j DNAT --to-destination ${LAN_PREFIX}.${NODE}:$PORT_INTERNAL
        INDEX=$((INDEX+1))
    done
 
iptables -nvL PREROUTING --line -t nat | grep -E "^num|Chain PREROUTING|VSERVER"
echo
iptables -nvL VSERVER --line -t nat | grep -E "^num|VSERVER|nth"
then test the script, and when satisfied, call it from nat-start.

NOTE: You will need to create a monitoring function/trigger to enable you to dynamically rewrite the round-robin rules if a Web server node goes DOWN.
 
Last edited:
@Martineau Just curious whether you've got your script to run without syntax errors? I tried using the statistic module but it always returned an error because it was not included in my firmware (John's Fork). John kindly built a custom firmware with it included and it then accepted the commands as expected. John said that he thought Merlin's firmware also lacked the statistic module. Did you find that to be the case?
 
@Martineau Just curious whether you've got your script to run without syntax errors? I tried using the statistic module but it always returned an error because it was not included in my firmware (John's Fork). John kindly built a custom firmware with it included and it then accepted the commands as expected. John said that he thought Merlin's firmware also lacked the statistic module. Did you find that to be the case?

I have created a user friendly script....
Code:
./PortForwardLoadBalancing.sh -h

#============================================================================== © 2018 Martineau, v01.01
#
# Configure Port Forward round-robin Load-balancing rules
#
#     PortForwardLoadBalancing     [--help|-h]
#                                  [--check] [--flush]  [nodes={"IP [IP"...]}] [extport{='port'}]  [intport{='port'}] [nocurl]
#     PortForwardLoadBalancing
#                                  Create the round-robin rules for the defined Web servers (default Ports External=8080,Internal=80)
#     PortForwardLoadBalancing     --check
#                                  Create the round-robin rules for the defined Web servers ONLY if the Web server is PING/CURL available
#     PortForwardLoadBalancing     --flush
#                                  Flush ALL round-robin rules
#     PortForwardLoadBalancing     --nodes="99 100 101"
#                                  Create the round-robin rules for Web servers .99,.100 and .101 (i.e. override $NODE variable)
#     PortForwardLoadBalancing     --extport=12345
#                                  Create the round-robin rules using External (Public) port 12345

Code:
./PortForwardLoadBalancing.sh

v1.01 © 2018 Martineau, Port Forwarding round-robin Load-Balancing requested.....

 ALL round-robin Port Forwarding Load-Balancing rules flushed.....

 Creating round-robin Port Forwarding Load-Balancing rules..... (Nodes=45 46 47 48 131)

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination   
7     2938  278K VSERVER    all  --  *      *       0.0.0.0/0            xxx.xxx.xxx.xxx
 
Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination   
1        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 5 to:10.88.8.131:80
2        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 4 to:10.88.8.48:80
3        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 3 to:10.88.8.47:80
4        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 2 to:10.88.8.46:80
5        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 1 to:10.88.8.45:80

Port Forwarding round-robin Load-Balancing completed.....


Code:
./PortForwardLoadBalancing.sh --check

v1.01 © 2018 Martineau, Port Forwarding round-robin Load-Balancing requested.....

 Checking Web server(s).....
 10.88.8.45      not available
 10.88.8.46      not available
 10.88.8.47      not available
 10.88.8.48      not available
 10.88.8.131     available

 ALL round-robin Port Forwarding Load-Balancing rules flushed.....

 Creating round-robin Port Forwarding Load-Balancing rules..... (Nodes= 131)

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination    
7     2944  279K VSERVER    all  --  *      *       0.0.0.0/0            xxx.xxx.xxx.xxx
 
Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination    
1        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 1 to:10.88.8.131:80

Port Forwarding round-robin Load-Balancing completed.....

Code:
./PortForwardLoadBalancing.sh --flush

v1.01 © 2018 Martineau, Port Forwarding round-robin Load-Balancing requested.....

 ALL round-robin Port Forwarding Load-Balancing rules flushed.....

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination    
7     2945  279K VSERVER    all  --  *      *       0.0.0.0/0            xxx.xxx.xxx.xxx
 
Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination    

Port Forwarding round-robin Load-Balancing completed.....

Code:
./PortForwardLoadBalancing.sh --extport=12345 --intport=81

v1.01 © 2018 Martineau, Port Forwarding round-robin Load-Balancing requested.....

 ALL round-robin Port Forwarding Load-Balancing rules flushed.....

 Creating round-robin Port Forwarding Load-Balancing rules..... (Nodes=45 46 47 48 131)

Chain PREROUTING (policy ACCEPT 0 packets, 0 bytes)
num   pkts bytes target     prot opt in     out     source               destination    
7     2945  279K VSERVER    all  --  *      *       0.0.0.0/0            xxx.xxx.xxx.xxx  

Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination    
1        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 state NEW statistic mode nth every 5 to:10.88.8.131:81
2        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 state NEW statistic mode nth every 4 to:10.88.8.48:81
3        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 state NEW statistic mode nth every 3 to:10.88.8.47:81
4        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 state NEW statistic mode nth every 2 to:10.88.8.46:81
5        0     0 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:12345 state NEW statistic mode nth every 1 to:10.88.8.45:81

Port Forwarding round-robin Load-Balancing completed.....
 
Last edited:
Can't a device request an internal port and forward to a different external port?
 
John said that he thought Merlin's firmware also lacked the statistic module. Did you find that to be the case?
I double checked...and according to the config files it's not there in Merlin as well. I don't understand how @Martineau got it working unless he's running a custom build.
 
I double checked...and according to the config files it's not there in Merlin as well. .

Déjà vu? iptables '-m statistic' module and I'm definitely sure I have never executed the instructions to compile the module for personal use. :D
I don't understand how @Martineau got it working unless he's running a custom build.
No idea either :confused:.... I assumed it was finally included sometime in the 382.xx/384.xx builds as Asus overhaul their wonky Dual-WAN LB/FO code etc.?

Clearly the round-robin is definitely working..... if not always the access?o_O
Code:
./PortForwardLoadBalancing.sh --status

v1.01 © 2018 Martineau, Port Forwarding round-robin Load-Balancing requested.....

 Rule status:

Chain PREROUTING (policy ACCEPT 18749 packets, 4911K bytes)
num   pkts bytes target     prot opt in     out     source               destination     
7     4324  353K VSERVER    all  --  *      *       0.0.0.0/0           xxx.xxx.xxx.xxx
 
Chain VSERVER (1 references)
num   pkts bytes target     prot opt in     out     source               destination     
1       74  3280 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 7 level 4 prefix "PFLB0Begin"
2       74  3280 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 7 level 4 prefix "PFLB5"
3        2   104 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 5 packet 4 to:10.88.8.131:80
4       72  3176 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 7 level 4 prefix "PFLB4"
5        2   104 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 4 packet 3 to:10.88.8.48:80
6       70  3072 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 7 level 4 prefix "PFLB3"
7        3   156 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 3 packet 2 to:10.88.8.47:80
8       67  2916 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 7 level 4 prefix "PFLB2"
9        3   156 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 2 packet 1 to:10.88.8.46:80
10      64  2760 LOG        all  --  *      *       0.0.0.0/0            0.0.0.0/0            LOG flags 7 level 4 prefix "PFLB1"
11       3   156 DNAT       tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 state NEW statistic mode nth every 1 to:10.88.8.45:80

grep -oE "PFLB[1-5]|PFLB0Begin" /tmp/syslog.log

PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB1
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB1
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB0Begin
PFLB5
PFLB4
PFLB0Begin
PFLB5
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB1
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB0Begin
PFLB5
PFLB4
PFLB0Begin
PFLB5
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB1
PFLB0Begin
PFLB5
PFLB4
PFLB3
PFLB2
PFLB0Begin
PFLB5
PFLB4
PFLB3

NOTE: I believe there was also a recent post by @Fitz Mutch who made use of the iptables '-m statistic' module in his example round-robin DNS resolver script?
 
Last edited:

Latest threads

Sign Up For SNBForums Daily Digest

Get an update of what's new every day delivered to your mailbox. Sign up here!
Top