What's new

Killswitch: move to next VPN client in line?

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

Merlin99

New Around Here
Hi,

Merlin 380.69 on RT-AC87U.

I have 2 VPN clients setup, killswitch is active for both. All settings are equal, apart from the server address obviously.

With the killswitch enabled, if VPN tunnel goes down, does Merlin activate the next VPN client in line, or does it cut off the internet access for VPN traffic until I manually enable 1 of the 2 clients again?

Thanks
 
As I understand it, if you have 2 VPN clients setup, you should be using selective routing and routing specific devices into each VPN tunnel. If one of the VPN tunnels goes down, only the devices that are configured in the selective routing for that VPN tunnel will go down if the kill switch is active.

I'm not sure what would happen if you set the same devices to go through both VPN tunnels. I wouldn't recommend it.

I have 2 VPN services and would love to be able to setup the router so if one VPN tunnel when down it would automatically activate a 2nd one as a backup and alert me via email. I have tried to find a script that does this but on luck yet.
 
I have 2 VPN services and would love to be able to setup the router so if one VPN tunnel when down it would automatically activate a 2nd one as a backup and alert me via email. I have tried to find a script that does this but on luck yet.

A very crude script, but can be invoked by the openvpn-event trigger scripts or hack firmware script vpnrouting.sh

Code:
#!/bin/sh
VER="v1.03"
#======================================================================================================= © 2016-2018 Martineau, v1.03
#
# Check every 30 secs, and switch to alternate VPN Client if current VPN Client is DOWN
#
#          VPN_Failover   [-h|help] {vpn_instance to monitor}
#
#          VPN_Failover
#                         Monitor VPN Client 1 (default) every 30 secs and if DOWN switch to VPN Client 2 and script monitor VPN Client 2       
#          VPN_Failover   2
#                         Monitor VPN Client 2           every 30 secs and if DOWN switch to VPN Client 1 and script monitor VPN Client 1
#
# Script may be scheduled by openvpn-event vpnclientX-up
#
#       VPN_ID=${dev:4:1}
#       sh VPN_Failover.sh $VPN_ID &

# Print between line beginning with'#==' to first blank line inclusive
ShowHelp() {
 awk '/^#==/{f=1} f{print; if (!NF) exit}' $0
}
SayT(){
   logger -t "($(basename $0))" $$ $@
}
ANSIColours () {
 cRESET="\e[0m";cBLA="\e[30m";cRED="\e[31m";cGRE="\e[32m";cYEL="\e[33m";cBLU="\e[34m";cMAG="\e[35m";cCYA="\e[36m";cGRA="\e[37m"
 cBGRA="\e[90m";cBRED="\e[91m";cBGRE="\e[92m";cBYEL="\e[93m";cBBLU="\e[94m";cBMAG="\e[95m";cBCYA="\e[96m";cBWHT="\e[97m"
 aBOLD="\e[1m";aDIM="\e[2m";aUNDER="\e[4m";aBLINK="\e[5m";aREVERSE="\e[7m"
 cRED_="\e[41m";cGRE_="\e[42m"
}


ANSIColours

MYROUTER=$(nvram get computer_name)

# Need assistance ?
if [ "$1" == "-h" ] || [ "$1" == "help" ];then
 echo -e $cBWHT
 ShowHelp
 echo -e $cRESET
 exit 0
fi

if [ -d "/tmp/mnt/"$MYROUTER ];then
 MOUNT="/tmp/mnt/"$MYROUTER
else
 MOUNT="/tmp"
fi

VPN_ID=1       # Default VPN Client to Check
if [ ! -z "$1" ];then
 VPN_ID=$1
fi

# Loop forever and check VPN Client status every 30 secs
while true
 do

  TRACKFILE="${MOUNT}/vpnclient$VPN_ID"
  LOCKFILE=$TRACKFILE"-monitor"
 
  echo $$ >$LOCKFILE
 
  SayT "VPN Client Monitor: Starting.....(using '"$LOCKFILE"')"
  echo -e $cBYEL"\n\tVPN Client Monitor: Starting.....\n"
 
  SayT "**VPN Client Monitor: Checking VPN Client" $VPN_ID "connection status...."
  echo -e $cBYEL"\tVPN Client Monitor: Checking VPN Client" $VPN_ID "connection status...."
 
  if [ "$(nvram get "vpn_client"${VPN_ID}"_state")" != "2" ];then   # Connected ?
   case "$VPN_ID" in
    1) NEW_VPN_ID=2   # VPN Client 1 is DOWN?; Switch to VPN Client 2
     ;;
    2) NEW_VPN_ID=1   # VPN Client 2 is DOWN?; Switch to VPN Client 1
     ;;
    3) NEW_VPN_ID=3   # Bounce VPN Client 3
     ;;
   esac
 
   # Status could be either 'Connecting' or Disconnecting so stop it anyway?
   RC=$(service stop_vpnclient${VPN_ID})
 
   if [ "$(nvram get "vpn_client"${VPN_ID}"_state")" != "0" ];then
    sleep 30
   fi
 
   SayT "**VPN Client Monitor: Switching VPN Client" $VPN_ID "to VPN Client" $NEW_VPN_ID
   echo -e $cBGRE"\a\t\tRequesting VPN Client" $NEW_VPN_ID
   RC=$(service restart_vpnclient${NEW_VPN_ID})
 
   sleep 30   # Allow for VPN Client to connect
 
   if [ "$(nvram get "vpn_client"${NEW_VPN_ID}"_state")" != "2" ];then
    SayT "***ERROR VPN Client Monitor: VPN Client" $NEW_VPN_ID "FAILED to start"
    echo -e ${cBRED}$aBLINK"\a\n\n\t***ERROR VPN Client Monitor: VPN Client" $NEW_VPN_ID "FAILED to start\n"
    echo -e $cRESET
    exit 99
   fi
 
   VPN_ID=$NEW_VPN_ID
   
  else
   SayT "VPN Client" $VPN_ID "status OK"
   echo -e $cBGRE"\tVPN Client Monitor: VPN Client" $VPN_ID "connection status OK"
  fi

  echo -e $cBCYA"\tVPN Client Monitor: Paused checking VPN Client" $VPN_ID "for 30 secs"
  sleep 30
 
  # Check for external kill switch
  if [ ! -f $LOCKFILE ];then
   SayT "VPN Client Monitor: Monitoring VPN Client" $VPN_ID "terminated ('"$LOCKFILE"' not found)"
   echo -e $cBYEL"\a\t\tVPN Client Monitor: Monitoring VPN Client" $VPN_ID "terminated ('"$LOCKFILE"' not found)\n"$cRESET
   break
  fi
 
  done
 
echo -e $cRESET

exit 0
 
Last edited:
Wow thanks! Gonna test it tonight after my family goes to sleep :) I've been banned from messing with the router in the evenings when they're all using the internet!
 
Another approach you could take is leaving them both connected all of the time. If you don't care which one is primary then that is all you need to do. If they are both active, the router will do some kind of crude load-balancing between them (not that it matters, they are sharing the same WAN connection). If one goes down, it will be removed from the routing table and not used until it reconnects.

If you do care which one is primary, then you can write a simple vpn script to change the routing table to lower the priority of the one you don't want to use.
Create a file /jffs/scripts/openvpn-event with the below commands, it will run every time a VPN tunnel changes states
#!/bin/sh

route del -net 128.0.0.0 netmask 128.0.0.0 dev tun12
route del -net default netmask 128.0.0.0 dev tun12
route add -net 128.0.0.0 netmask 128.0.0.0 dev tun12 metric 100
route add -net default netmask 128.0.0.0 dev tun12 metric 100

This assumes you want to lower the priority of tun12, which should be client 2. Setting a metric 100 sets the route at a higher cost, which tells the router to only use it if lower cost options are not available.

Note, I am recreating the routes without a Gateway, which should be fine because VPN tunnels are considered point-to-point interfaces and work without a GW. The gateway will likely change between sessions, so you don't want to hard-code it. If you want to get fancy, you could first read the existing gateway into a variable and provide it when recreating the routes. Another nice enhancement would be first checking to see if the commands need to run (is there a tun12 route? is the metric already set?). I am not a script junkie, and wanted to keep this super basic. This should work as-is, even if it isn't as elegant as it could be.
 
Last edited:
Another approach you could take is leaving them both connected all of the time.

I should have mentioned that both VPN clients are from the same provider (PIA). With same settings, policy rules, etc, just a different server address. Both are UDP 1197 (the "strong" version as PIA calls it).

I assumed only 1 of the 2 VPN clients should/could be active at a given point. Are you saying I can activate both VPN clients (PIA UK 1 and PIA UK 2) at the same time, routing the same devices through both tunnels? Then if a tunnel goes down, the second tunnel acts as a failover automatically?

If so, are there any disadvantages of doing this (stability, speed, quality)?
 
If the provider allows it, then yes, it would be possible. If they do not allow simultaneous logins, or if both connections get assigned the same virtual IP address, then no, it would not be possible. This falls in the category of "try it and see." It might be a simple solution, or it might be better going with a script like you originally described.

Here are the things to keep in mind.
  • The router *might* try to establish one tunnel through the other, which would be really bad. I would hope it is designed to prevent this, but there is a chance Merlin did not add any kind of protection against that when he added multiple client support. If it is a problem, you could create static routes to the VPN servers to ensure they use the WAN interface, and not the tunnel interface.
  • If a tunnel fails in a way that does not cause it to disconnect, the router will not realize it is down and will keep trying to use it.
  • If one tunnel works, and the other does not work but is still being used, the result will be really strange and inconstant problems, which may be harder to troubleshoot (until you realize the problem, then the fix it simple).
  • Even if the tunnel does disconnect, there could be a delay longer than you are happy with for the router to mark the tunnel down.
  • Using both tunnels at the same time may mean that a single user could have sessions on both tunnels, which shouldn't be a problem, but it worth noting.
  • Assuming everything else works as expected, there should be no performance issues, the cost of using a tunnel is CPU time on the router to encrypt/decrypt each packet that passes. There is very minimal overhead in maintaining the 2nd tunnel.
 
I assumed only 1 of the 2 VPN clients should/could be active at a given point. Are you saying I can activate both VPN clients (PIA UK 1 and PIA UK 2) at the same time,

You should be able to have two concurrent VPN sessions from the same VPN ISP if you ensure that you use different ports i.e. 1194 and say 553 (if available) for the two clients. This should ensure unique VPN client sockets but sometimes the VPN subnets overlap and it won't work.

....routing the same devices through both tunnels?

Selective Routing creates RPDB entries using fixed 'prio' priority entries:
e.g. if say you define 192.168.1.123 to both the Selective routing tables, the following RPDB rules are created:
Code:
10101: from 192.168.1.123 lookup ovpnc1
10201: from 192.168.1.123 lookup ovpnc2

So even if VPN Client 1 isn't up, RPDB rule 10101 takes precedence, and the selective routing via route table ovpnc2 is never used.

NOTE: This is the current (although fixable) flaw in my crude script.[/CODE]
 
You actually don't need the two VPNs to use different port numbers. The router (or any device) is able to establish multiple sockets to the same destination port number (otherwise it would be impossible to use more than one webpage at a time). The comment about overlapping addresses is valid, which is why you need to test. Assuming you are connecting to different data centers owned by the same provider, they probably use different addresses, but maybe not.

I probably should have mentioned this sooner, but if the provider only has one data center, this entire exercise becomes pretty pointless. The "servers" you connect to are actually load-balancers that represent multiple servers. Connecting to two different load-balancers at the same datacenter representing the same servers is pointless. You may be able to tell simply by looking at their IP addresses (if everything but the last octet is the same), but the main way to tell is do a traceroute to each and look for similarities, if the last few hops are the same, then you are passing through the same infrastructure.
 
Last edited:
So I finally got around to testing this (had issues earlier in the week had to deal with first). Not sure what's happening and I'm still a noob at this so I'm not sure how to diagnose the issue. I added the route settings to my openvpn-event and changed both my OpenVPN Clients so they cover the same small group of IPs (didn't want the test affecting my family :) ). The 2nd VPN client is connected fine but the 1st one connects with no public address. I changed the Redirect Internet traffic from policy routing strict to policy routing. I also disabled both VPN clients killswitches. Tried messing around with the order they start but no luck. I did confirm the route tables were correct.

Btw, I'm using two different VPN services in the 2 clients. PIA on the 1st and NordVPN on the 2nd, so I know it's not the same server or port issue. Any ideas on how I can diagnose this?

Thanks

Found the following in the log:

Code:
Jan 21 00:29:02 ovpn-client1[11690]: Ignore conflicted routing rule: 0.0.0.0 128.0.0.0
Jan 21 00:29:02 ovpn-client1[11690]: Ignore conflicted routing rule: 128.0.0.0 128.0.0.0
Jan 21 00:36:01 custom_script: Running /jffs/scripts/openvpn-event (args: tun11 1500 1622 10.10.10.10 10.10.10.9 init)
Jan 21 00:36:01 ovpn-client1[11690]: ERROR: Linux route delete command failed: external program exited with error status: 2
Jan 21 00:36:01 ovpn-client1[11690]: /bin/ip addr del dev tun11 local 10.10.10.10 peer 10.10.10.9
Jan 21 00:36:01 ovpn-client1[11690]: updown.sh tun11 1500 1622 10.10.10.10 10.10.10.9 init
 
Last edited:

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