What's new

x3mRouting x3mRouting ~ Selective Routing for Asuswrt-Merlin Firmware

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

hello @Martineau
i got this to work so all vpn clients are routed through the other vpn.

vpnclient1-route-up
Code:
#!/bin/sh
logger -st "($(basename "$0"))" $$ Starting Script Execution JAJA

sh /jffs/scripts/x3mRouting/load_MANUAL_ipset_iface.sh 1 amazon_vpn

iptables -D POSTROUTING -t nat -s 10.0.1.0/24 -o tun11 -j MASQUERADE
iptables -I POSTROUTING -t nat -s 10.0.1.0/24 -o tun11 -j MASQUERADE

logger -st "($(basename "$0"))" $$ Ending Script Execution

quick question: how do i undo this so the clients are now routed back throught the routers wan?

i tried by running
Code:
iptables -D POSTROUTING -t nat -s 10.0.1.0/24 -o tun11 -j MASQUERADE

but now clients will have no internet access
 
hello @Martineau
i got this to work so all vpn clients are routed through the other vpn.

vpnclient1-route-up
Code:
#!/bin/sh
logger -st "($(basename "$0"))" $$ Starting Script Execution JAJA

sh /jffs/scripts/x3mRouting/load_MANUAL_ipset_iface.sh 1 amazon_vpn

iptables -D POSTROUTING -t nat -s 10.0.1.0/24 -o tun11 -j MASQUERADE
iptables -I POSTROUTING -t nat -s 10.0.1.0/24 -o tun11 -j MASQUERADE

logger -st "($(basename "$0"))" $$ Ending Script Execution

quick question: how do i undo this so the clients are now routed back throught the routers wan?

i tried by running
Code:
iptables -D POSTROUTING -t nat -s 10.0.1.0/24 -o tun11 -j MASQUERADE

but now clients will have no internet access

The -t nat POSTROUTING rule simply ensures the packets originating from the OpenVPN Server subnet will find their way back when they return inbound from the VPN Client ISP.

You need to review the RPDB rules, and remove the OpenVPN subnet entries
Code:
ip rule
i.e. if they are defined in the VPN Client Selective Routing GUI then remove them or manually issue the appropriate delete command
Code:
ip rule del prio nnnn
 
Hi.
I found incompatibility of selective routing with SkyNet.
SkyNet during update process did a firewall restart.
It is clear any selective routing rules ...
Code:
2019-10-14T01:25:01+03:00 192.168.99.1 Skynet: [%] New Version Detected - Updating To v6.8.8 (fc4a4faf0394ad20cac1efed649caad7)
2019-10-14T01:25:03+03:00 192.168.99.1 Skynet: [%] Restarting Firewall Service
2019-10-14T01:25:03+03:00 192.168.99.1 rc_service: service 6334:notify_rc restart_firewall
2019-10-14T01:25:03+03:00 192.168.99.1 custom_script: Running /jffs/scripts/service-event (args: restart firewall)
2019-10-14T01:25:03+03:00 192.168.99.1 service-event: Started for event restart of service firewall
2019-10-14T01:25:04+03:00 192.168.99.1 nat: apply nat rules (/tmp/nat_rules_ppp0_eth0)
2019-10-14T01:25:04+03:00 192.168.99.1 custom_script: Running /jffs/scripts/firewall-start (args: ppp0)

After that I have the next result of iptables -t mangle -L PREROUTING
Code:
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination
MARK       all  --  anywhere             anywhere             MARK xset 0x1/0x7
That makes sense as restarting the firewall wipes the iptable rules. For now, placing the commands in /jffs/scripts/nat-start will fix the issue after a firewall restart.

nat-start
Code:
#!/bin/sh

### IPSET Shell Script Method

sh /jffs/scripts/x3mRouting/load_AMAZON_ipset_iface.sh 1 AMAZON_US US
sh /jffs/scripts/x3mRouting/load_ASN_ipset_iface.sh 1 NETFLIX AS2906

sh /jffs/scripts/x3mRouting/load_DNSMASQ_ipset_iface.sh 3 BBC_WEB bbc.co.uk,bbc.com,bbc.gscontxt.net,bbci.co.uk,bbctvapps.co.uk,ssl-bbcsmarttv.2cnt.net,llnwd.net
sh /jffs/scripts/x3mRouting/load_DNSMASQ_ipset_iface.sh 5 CBS_WEB cbs.com,cbsnews.com,cbssports.com,cbsaavideo.com,omtrdc.net,akamaihd.net,irdeto.com,cbsi.com,cbsig.net
sh /jffs/scripts/x3mRouting/load_DNSMASQ_ipset_iface.sh 1 HULU_WEB hulu.com,hulustream.com,akamaihd.net
sh /jffs/scripts/x3mRouting/load_DNSMASQ_ipset_iface.sh 5 MOVETV movetv.com

It appears I will have to recommend that users place the command in both /jffs/scripts/nat-start and /jffs/scripts/x3mRouting/vpnclientX-route-up to resolve. But I need to get to work now and will look into some more tonight.
 
Last edited:
I have a problem trying to install this.

Option ==> 2
Installing jq (1.6-1) to root...
Downloading http://bin.entware.net/aarch64-k3.10/jq_1.6-1_aarch64-3.10.ipk
Collected errors:
* opkg_install_pkg: Package size mismatch: jq is 109237 bytes, expecting 10923s
* opkg_install_cmd: Cannot install package jq.
An error occurred installing jq
Looks like an entware issue. You can try the commands below or try updating entware using the "ep" option in AMTM.
Code:
opkg update
opkg upgrade
opkg install jq
 
Did you try using another browser. I found a recent reference about the error online. https://superuser.com/questions/148...-pr-connect-reset-error-in-firefoxs-incognito

If there are sites you want to access over the VPN that your ISP is blocking, find out the IP address of the domain using the nslookup command. You can create a manual IPSET list in /opt/tmp directory. Open the file in an editor and enter the ip addresses. Then, use the MANUAL script script to route the traffic:

sh load_MANUAL_ipset_iface.sh 3 BBC

Okay, I installed x3mRouting succesfully (op2 and op3).
Created a file (named rlist) containing every ip I found through nslookup. Every line contains single ip.
Placed this file into the /opt/tmp folder
SSHed router
navigated to the jffs/scripts/x3mRouting
run the below command
sh load_MANUAL_ipset_iface.sh 2 rlist
Code:
(load_MANUAL_ipset_iface.sh): 17278 Starting Script Execution
(load_MANUAL_ipset_iface.sh): 17278 IPSET created: List hash:net family inet hashsize 1024 maxelem 65536
(load_MANUAL_ipset_iface.sh): 17278 Selective Routing Rule via VPN Client 2 created TAG fwmark 0x2000/0x2000
(load_MANUAL_ipset_iface.sh): 17278 Ending Script Execution
After that I accessed the webgui of the router and enabled client 2.

DNS configuration is exclusive
Force Internet traffic through tunnel is set to Policy Rules (Strict).
The list is empty.
After that I am stuck.
I think something going wrong with the IPSET creation because when I try to delete the list I just created I get an error msg like that
sh load_MANUAL_ipset_iface.sh 2 rlist del
Code:
25451 Error attempting to delete IPSET rlist!
 
I think something going wrong with the IPSET creation because when I try to delete the list I just created I get an error msg like that
sh load_MANUAL_ipset_iface.sh 2 rlist del
Code:
25451 Error attempting to delete IPSET rlist!
After running
Code:
sh load_MANUAL_ipset_iface.sh 2 rlist
you can manually check if the IPSET is created correctly (it should list the IPs imported from/opt/tmp/rlist)
Code:
ipset list rlist
I suspect that
Code:
sh load_MANUAL_ipset_iface.sh 2 rlist del
does actually physically delete the IPSET, but spuriously reports the error.
 
That makes sense as restarting the firewall wipes the iptable rules. For now, placing the commands in /jffs/scripts/nat-start will fix the issue after a firewall restart.

nat-start

It appears I will have to recommend that users place the command in both /jffs/scripts/nat-start and /jffs/scripts/x3mRouting/vpnclientX-route-up to resolve. But I need to get to work now and will look into some more tonight.
Thanks for the idea.

Now I created two files
/jffs/scripts/nat-start
Code:
#!/bin/sh
sh /jffs/scripts/x3mRouting/nat-start $@

and

/jffs/scripts/x3mRouting/nat-start
Code:
#!/bin/sh
###########################################################################################################
# Script: nat-start
# Based on script openvpn-event from Xentrk for x3mRouting project
###########################################################################################################
# Script: openvpn-event
# Author: Xentrk
# Last Updated Date: 3-June-2019
#
# Description:
#   Original Script by John9527:
#   https://www.snbforums.com/threads/fork-asuswrt-merlin-374-43-lts-releases-v39e3.18914/page-238#post-294825
#
#   Modified by Xentrk for x3mRouting project
############################################################################################################
# shellcheck disable=SC2154
PROJECT_REPO="/jffs/scripts/x3mRouting"

scr_name="$(basename "$0")[$$]"
for vpn_id in $(ip rule | grep -oE 'ovpnc[1-5]' | sed 's/ovpnc//')
do
    vpn_if=tun1"$vpn_id"

    vpn_addr=$(ifconfig $vpn_if | grep -oE 'inet addr:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed 's/inet addr://')

    if [ "$vpn_addr" = "" ]; then
      continue
    fi

    vpn_mtu=$(ifconfig $vpn_if | grep -oiE 'mtu:[0-9]{1,4}' | sed 's/mtu://i')

    # Call appropriate script based on script_type
    vpn_script_name=vpnclient"$vpn_id"-route-up
    vpn_script_params="$vpn_mtu $vpn_mtu $vpn_addr"

    if [ -f "$PROJECT_REPO/$vpn_script_name" ]; then
      echo "Running $PROJECT_REPO/$vpn_script_name $vpn_script_params" | logger -t "$scr_name"
      sh $PROJECT_REPO/"$vpn_script_name" "$vpn_script_params"
    else
      echo "Script not defined for event: ""$vpn_script_name" | logger -t "$scr_name"
      continue
    fi

done

And it works ;-)
But only for clients. I have no openvpn server
 
Thanks for the idea.

Now I created two files
/jffs/scripts/nat-start
Code:
#!/bin/sh
sh /jffs/scripts/x3mRouting/nat-start $@

and

/jffs/scripts/x3mRouting/nat-start
Code:
#!/bin/sh
###########################################################################################################
# Script: nat-start
# Based on script openvpn-event from Xentrk for x3mRouting project
###########################################################################################################
# Script: openvpn-event
# Author: Xentrk
# Last Updated Date: 3-June-2019
#
# Description:
#   Original Script by John9527:
#   https://www.snbforums.com/threads/fork-asuswrt-merlin-374-43-lts-releases-v39e3.18914/page-238#post-294825
#
#   Modified by Xentrk for x3mRouting project
############################################################################################################
# shellcheck disable=SC2154
PROJECT_REPO="/jffs/scripts/x3mRouting"

scr_name="$(basename "$0")[$$]"
for vpn_id in $(ip rule | grep -oE 'ovpnc[1-5]' | sed 's/ovpnc//')
do
    vpn_if=tun1"$vpn_id"

    vpn_addr=$(ifconfig $vpn_if | grep -oE 'inet addr:[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}' | sed 's/inet addr://')

    if [ "$vpn_addr" = "" ]; then
      continue
    fi

    vpn_mtu=$(ifconfig $vpn_if | grep -oiE 'mtu:[0-9]{1,4}' | sed 's/mtu://i')

    # Call appropriate script based on script_type
    vpn_script_name=vpnclient"$vpn_id"-route-up
    vpn_script_params="$vpn_mtu $vpn_mtu $vpn_addr"

    if [ -f "$PROJECT_REPO/$vpn_script_name" ]; then
      echo "Running $PROJECT_REPO/$vpn_script_name $vpn_script_params" | logger -t "$scr_name"
      sh $PROJECT_REPO/"$vpn_script_name" "$vpn_script_params"
    else
      echo "Script not defined for event: ""$vpn_script_name" | logger -t "$scr_name"
      continue
    fi

done

And it works ;-)
But only for clients. I have no openvpn server
Thanks for reporting back.

Did you test by issuing the command "service restart_firewall".

What I was recommending is to put the contents of /jffs/scripts/x3mRouting/vpnclientX-route-up inside of /jffs/scripts/nat-start. But your solution should work too. Please note that when /jffs/scripts/nat-start is called, it doesn't pass the VPN parameters though. The "$@" parameter won't have any values. You can add the line echo $@ > /jffs/scripts/nat-start-parms to the /jffs/scripts/nat-start script to log the parms to see what if anything is being passed.
 
Okay, I installed x3mRouting successfully (op2 and op3).
Edit:

It was my original intent that people would select either option 2 or option 3 - but not both at the same time. However, they can coexist peacefully if you install option 2 first before installing option 3. Option 3 gives you the modified OpenVPN Client screen to selectively route IPSET lists thru an OpenVPN Client.

If you install option 2, an entry gets created in /jffs/scripts/init-start that mounts some custom code. If you then install option 3, the install script deletes the line created by option 2 and inserts a line that also mounts custom code associated with option 3. The only difference is the mounting of the customized OpenVPN Client screen. The other two files being mounted are the same in both options. I have ran with this setup for several months and didn't experience any conflicts.

You can use the command below to see if traffic is traversing the chain:

Code:
iptables -nvL PREROUTING -t mangle --line

The output will display the number of packets and bytes traversing the iptables rule which can be used as confirmation that traffic is being routed according to the rule
 
Last edited:
Edit:

It was my original intent that people would select either option 2 or option 3 - but not both at the same time. However, they can coexist peacefully if you install option 2 first before installing option 3. Option 3 gives you the modified OpenVPN Client screen to selectively route IPSET lists thru an OpenVPN Client.

If you install option 2, an entry gets created in /jffs/scripts/init-start that mounts some custom code. If you then install option 3, the install script deletes the line created by option 2 and inserts a line that also mounts custom code associated with option 3. The only difference is the mounting of the customized OpenVPN Client screen. The other two files being mounted are the same in both options. I have ran with this setup for several months and didn't experience any conflicts.

You can use the command below to see if traffic is traversing the chain:

Code:
iptables -nvL PREROUTING -t mangle --line

The output will display the number of packets and bytes traversing the iptables rule which can be used as confirmation that traffic is being routed according to the rule
Okay deleted the x3m and reinstalled. After that only installed op3.
Then created the IPSET with
Code:
sh load_MANUAL_ipset_iface.sh 2 rlist
Code:
(load_MANUAL_ipset_iface.sh): 23737 Starting Script Execution
(load_MANUAL_ipset_iface.sh): 23737 IPSET created: rlist hash:net family inet ha                             shsize 1024 maxelem 65536
(load_MANUAL_ipset_iface.sh): 23737 Selective Routing Rule via VPN Client 2 crea                             ted TAG fwmark 0x2000/0x2000
(load_MANUAL_ipset_iface.sh): 23737 Ending Script Execution
run
Code:
ipset list rlist
to see if it was created. and yes ips are listed with this command.
Code:
Name: rlist
Type: hash:net
Revision: 6
Header: family inet hashsize 1024 maxelem 65536
Size in memory: 7204
References: 1
Number of entries: 131
Members:
...
...
.
.
Checking with
Code:
iptables -nvL PREROUTING -t mangle --line
I got
Code:
Chain PREROUTING (policy ACCEPT 16984 packets, 6855K bytes)
num   pkts bytes target     prot opt in     out     source               destination
1     617K   73M MARK       all  --  *      *       192.168.1.0/24       192.168.1.2          MARK set 0x9
2     617K   73M RETURN     all  --  *      *       192.168.1.0/24       192.168.1.2
3      150 32450 MARK       all  --  br0    *       0.0.0.0/0            0.0.0.0/0            match-set rlist dst MARK or 0x2000
However, I check from browser to one of the listed websites, it doesn't seem to route through VPN.
2nd VPN client is ON and connected with Policy Rules (Strict) and exclusive DNS
 
Okay deleted the x3m and reinstalled. After that only installed op3.

However, I check from browser to one of the listed websites, it doesn't seem to route through VPN.
2nd VPN client is ON and connected with Policy Rules (Strict) and exclusive DNS
Did you create the at least one client record in on vpnclient page ? I.e. dummyvpn ?
Without it the appropriate routing didn't created.

Check by
Code:
 ip route show table ovpncX

where X - your vpnclient number
 
Thanks for reporting back.

Did you test by issuing the command "service restart_firewall".

What I was recommending is to put the contents of /jffs/scripts/x3mRouting/vpnclientX-route-up inside of /jffs/scripts/nat-start. But your solution should work too. Please note that when /jffs/scripts/nat-start is called, it doesn't pass the VPN parameters though. The "$@" parameter won't have any values. You can add the line echo $@ > /jffs/scripts/nat-start-parms to the /jffs/scripts/nat-start script to log the parms to see what if anything is being passed.

Yes, it was checked.
Moreover - it will run all possible vpnclientX-route-up, depending on the presence of appropriate rule in
Code:
ip rule
.
If rule is exists - it has sense to run appropriate route-up. And I can forget about it for a future.
When I will use other ovpn client, then now - it will run appropriate route-up
Moreover - I made a generation all params, which was usually passed to such scripts. Except a true remote MTU.
But, with your idea has a reason too :)
 
Did you create the at least one client record in on vpnclient page ? I.e. dummyvpn ?
Without it the appropriate routing didn't created.

Check by
Code:
 ip route show table ovpncX

where X - your vpnclient number
Yep that was the problem. Now it seemed to be fixed and properly routing. Thanks for the help @PeterV @Xentrk
 
@Xentrk, recently my letgo app (us.letgo.com/en) to sell/buy items online no longer work with my VPN. What wld the easiest way to bypass VPN?
 
@Xentrk, recently my letgo app (us.letgo.com/en) to sell/buy items online no longer work with my VPN. What wld the easiest way to bypass VPN?
Strange that site is blocking VPN. But some sites do that if someone tried to launch a DoS attach against the site using the VPN server you connect to.

I recommend using the DNSMASQ script to route the domain to the WAN0 interface per the example below:

Code:
sh /jffs/scripts/x3mRouting/load_DNSMASQ 0 LETGO us.letgo.com

Code:
nslookup us.letgo.com
Server:  bcm-adds1.bdms.co.th
Address:  10.154.10.31

Non-authoritative answer:
Name:    e6368.dscj.akamaiedge.net
Addresses:  2001:fb0:1019:1ac::18e0
          2001:fb0:1019:1be::18e0
          23.53.99.203
Aliases:  us.letgo.com
          us.letgo.com-v1.edgekey.net

I also suggest adding an IP address lookup site like whatismyip.com to the list so you can easily confirm if the traffic is routing to the WAN. If you go whatismyip.com, it should report your WAN IP address and not the VPN. Check that the list is populated after doing a lookup or accessing the website:

Code:
ipset -L LETGO
 
Strange that site is blocking VPN. But some sites do that if someone tried to launch a DoS attach against the site using the VPN server you connect to.

I recommend using the DNSMASQ script to route the domain to the WAN0 interface per the example below:

Code:
sh /jffs/scripts/x3mRouting/load_DNSMASQ 0 LETGO us.letgo.com

Do I add this to the nat-start file?
 
I am trying to route netflix traffic over vpn1 and have run into a snag with a chromecast. The routing works using the netflix app on my android phone but when I try to cast to the chromecast I get the dreaded proxy error.

I believe the problem lies within the hard coded DNS on the chromecasts, also I have read that the chromecasts now use DNS over TLS.

I am using the shell script method and this is my nat-start file.
Code:
#!/bin/sh

### IPSET Shell Script Method

sh /jffs/scripts/x3mRouting/load_ASN_ipset_iface.sh 1 NETFLIX AS2906
sh /jffs/scripts/x3mRouting/load_DNSMASQ_ipset_iface.sh 1 NETFLIX1 amazonaws.com,netflix.com,nflxext.com,nflximg.net,nflxso.net,nflxvideo.net,nflximg.com,netflix.net,nflxext.com,nflxso.net
iptables -t nat -A PREROUTING -s 192.168.0.0/24 -d 8.8.4.4 -p udp --dport 53 -j DNAT --to 162.168.0.1
iptables -t nat -A PREROUTING -s 192.168.0.0/24 -d 8.8.8.8 -p udp --dport 53 -j DNAT --to 162.168.0.1
iptables -t nat -A PREROUTING -s 192.168.0.0/24 -d 8.8.4.4 -p tcp --dport 53 -j DNAT --to 162.168.0.1
iptables -t nat -A PREROUTING -s 192.168.0.0/24 -d 8.8.8.8 -p tcp --dport 53 -j DNAT --to 162.168.0.1
ip6tables -I FORWARD --destination 2001:4860:4860::8844 -j REJECT
ip6tables -I FORWARD --destination 2001:4860:4860::8888 -j REJECT
iptables -A INPUT -p tcp --destination-port 853 -j DROP
iptables -A OUTPUT -p tcp --destination-port 853 -j DROP
What am I doing something wrong here?
Should I be using something like this instead of the PREROUTING/FORWARD/IN/OUT rules to route requests from the chromecast to port 53 and port 853(DoT) to vpn1?
Code:
iptables -t mangle -A PREROUTING -i br0 -m iprange --src-range <CHROMECAST_IP> -p tcp -m multiport --dport 53,853 -j MARK --set-mark 0x1000/0x1000
iptables -t mangle -A PREROUTING -i br0 -m iprange --src-range <CHROMECAST_IP> -p udp -m multiport --dport 53,853 -j MARK --set-mark 0x1000/0x1000
Also, thanks for the excellent work on this project Xentrk.
 

Similar threads

Support SNBForums w/ Amazon

If you'd like to support SNBForums, just use this link and buy anything on Amazon. Thanks!

Sign Up For SNBForums Daily Digest

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

Members online

Top