1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.
Dismiss Notice

Welcome To SNBForums

SNBForums is a community for anyone who wants to learn about or discuss the latest in wireless routers, network storage and the ins and outs of building and maintaining a small network.

If you'd like to post a question, simply register and have at it!

While you're at it, please check out SmallNetBuilder for product reviews and our famous Router Charts, Ranker and plenty more!

Killswitch: move to next VPN client in line?

Discussion in 'Asuswrt-Merlin' started by Merlin99, Jan 12, 2018.

  1. Merlin99

    Merlin99 New Around Here

    Joined:
    Jan 3, 2018
    Messages:
    5
    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
     
  2. Please support SNBForums! Just click on this link before you buy something from Amazon and we'll get a small commission on anything you buy. Thanks!
  3. JJQuin

    JJQuin Regular Contributor

    Joined:
    Jan 10, 2018
    Messages:
    54
    Location:
    USA
    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.
     
  4. Martineau

    Martineau Very Senior Member

    Joined:
    Jul 8, 2012
    Messages:
    1,699
    Location:
    UK
    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))" $$ [email protected]
    }
    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: Jan 13, 2018
  5. JJQuin

    JJQuin Regular Contributor

    Joined:
    Jan 10, 2018
    Messages:
    54
    Location:
    USA
    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!
     
  6. Stephen Becker

    Stephen Becker Occasional Visitor

    Joined:
    Apr 13, 2016
    Messages:
    21
    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: Jan 13, 2018
  7. Merlin99

    Merlin99 New Around Here

    Joined:
    Jan 3, 2018
    Messages:
    5
    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)?
     
  8. Stephen Becker

    Stephen Becker Occasional Visitor

    Joined:
    Apr 13, 2016
    Messages:
    21
    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.
     
  9. Martineau

    Martineau Very Senior Member

    Joined:
    Jul 8, 2012
    Messages:
    1,699
    Location:
    UK
    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.

    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]
     
  10. Stephen Becker

    Stephen Becker Occasional Visitor

    Joined:
    Apr 13, 2016
    Messages:
    21
    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: Jan 15, 2018
  11. JJQuin

    JJQuin Regular Contributor

    Joined:
    Jan 10, 2018
    Messages:
    54
    Location:
    USA
    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: Jan 21, 2018
Please support SNBForums! Just click on this link before you buy something from Amazon and we'll get a small commission on anything you buy. Thanks!