What's new

Selective Routing with Asuswrt-Merlin

  • 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!

RMerlin creates RPDB prio rules starting at 100x (which seems unnecessarily restrictive?)

I chose to start at 1000 because of the following calculations:

1) There are five clients
2) Each client has inbound and outbound rulesets
3) Each ruleset can have up to 100 entries

So, 5 * 2 * 100 = 1000 priorities need to be reserved. Therefore, I use 1000 to 1999 for policy routing.
 
I chose to start at 1000 because of the following calculations:

1) There are five clients
2) Each client has inbound and outbound rulesets
3) Each ruleset can have up to 100 entries

So, 5 * 2 * 100 = 1000 priorities need to be reserved. Therefore, I use 1000 to 1999 for policy routing.
Is there any particular reason you started at 1000? ( leaving only 1000 priorities between 0 and your start point, where there are considerably more between 2000 and the lowest priority) and is there any way of determining a range of priorities that may have been already reserved?
 
Last edited:
Is there any particular reason you started at 1000? ( leaving only 1000 priorities between 0 and your start point, where there are considerably more between 2000 and the lowest priority) and is there any way of determining a range of priorities that may have been already reserved?

I can't start from 1 because Asus might use it. 1000 was the lowest number that made the maths simple to implement. Nothing prevents you from using 2000 through 32766, the range that I use is very specific.
 
I can't start from 1 because Asus might use it. 1000 was the lowest number that made the maths simple to implement. Nothing prevents you from using 2000 through 32766, the range that I use is very specific.
I understand that 2000 to 32766 are available, however aren't these all lower priority in the RPDB? For example in jaydee99 case in post #459, his script is probably not working because his packets will have been routed according to a matching rule with higher priority before getting to rule 3001, correct? So the likelihood is that if we want more control over routing then, won't we need to set rules to have a higher priority ( say for example, with marks). Wont the lower priority rules only be considered if the higher priority rules are made specific enough that your target packet won't match any of them?... if i have hold of the wrong end of the stick do tell me so...
 
Thanx a lot Martineau, it finally worked with your help, alleluyah !

Here is the script i did :

Code:
#!/bin/sh                                                                                                                    
                                                                                                                              
logger -t "($(basename $0))" $$ VPN Selective Customization                                                                  
                                                                                                                              
ip rule add fwmark 0x7000 table main prio 999                                                                                
                                                                                                                              
iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --dport 80,443 -j MARK --set-mark 0x7000/0x7000                  
iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --sport 5000,5001 -j MARK --set-mark 0x7000/0x7000

I use this script in openvpn-event. Tried it it nat-start but didn't work.

Only strange thing is it seems to run twice :

Code:
admin@RT-AC68U-9048:/jffs/scripts# ip rule
0:    from all lookup local
999:    from all fwmark 0x7000 lookup main
999:    from all fwmark 0x7000 lookup main
1101:    from 192.168.0.2 lookup ovpnc1
1102:    from 192.168.0.5 lookup ovpnc1
32766:    from all lookup main
32767:    from all lookup default

Looking in log the openvpn-event launches twice.

Code:
Oct 23 14:27:17 dnsmasq[839]: using nameserver 192.168.1.1#53 for domain home
Oct 23 14:27:17 dnsmasq[839]: using nameserver 8.8.8.8#53 for domain france-paris-1-ca-version-2.expressnetw.com
Oct 23 14:27:17 dnsmasq[839]: using nameserver 10.11.0.1#53
Oct 23 14:27:17 dnsmasq[839]: using nameserver 192.168.1.1#53
Oct 23 14:27:18 custom script: Running /jffs/scripts/openvpn-event (args: tun11 1500 1606 10.11.2.46 10.11.2.45 init)
Oct 23 14:27:18 (openvpn-event): 843 VPN Selective Customization
Oct 23 14:27:20 openvpn[779]: /usr/sbin/ip route add 159.8.86.41/32 via 192.168.1.1
Oct 23 14:27:20 openvpn[779]: /usr/sbin/ip route add 0.0.0.0/1 via 10.11.2.45
Oct 23 14:27:20 openvpn[779]: /usr/sbin/ip route add 128.0.0.0/1 via 10.11.2.45
Oct 23 14:27:20 openvpn[779]: /usr/sbin/ip route add 10.11.0.1/32 via 10.11.2.45
Oct 23 14:27:20 openvpn-routing: Configuring policy rules for client 1
Oct 23 14:27:20 openvpn-routing: Creating VPN routing table
Oct 23 14:27:20 openvpn-routing: Removing route for 10.11.0.1 to tun11 from main routing table
Oct 23 14:27:20 openvpn-routing: Removing route for 0.0.0.0/1 to tun11 from main routing table
Oct 23 14:27:20 openvpn-routing: Removing route for 128.0.0.0/1 to tun11 from main routing table
Oct 23 14:27:20 openvpn-routing: Adding route for 192.168.0.2 to 0.0.0.0 through VPN client 1
Oct 23 14:27:20 openvpn-routing: Adding route for 192.168.0.5 to 0.0.0.0 through VPN client 1
Oct 23 14:27:20 openvpn-routing: Adding route for 192.168.0.6 to 0.0.0.0 through VPN client 1
Oct 23 14:27:20 openvpn-routing: Completed routing policy configuration for client 1
Oct 23 14:27:20 custom script: Running /jffs/scripts/openvpn-event (args: tun11 1500 1606 10.11.2.46 10.11.2.45)
Oct 23 14:27:20 (openvpn-event): 967 VPN Selective Customization
Oct 23 14:27:20 openvpn[779]: Initialization Sequence Completed
Oct 23 14:27:34 dnsmasq-dhcp[839]: DHCPREQUEST(br0) 192.168.0.21 74:da:38:65:e3:49
Oct 23 14:27:34 dnsmasq-dhcp[839]: DHCPACK(br0) 192.168.0.21 74:da:38:65:e3:49 LEChambre
Oct 23 14:27:38 crond[447]: time disparity of 647367 minutes detected

It's not a big deal as long as it's working but do you have a fix for that ?

Thanx a lot
 
Last edited:
Thanx a lot Martineau, it finally worked with your help, alleluyah !

Here is the script i did :

Code:
#!/bin/sh                                                                                                            
                                                                                                                      
logger -t "($(basename $0))" $$ VPN Selective Customization                                                          
                                                                                                                      
ip rule add fwmark 0x7000 table main prio 999                                                                        
                                                                                                                      
iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --dport 80,443 -j MARK --set-mark 0x7000/0x7000          
iptables -t mangle -A PREROUTING -i br0 -p tcp -m multiport --sport 5000,5001 -j MARK --set-mark 0x7000/0x7000

I use this script in openvpn-event. Tried it it nat-start but didn't work.

Only strange thing is it seems to run twice :

Code:
admin@RT-AC68U-9048:/jffs/scripts# ip rule
0:    from all lookup local
999:    from all fwmark 0x7000 lookup main
999:    from all fwmark 0x7000 lookup main
1101:    from 192.168.0.2 lookup ovpnc1
1102:    from 192.168.0.5 lookup ovpnc1
32766:    from all lookup main
32767:    from all lookup default

Looking in log the openvpn-event launches twice.

It's not a big deal as long as it's working but do you have a fix for that ?

Thanx a lot


openvpn-event fires multiple times for (most) VPN Client / Server actions;)

e.g. a possible sample openvpn-event script:

Code:
#!/bin/sh
logger -s -t "($(basename $0))" $$ "Openvpn event '$script_type'" $dev via $ifconfig_local args = [$@]

if [ "x$dev" = "xtun21" -o "x$dev" = "xtun21" ];then
   logger -s -t "($(basename $0))" $$ Ignoring Openvpn event for Server $dev
   exit
fi

case "$script_type" in
"route-up")

#logger -s -t "($(basename $0))" $$ Added VPN Client$VPN_ID fwmark $TAG_MARK to routing policy
if [ "$dev" = "tunxx" ]; then
etc.
fi
;;

case "$script_type" in
"route-pre-down")

logger -s -t "($(basename $0))" $$ Removing VPN fwmark $TAG_MARK from routing policy
etc.
;;

*)
logger -s -t "($(basename $0))" $$ Ignoring Openvpn Client event "'$script_type'" for $dev
;;
esac

Clearly if you don't differentiate ($script_type) between the calls to openvpn-event then I suggest you ensure you delete any existing/conflicting RPDB rules before you insert them to prevent duplicates!

Code:
ip rule del prio 999 2> /dev/null > /dev/null
ip rule add fwmark 0x7000 table main prio 999

I prefer to use a modified RMerlins vpnrouting.sh script given that this is obviously the best place to include the Selective Port routing fwmark entries since this is also where the VPN Policy rules are added as defined by the user via the GUI.


@RMerlin is against promoting the 'advanced user' use of fwmarks (there are caveats that need to be considered but they can be managed) but I have simply changed a few lines to move his block of RPDB rules to start at 10000 (rather than the original 1000) and also added the appropriate WAN/VPN Client fwmarks

Code:
########################################################################################## Martineau Hack Optional
#START_PRIO=$((1000+(200*($VPN_UNIT-1))))
START_PRIO=$((10000+(200*($VPN_UNIT-1))))

ip rule del from 0/0 fwmark 0x7000 table main prio "10000" 2> /dev/null > /dev/null
ip rule add from 0/0 fwmark 0x7000 table main prio "10000"
etc.
##########################################################################################

Regards,
 
Last edited:
Thanx a lot for your help, i really appreciate it !

How to use the openvpn-script you just gave, i don't get it ?

Sorry to ask this but how do you use a modified vpnrouting.sh script ? Where to get it ? Could you give me a sample of yours to see what it looks like ? And how to run it at startup ?

If it seems too complicated for me, i'll try what you said ie :

Code:
ip rule del prio 999 2> /dev/null > /dev/null
ip rule add fwmark 0x7000 table main prio 999

But my problem is the "iptables -t mangle" commands also add twice... Is there a simple way to prevent adding them twice, like with ip rule ?
 
Thanx a lot for your help, i really appreciate it !

Sorry to ask this but how do you use a modified vpnrouting.sh script ? Where to get it ? Could you give me a sample of yours to see what it looks like ? And how to run it at startup ?

If it seems too complicated for me, i'll try what you said ie :

Code:
ip rule del prio 999 2> /dev/null > /dev/null
ip rule add fwmark 0x7000 table main prio 999

But my problem is the "iptables -t mangle" commands also add twice... Is there a simple way to prevent adding them twice, like with ip rule ?

To prevent duplicate iptables -t mangle entries etc. simply use the iptables delete command before adding/inserting the iptables rule!

Code:
iptables -t mangle -D PREROUTING -i br0 -m iprange --src-range $IP_RANGE -p tcp --dport $3 -j MARK --set-mark $TAG_MARK/$TAG_MARK 2>  /dev/null > /dev/null
iptables -t mangle -A PREROUTING -i br0 -m iprange --src-range $IP_RANGE -p tcp --dport $3 -j MARK --set-mark $TAG_MARK/$TAG_MARK

openvpn-event is always called by vpnrouting.sh so really you should perform any VPN customisation in the openvpn-event script.

However if you are determined see /usr/sbin/vpnrouting.sh :cool: then you can hack it as you desire. :eek:
 
I understand that 2000 to 32766 are available, however aren't these all lower priority in the RPDB? For example in jaydee99 case in post #459, his script is probably not working because his packets will have been routed according to a matching rule with higher priority before getting to rule 3001, correct? So the likelihood is that if we want more control over routing then, won't we need to set rules to have a higher priority ( say for example, with marks). Wont the lower priority rules only be considered if the higher priority rules are made specific enough that your target packet won't match any of them?... if i have hold of the wrong end of the stick do tell me so...

I'm not sure what kind of scenario you would have that requires more than 1000 higher priority routing rules on a home router, but if you do have such a scenario, it might be time to invest into a business-class product IMHO, as this is a very unusual setup, and I doubt the performance would be anything stellar with 1000+ different routing rules applied.

The VPN routing rules will be as specific or as broad as you make them.
 
I'm not sure what kind of scenario you would have that requires more than 1000 higher priority routing rules on a home router, but if you do have such a scenario, it might be time to invest into a business-class product IMHO, as this is a very unusual setup, and I doubt the performance would be anything stellar with 1000+ different routing rules applied.

The VPN routing rules will be as specific or as broad as you make them.
I can't think of a scenario where 1000+ rules would be applied on a home router either. I was thinking more about reserving the rules as indeed you have done for your openvpn routing solution. Even though you have reserved 1000 rules , only a handful of them may be applied at any one time. My questions were not meant to be critical of your design in any way, i was simply trying to understand the rationale. Thanks for taking the time to explain.
 
I can't think of a scenario where 1000+ rules would be applied on a home router either. I was thinking more about reserving the rules as indeed you have done for your openvpn routing solution. Even though you have reserved 1000 rules , only a handful of them may be applied at any one time. My questions were not meant to be critical of your design in any way, i was simply trying to understand the rationale. Thanks for taking the time to explain.

I can easily shift my table up to 10000, that's not a problem. I made the vpnrouting script clean enough that it's easy to make that kind of changes.
 
I can easily shift my table up to 10000, that's not a problem. I made the vpnrouting script clean enough that it's easy to make that kind of changes.
I see Martineau has done that very thing in one of his earlier posts. A question in this regard.... is it documented anywhere when such changes may be made to reserved rules or tables that might trip up a perspective scripter? unless a rule is actually applied at the time, an "ip rule" command won't show it, which leaves digging around in the code looking to see whats been done or "tribal knowledge" ( the ever helpful and knowledgeable members of the forum)
 
is it documented anywhere when such changes may be made to reserved rules or tables that might trip up a perspective scripter?

You'd have to keep track of development commits on Github.
 
Will wait for Janoesk to make a proper wiki but for extreme novice users like me - got it working with the help of Janosek and here are the steps

THE CODE

Code:
#!/bin/sh


sleep 2

touch /tmp/000wanstarted

for i in /proc/sys/net/ipv4/conf/*/rp_filter ; do
      echo 0 > $i
done



#US VPN

#
# Delete and table 100 and flush any existing rules if they exist.
#
ip route flush table 100
ip route del default table 100
ip rule del fwmark 1 table 100
ip route flush cache
iptables -t mangle -F PREROUTING



#
# Copy all non-default and non-VPN related routes from the main table into table 100.
# Then configure table 100 to route all traffic out the WAN gateway and assign it mark "1"
#
# NOTE: Here I assume the OpenVPN tunnel is named "tun11".
#
#
ip route show table main | grep -Ev ^default | grep -Ev tun11 \
  | while read ROUTE ; do
      ip route add table 100 $ROUTE
done



ip route add default table 100 via $(nvram get wan_gateway)
ip rule add fwmark 1 table 100
ip route flush cache




#
# Define the routing policies for the traffic. The rules will be applied in the order that they
# are listed. In the end, packets with MARK set to "0" will pass through the VPN. If MARK is set
# to "1" it will bypass the VPN.
#




#  All LAN traffic will bypass the VPN (Useful to put this rule first, so all traffic bypasses the VPN and you can # configure exceptions afterwards)

   iptables -t mangle -A PREROUTING -i br0 -j MARK --set-mark 1



# All traffic from[B] Roku Wireless [/B]will use the UK VPN
iptables -t mangle -A PREROUTING -i br0 -m iprange --src-range 192.168.1.103 -j MARK --set-mark 0




exit 0

If you notice the code, I only have 1 device configured to use VPN ( Roku Wireless )
Rest is all via regular LAN Speed

Save the above as "openvpn-event" ( without the quotes and NO FILE EXTENSION at all )

1) Assuming you have VPN Account and have it already working with OpenVPN in your Asus-Merlin Router ( test manually if VPN works first )
2) So make sure its ON and Start with WAN option
3) Goto to Administration > System
  • Enable JFFS partition = YES
  • Format JFFS partition at next boot = YES
REBOOT ROUTER
4) Download a Software like WinSCP
File Protocoal - SCP
Hostname: 192.168.1.1
Username/Password: Whatever you use to login to the router
Port 22
5) Need to go upto the root folder where you see jffs folder
6) Go Inside Folder then Go Inside Scripts Folder
7) Place the code openvpn-event you made above in this folder, right click > Properties > Change Octal to 0777

Thats it

Close WinSCP
Reboot Router

GOOD TO GO

I'm trying to route my VPN through my Apple TV (2016) and my Nvidia Shield TV to access US netflix, would this work? And by doing so, are local things like Plex still available on said devices?
 
Hi,

Please could someone give me a hand, I am at a loss and this is literally hurting my head trying to work out wtf is going on!?

I have been using the following script for a few weeks to selectively route traffic from a single host to a single destination and port over vpn (tun11) and block said traffic if vpn tunnel is down:

Code:
#!/bin/sh

TAG_MARK=8
ip rule  del  fwmark  $TAG_MARK  2>  /dev/null > /dev/null
ip rule  add  fwmark  $TAG_MARK  table  111  prio 11
ip route  flush  cache

iptables -t mangle -A PREROUTING -i br0 -s 192.168.1.xx -d xxxx.xxxx.com -j MARK --set-mark $TAG_MARK
iptables -I FORWARD ! -o tun11 -s 192.168.1.xx -d xxxx.xxxx.com -j DROP

Now, as I mentioned this has been working for a number of weeks and the only thing that has changed on my network is that I have just had a new work laptop, I have not upgraded the firmware (Firmware:380.62), I have not added any new port forwards through the gui or via iptables...it has just stopped working.

I have tried running the above script one line at a time and it appears that as soon as I run the add the iptables -t mangle -A...line my host can no longer reach the destination.

The only other thing I have noticed when listing iptables is this PCREDIRECT Chain:

Code:
Chain PREROUTING (policy ACCEPT 678 packets, 70496 bytes)
num   pkts bytes target     prot opt in     out     source               destination
...
4        0     0 PCREDIRECT  all  --  br0    *       0.0.0.0/0            0.0.0.0/0           MAC 34:xx:xx:xx:xx:7C

Chain PCREDIRECT (1 references)
num   pkts bytes target     prot opt in     out     source               destination
1        0     0 DNAT       tcp  --  br0    *       0.0.0.0/0           !192.168.1.0/24      tcp dpt:80 MAC 34:xx:xx:xx:xx:7C to:192.168.1.1:18099

I don't remember seeing in the past so not sure if my new laptop (Dell XPS) has somehow set it up? The reason I am pretty sure that I haven't seen this in the past is because this appears as line 4 in the PREROUTING table, and when this selective routing worked in the past the line added by the 'iptables -t mangle -A ...' part of the script was always listed as line 4.

Thanks in advance for any light you can shed on this, I have gotten by for years without the need to ask for help and I have followed this thread from pretty much word go, so please forgive me if I have missed something silly.

Thanks
Jon
 
PCREDIRECT is used by the router to redirect clients to an internal error. In your case, you probably have parental control configured.
 
PCREDIRECT is used by the router to redirect clients to an internal error. In your case, you probably have parental control configured.

Thanks Merlin, you are correct. . . Parental control was turned on, and there was an Apple ipad-3 device configured... but what is worrying is this is not something I enabled, so god knows how it got enabled.

I have just turned this off, but unfortunately still no joy with my script. . . As soon as I run it I cannot get to the destination.

Any more ideas?

Thanks again
 
Packet marking is a tricky business, since various marks are used by the firmware. You need to use a bit that isn't already in use, and also account for the use of bitmasks. If you check the forums, there's been a few posts a couple of weeks ago listing the currently used bits, and what masks to use.

Also note that some of these can be overwritten by the Trend Micro engine. That was why I made the policy routing strictly reliant on RPDB rather than packet marking.
 
Packet marking is a tricky business, since various marks are used by the firmware. You need to use a bit that isn't already in use, and also account for the use of bitmasks. If you check the forums, there's been a few posts a couple of weeks ago listing the currently used bits, and what masks to use.

Also note that some of these can be overwritten by the Trend Micro engine. That was why I made the policy routing strictly reliant on RPDB rather than packet marking.

So instead of packet marking, is there a better, more reliable way of achieving what once worked in the script i posted above?

I only want to route packets from one host on my network to one destination over vpn. . . The dropping of said packets when the tunnel is down is not really a necessity for me (just a nice to have)

I have set all packets from another local client to go via vpn only from the 'block routed clients clients if tunnel goes down' toggle on the router ui - but cant see this when I list the iptables? Is this stored somewhere else? Is there no way of adding a hostname instead of an IP only fo this 'rules for routing clients through the tunnel' ?
 

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