What's new

Clear/delete vpn profile from router?

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

Hi, Martineau

I discover few thing i vpnrouting.sh wrong client "number vpn_client2_clientlist" should be "3" and double of "PARAM=$*"

<snip>

elif [ "$dev" == "tun12" ]
then
VPN_IP_LIST=$(nvram get vpn_client2_clientlist)
VPN_TBL=112
VPN_REDIR=$(nvram get vpn_client2_rgw)
VPN_FORCE=$(nvram get vpn_client2_enforce)
VPN_UNIT=2
VPN_CLIENT_ADDR=$(nvram get vpn_client2_addr)
elif [ "$dev" == "tun13" ]
then
VPN_IP_LIST=$(nvram get vpn_client2_clientlist) <<<=== wrong client number
VPN_TBL=113
VPN_REDIR=$(nvram get vpn_client3_rgw)
VPN_FORCE=$(nvram get vpn_client3_enforce)
VPN_UNIT=3
VPN_CLIENT_ADDR=$(nvram get vpn_client3_addr)

<snip>

octopus
 
Last edited:
Hi, Martineau

I discover few thing i vpnrouting.sh wrong client "number vpn_client2_clientlist" should be "3" and double of "PARAM=$*"

octopus


RMerlin has already fixed this typo in 380.58 Alpha-gcf77301 and rewritten the code....

Code:
# Begin
################################### Martineau Hack
if [ "$1" = "wan_block" ]; then
    dev=$2
fi
##################################################
if [ "$dev" == "tun11" ]
then
    VPN_IP_LIST=$(nvram get vpn_client1_clientlist)
    VPN_REDIR=$(nvram get vpn_client1_rgw)
    VPN_FORCE=$(nvram get vpn_client1_enforce)
    VPN_UNIT=1
elif [ "$dev" == "tun12" ]
then
    VPN_IP_LIST=$(nvram get vpn_client2_clientlist)
    VPN_REDIR=$(nvram get vpn_client2_rgw)
    VPN_FORCE=$(nvram get vpn_client2_enforce)
    VPN_UNIT=2
elif [ "$dev" == "tun13" ]
then
    VPN_IP_LIST=$(nvram get vpn_client3_clientlist)
    VPN_REDIR=$(nvram get vpn_client3_rgw)
    VPN_FORCE=$(nvram get vpn_client3_enforce)
    VPN_UNIT=3
elif [ "$dev" == "tun14" ][

<snip>

# webui reports that vpn_force changed while vpn client was down
################################################### Martineau Hack
#if [ $script_type = "rmupdate" ]
if [ "$script_type" = "rmupdate" -o $1 == "wan_block" ]
##################################################################
/CODE]
 
Okey, nice. Have you link to github so i can se new rewritten code?
Or maby dump it from 380 if you have it running?

Thanks
Octopus
 
Last edited:
@john9527 : Looking at this commit:

https://github.com/john9527/asuswrt-merlin/commit/2ebc49faa9b5fdd2362275d6801c7d49e55ce086

What it does is only remove these entries from the client (111-115) tables, is that correct? I know I'm already removing them from the main table here:

Code:
if [ $script_type == "route-up" ]
then
        init_table

# Delete existing VPN routes that were pushed by server on table main
        NET_LIST=$(ip route show|awk '$2=="via" && $3==ENVIRON["route_vpn_gateway"] && $4=="dev" && $5==ENVIRON["dev"] {print $1}')
        for NET in $NET_LIST
        do
                ip route del $NET dev $dev
                logger -t "openvpn-routing" "Removing route for $NET to $dev from main routing table"
        done

Which gives me this in syslog:

Code:
Mar 15 00:23:38 rc_service: service 2701:notify_rc updateresolv
Mar 15 00:23:40 openvpn[2623]: /usr/sbin/ip route add 198.7.62.204/32 via 198.48.xxx.yyy (wan IP)
Mar 15 00:23:40 openvpn[2623]: /usr/sbin/ip route add 0.0.0.0/1 via 10.9.3.37
Mar 15 00:23:40 openvpn[2623]: /usr/sbin/ip route add 128.0.0.0/1 via 10.9.3.37
Mar 15 00:23:40 openvpn[2623]: /usr/sbin/ip route add 10.9.0.1/32 via 10.9.3.37
Mar 15 00:23:40 openvpn-routing: Configuring policy rules for client 2
Mar 15 00:23:40 openvpn-routing: Creating VPN routing table
Mar 15 00:23:40 openvpn-routing: Removing route for 10.9.0.1 to tun12 from main routing table
Mar 15 00:23:40 openvpn-routing: Removing route for 0.0.0.0/1 to tun12 from main routing table
Mar 15 00:23:40 openvpn-routing: Removing route for 128.0.0.0/1 to tun12 from main routing table
Mar 15 00:23:40 openvpn-routing: Adding route for 0.0.0.0 to 45.56.96.24 through VPN client 2
Mar 15 00:23:40 openvpn-routing: Completed routing policy configuration for client 2

If that's what your change does, I guess it would be simpler to move my code two lines up, just before init_table. There's no need to explicitly look for 0.0.0.0/128.0.0.0, as those are already properly removed with my code (as shown by my log entries).

Unless your code covers a particular scenario that isn't properly handled with the existing code. My code only gets called on a route-up event, while yours gets called every time the vpnrouting.sh script is called.
 
What it does is only remove these entries from the client (111-115) tables, is that correct?
Wow....going back to August....I sometimes have trouble remembering last week :)

The intent is what you stated.....if I remember correctly there was a case I found with multiple clients active where the main table could be repopulated with those entries after they had been removed. But memory is definitely a bit fuzzy.....
 
Wow....going back to August....I sometimes have trouble remembering last week :)

The intent is what you stated.....if I remember correctly there was a case I found with multiple clients active where the main table could be repopulated with those entries after they had been removed. But memory is definitely a bit fuzzy.....

Just trying to catch up on your January discussions, and a look at your repo only showed that single commit from August :)

I was initially tempted to move my cleanup code before init_table so both the main and vpnc tables would be cleaned up. My main worry however is if the VPN server pushes some special routes that must be routed through the VPN server, beside the 0.0.0.0/128.0.0.0 default routes. For example, if the server was to push a route to an internal LAN server (not all servers are public tunnel providers, could be a user's site-to-site tunnel for instance). That's why it might be safer to keep all those routes in the vpnc tables, and only clean them from the main table.
 
Just trying to catch up on your January discussions, and a look at your repo only showed that single commit from August :)

I was initially tempted to move my cleanup code before init_table so both the main and vpnc tables would be cleaned up. My main worry however is if the VPN server pushes some special routes that must be routed through the VPN server, beside the 0.0.0.0/128.0.0.0 default routes. For example, if the server was to push a route to an internal LAN server (not all servers are public tunnel providers, could be a user's site-to-site tunnel for instance). That's why it might be safer to keep all those routes in the vpnc tables, and only clean them from the main table.

RMerlin, two issues were addressed by myself and @john9527 during your temporary absence.

1. PARAM args were not being passed from vpnrouting.sh to openvpn-event (Patch by @john9527)
2. Routes 128.0.0.0/0.0.0.0 were not being removed from table main for multiple VPN Client connections (Patch by @john9527 / Hack by @Martineau)

My requirement is to create simple RPDB tables containing at most ONLY three entries - hence hacks to your vpnrouting.sh script.
(Clearly in the example below, only the 'default' line is actually required, the other two lines shown are my optional custom requirements.)

e.g. ovpnc2

Code:
ip route show table 112

10.3.0.0/24 dev br3  scope link
10.8.0.0/24 dev tun21  scope link
default via 10.200.5.19 dev tun12

Your code relies on the fact that table main correctly identifies the $dev that relates to the two VPN Client routes 128.0.0.0/0.0.0.0 but in my case (as described back in July) it is always incorrect for more than one ACTIVE VPN Client.

Consequently my (non-subtle) indiscriminate hack (unlike @john9527's) is as follows:

Code:
init_table(){
logger -t "openvpn-routing" "Creating VPN routing table"
ip route flush table $VPN_TBL

# Fill it with copy of existing main table
########################################################################################## Martineau Hack
logger -t "openvpn-routing" "Martineau Removing routes 0.0.0.0/1,128.0.0.0/1 from table main"
ip route delete 0.0.0.0/1 2> /dev/null > /dev/null
ip route delete 128.0.0.0/1 2> /dev/null > /dev/null
logger -t "openvpn-routing" "Martineau Skipping cloning of ALL routes from table main to table" $VPN_TBL
#ip route show table main | while read ROUTE
#do
#ip route add table $VPN_TBL $ROUTE
#done
##########################################################################################
}
# Begin
########################################################################################## Martineau Hack
if [ "$1" = "wan_block" ]; then
dev=$2
fi
##########################################################################################


I acknowledge why you elect to clone the contents of table main, but I suspect for most configurations, obscure esoteric routes pushed by a VPN server are usually non-existent...although I believe for AirVPN clients the cloning of table main is mandatory??

Furthermore, there are a couple of additional VPN Client issues so I have resorted to not using the VPN GUI to manage my VPN Client connections but reluctantly now utilise a script - together with another vpnrouting.sh hack. :eek:

i.e. a custom script VPN_Client_Switch.sh called from wan-start (and can also be scheduled via cron or on demand from command line) that

1. Eliminates the spurious/innocuous 'Error Routing' conflict VPN Status GUI message
2. Ensures that WAN blocking is always enforced if the VPN is taken down manually (or during router boot time BEFORE an attempt is made to actually start the VPN Client)


Code:
admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh 2 on

(VPN_Client_Switch.sh): 10951 Starting VPN Client 2
(VPN_Client_Switch.sh): 10951 Flushing VPN Client 2 route 192.157.56.146
(VPN_Client_Switch.sh): 10951 Waiting for VPN Client 2 to connect.....
(VPN_Client_Switch.sh): 10951 VPN Client 2 connect'd in 8 secs
(VPN_Client_Switch.sh): 10951 Complete.

....and when terminating a VPN Client connection, I ensure that WAN blocking (if configured) is enforced by exploiting your script :D

Code:
admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh 2 off

(VPN_Client_Switch.sh): 11456 Stopping VPN Client 2
(VPN_Client_Switch.sh): 11456 Martineau Blocking WAN for VPN Client 2 to 192.157.56.146
(vpnrouting.sh): 11510 Patched by John9527/Martineau /usr/sbin/vpnrouting.sh wan_block tun12
(VPN_Client_Switch.sh): 11456 Waiting for VPN Client 2 to disconnect.....
(VPN_Client_Switch.sh): 11456 VPN Client 2 disconnect'd in 2 secs
(VPN_Client_Switch.sh): 11456 ....and VPN Client 'off' requested.
(VPN_Client_Switch.sh): 11456 Complete.

admin@RT-AC68U:/jffs/scripts# ip route show table ovpnc2

prohibit default


This is the additional vpnrouting.sh hack (together with the one shown above) to allow me to call your script to enforce the WAN blocking

Code:
# webui reports that vpn_force changed while vpn client was down
########################################################################################## Martineau Hack
#if [ $script_type = "rmupdate" ]
if [ "$script_type" = "rmupdate" -o "$1" == "wan_block" ]
##########################################################################################


NOTE: In init-start I also have appropriate calls to vpnrouting.sh with modified args 'wan_block tun1x'

Code:
Aug  1 01:00:16 openvpn-routing: Refreshing policy rules for client 2
Aug  1 01:00:16 openvpn-routing: Creating VPN routing table
Aug  1 01:00:16 openvpn-routing: Martineau Removing routes 0.0.0.0/1,128.0.0.0/1 from table main
Aug  1 01:00:16 openvpn-routing: Martineau Skipping cloning of ALL routes from table main to table ovpnc2
Aug  1 01:00:16 openvpn-routing: Tunnel down - VPN client access blocked
Aug  1 01:00:16 kernel: Found a AMD NAND flash:

Perhaps I should learn how to submit Pull requests to GIT to report 'tweaks/bugs' :p

P.S. Was it intentional when you decided to implement my suggest of tagging the VPN client RPDB tables in /etc/iproute2/rt_tables...you intentionally made it read ONLY!!!!???? :(
 
Last edited:
@Martineau
Do you have any files i can test?

Thanks
octopus
 
1. PARAM args were not being passed from vpnrouting.sh to openvpn-event (Patch by @john9527)

Openvpn-event was only intended to be used with the environmental variables passed to it by OpenVPN. It shouldn't be a problem extending that to also pass the arguments passed as parameters to vpnrouting.sh.

2. Routes 128.0.0.0/0.0.0.0 were not being removed from table main for multiple VPN Client connections (Patch by @john9527 / Hack by @Martineau)

Your code relies on the fact that table main correctly identifies the $dev that relates to the two VPN Client routes 128.0.0.0/0.0.0.0 but in my case (as described back in July) it is always incorrect for more than one ACTIVE VPN Client.

What device is it using in your test case?

Consequently my (non-subtle) indiscriminate hack (unlike @john9527's) is as follows:

In your case, I would look at two "cleaner" solutions instead:

1) Use a "route-delay 2" in your custom config. This is what VPNBook uses in their client.ovpn file, and it's working fine for me, even when I connected to two tunnels at once (using two of their different servers, of course)
2) Disable any route pull in your client, by using "route-nopull"


I acknowledge why you elect to clone the contents of table main, but I suspect for most configurations, obscure esoteric routes pushed by a VPN server are usually non-existent...although I believe for AirVPN clients the cloning of table main is mandatory??

The OpenVPN client isn't just for connecting to a tunnel provider to redirect Internet traffic, it can also be used to connect to a remote office, to establish a site-to-site VPN. And I know at least one VPN tunnel provider that pushes a long list of routes, presumably to redirect only specific sites (Netflix perhaps? I can't remember) through them. I've seen at least two users already using that particular service.

2. Ensures that WAN blocking is always enforced if the VPN is taken down manually (or during router boot time BEFORE an attempt is made to actually start the VPN Client)

Not blocking on manual down is by design. I want a user-initiated down to be a COMPLETE down of the VPN facility, not just half of it, otherwise someone who decides to temporarily disable everything would also need to change his configuration. This would also open the door to hard-to-troubleshoot issues ("Why is my Internet no longer working?")

Being blocked at boot time however should already be implemented (and was working back when I implemented and tested it). I'm not doing it as early as WAN start however, so there might still be a small window open there between WAN start and VPN start. Doing it too early might be tricky, as a lot of WAN-related stuff might also be manipulating the routing tables.

P.S. Was it intentional when you decided to implement my suggest of tagging the VPN client RPDB tables in /etc/iproute2/rt_tables...you intentionally made it read ONLY!!!!???? :(

No, just a design limitation. The file is stored in flash and not dynamically generated. I didn't feel it was necessary to dynamically generate it in RAM since it wouldn't survive a reboot anyway, and any user changes would be lost. So either way, you'd need a script that would either bind mount it to your own copy that's in JFFS, or you'd need to re-add your entries to any dynamically generated copy. Since both cases required a user script, I went with the design that was the simplest and most efficient for the majority of users, and used a static file located in flash, and symlinked at boot time.
 
Last edited:
is it possible to do it with a "hidden" ram variable or added to gui with default "no" to those want wan blocked ?
Block routed clients if tunnel goes down: always
Not blocking on manual down is by design. I want a user-initiated down to be a COMPLETE down of the VPN facility, not just half of it, otherwise someone who decides to temporarily disable everything would also need to change his configuration. This would also open the door to hard-to-troubleshoot issues ("Why is my Internet no longer working?")

Being blocked at boot time however should already be implemented (and was working back when I implemented and tested it).
 
is it possible to do it with a "hidden" ram variable or added to gui with default "no" to those want wan blocked ?
Block routed clients if tunnel goes down: always

There's already far too many settings related to OpenVPN for my taste, I don't want to add any, especially for such nice needs, sorry.
 
@Martineau

Do you have any files i can test?
Thanks
octopus

But there is nothing to test as everything is 'working' as designed! ;)

However, if you want to use a script to manage your VPN Client connections etc....

PART 1

VPN_Client_Switch.sh

Code:
#!/bin/sh

# Switch between VPN Clients and remove obsolete VPN Client routes from table main otherwise Get_ActiveVPN() will never match "2"
#
# See comments at bottom of script for command line args syntax.

# FUNCTIONS
# =========
Say(){
   logger -st "($(basename $0))" $$ $@
}

Get_VPN_ADDR() {
local VPNADDRS=`nvram show | grep vpn_client | grep addr | grep -v t_addr`
local VPN_ADDR=""

for VPN in $VPNADDRS
do
   if [ "${VPN:10:1}" = "$1" ]; then
      VPN_ADDR=${VPN:17}
      #Say "ACTIVE VPN Client="$1 "via" $VPN_ADDR
   #else
   #   Say "Get_VPN_ADDR():" $VPN ">" ${VPN:10:1} ">>" ${VPN:17} 
   fi

done

echo $VPN_ADDR
}

Flush_VPN_ROUTE() {
      local VPN_ADDR=$(Get_VPN_ADDR $1)
      local VPNTAG=`grep -i "11"$1 /etc/iproute2/rt_tables | awk '{print $2}'`
      Say "Flushing VPN Client" $1 "route" $VPN_ADDR "("$VPNTAG")"
      ip route del $VPN_ADDR 2> /dev/null > /dev/null
}

Get_ActiveVPN() {
local VPNS=`nvram show | grep vpn_client | grep state | sort -r`        # 'sort -r' ensures the lowest numerically VPN instance is returned
local VPN=""
local ACTIVE_VPN=""
local ACTIVE_CNT=0
local VPNTAG="?"

if [ "$1" = "?" ]; then
    Say "VPN Client Status:"
fi   

for VPN in $VPNS
do
   if [ ${VPN:18:1} = "2" ]; then
      if [ ! -z "$1" ]; then
         if [ "$1" = "?" ]; then
            VPNTAG=`grep -i "11"${VPN:10:1} /etc/iproute2/rt_tables | awk '{print $2}'`
            Say " Client" ${VPN:10:1} "connected ("$VPNTAG")"
            ACTIVE_CNT=`expr $ACTIVE_CNT + 1`
         fi
         if [ "${VPN:10:1}" = "$1" ]; then
            ACTIVE_VPN=${VPN:10:1}
            #Say " Get_ActiveVPN(): Matched! ACTIVE_VPN="$ACTIVE_VPN
            break
         fi
      else
         ACTIVE_VPN=${VPN:10:1}
         #Say " Get_ActiveVPN(): Found active" $VPN ">" ${VPN:10:1} ">>" ${VPN:18:1}
      fi
   else
         if [ "$1" = "?" ] && [ "$2" = "debug" ]; then
        Say " Get_ActiveVPN():" $VPN ">" ${VPN:10:1} ">>" ${VPN:18:1}
      fi
     
         if [ "$1" = "fix" ] && [ ${VPN:18:1} = "-" ]; then
         Say " Get_ActiveVPN(): Fixing state for" $VPN
         ACTIVE_VPN=${VPN:10:1}
         RC=$(nvram set "vpn_client"$ACTIVE_VPN"_state=2")
      fi     
   fi
done

if [ "$ACTIVE_CNT" = "0" ] && [ "$1" = "?" ]; then
   Say " *NO VPN Clients connected*"
fi

echo $ACTIVE_VPN
}

Check_VPNState(){
      local i=0
      local OK=0
      local VPNTAG=`grep -i "11"$1 /etc/iproute2/rt_tables | awk '{print $2}'`
     
      if [ "$2" = "2" ]; then
         local WSTATE="connect"
      fi
      if [ "$2" = "0" ]; then
         local WSTATE="disconnect"
      fi
      Say "Waiting for VPN Client" $1 "("$VPNTAG") to" $WSTATE"....."
      while [ $i -lt 60 ]; do
        sleep 1
        #Say "Waiting for VPN Client" $1 "to" $WSTATE"....." $i
        if [ "$(nvram get "vpn_client"$1"_state")" = "$2" ];then
           OK="1"
           break
        fi
        i=`expr $i + 1`
      done
      if [ "$OK" = "1" ];then
            Say "VPN Client" $1 "("$VPNTAG")" $WSTATE"'d in" $i "secs"
      else
            Say "***ERROR*** VPN Client" $1 "("$VPNTAG") FAILED to" $WSTATE "after" $i "secs"
      fi
}

Main(){

#Say "Main(): Debug ACTIVE_VPN='"$ACTIVE_VPN"'"
#Say "Main(): NEW_VPN='"$NEW_VPN"'"
#Say "Main(): MATCH_VPN='"$MATCH_VPN"'"
#Say "Main(): Debug ARG1='"$1"'"
#Say "Main(): Debug ARG2='"$2"'"

local IS_VPN_UP="2"
local IS_VPN_DOWN="0"

# If no args supplied assume we should simply bounce the ACTIVE Client or start VPN Client 1 if none ACTIVE
if [ -z $ACTIVE_VPN ]; then        # No ACTIVE VPN Client....

   if [ -z $NEW_VPN ]; then        # Did user supply VPN Client?
      Flush_VPN_ROUTE 1
      RC=`service restart_vpnclient1`
      # Track VPN Client (DOWN state=0) thru' (CONNECTING state=1) to (UP state=2)   !!!
      Check_VPNState 1 $IS_VPN_UP
   else
      if [ "$NEW_VPN" != "off" ] && [ "$2" != "off" ]; then
         Say "No VPN ACTIVE - Starting VPN Client" $NEW_VPN
         Flush_VPN_ROUTE $NEW_VPN
         RC=`service start_vpnclient$NEW_VPN`
         # Track VPN Client (DOWN state=0) thru' (CONNECTING state=1) to (UP state=2)   !!!
         Check_VPNState $NEW_VPN $IS_VPN_UP
      else
         Say "No VPN ACTIVE - and VPN Client 'off' requested."
      fi
   fi
else

    # Don't terminate ACTIVE client if 'on' specified
    #if ([ "X$2" != "Xon" ] && [ "X$2" != "X" ]) || [ "$2" == "off" ] || [ "$1" == "off" ]; then
    if [ "$2" == "off" ] || [ "$1" == "off" ] || [ -n "$ACTIVE_VPN" ]; then
        if [ -n $1 ] && [ "$2" == "off" ]; then
           ACTIVE_VPN=$1
        fi
        if [ "$2" != "on" ]; then
            Say "Stopping VPN Client" $ACTIVE_VPN
            if [ -n $ACTIVE_VPN ]; then
                       
                VPNADDR=$(nvram get "vpn_client"$ACTIVE_VPN"_addr")
                VPNFORCE=$(nvram get "vpn_client"$ACTIVE_VPN"_enforce")
                #Say "Debug: "$VPNADDR "block" $VPNFORCE
                if [ ! -z "$VPNADDR" ] && [ "$VPNFORCE" = "1" ]; then
                    Say "Blocking WAN for VPN Client" $ACTIVE_VPN "to" $VPNADDR
                    #vpnrouting.sh vpn_flush tun1$ACTIVE_VPN
                    vpnrouting.sh wan_block tun1$ACTIVE_VPN                    # Requires Martineau Hacked /jffs/scripts/vpnrouting.sh
                fi
               
                RC=`service stop_vpnclient$ACTIVE_VPN`
                Check_VPNState $ACTIVE_VPN $IS_VPN_DOWN
                if [ "X$2" = "Xoff" ]; then
                  NEW_VPN="off"
                  #Say  "Debug set NEW_VPN="$NEW_VPN
               fi
            fi
        fi
    fi

   if [ "$NEW_VPN" != "off" ]; then
      if [ -z $NEW_VPN ]; then
         NEW_VPN="1"
      fi
      Say "Starting VPN Client" $NEW_VPN
      Flush_VPN_ROUTE $NEW_VPN
      RC=`service start_vpnclient$NEW_VPN`
      # Track VPN Client (DOWN state=0) thru' (CONNECTING state=1) to (UP state=2)   !!!
      Check_VPNState $NEW_VPN $IS_VPN_UP
   else
      Say "....and VPN Client 'off' requested."
   fi

fi
}
#====================================================================================================

# Switch between VPN Clients
#
#   e.g.   VPN_Switch   [ 1 | 2 | 3 | 4 | 5 ] [off | on] [ ? [ debug]] [ fix ]

#          VPN_Switch  
#                       Restart current ACTIVE VPN Client but if none ACTIVE, then Start VPN Client 1
#          VPN_Switch   5
#                       Terminate current ACTIVE VPN Client then switch to VPN Client 5
#          VPN_Switch   off
#                       Terminate current ACTIVE VPN Client.
#          VPN_Switch   3   on
#                       Start VPN Client 3
#          VPN_Switch   3   off
#                       Stop VPN Client 3
#          VPN_Switch   ?
#                       List the status of ALL VPN Clients
#          VPN_Switch   fix
#                       Change any VPN client from state=-1(Error Conflict) to state=2(UP) - use with caution!


Say "Starting....." [$@]

if [ "$1" = "?" ]; then
   ACTIVE_VPN=$(Get_ActiveVPN $1 $2)        # List ACTIVE VPN Clients
   exit
fi

if [ "$1" = "fix" ]; then                # Fix annoying non-critical VPN Status GUI 'Error Routing conflict'
   ACTIVE_VPN=$(Get_ActiveVPN $1)        # VPN Clients in status -1; but assume that they are actually connected and working! ;-)
   exit
fi

ACTIVE_VPN=$(Get_ActiveVPN)    # Current ACTIVE VPN Client to terminate
NEW_VPN=$1                        # VPN Client to use for NEW connection specified by user

# Use VPN Client 1 if no current ACTIVE VPN Client connection and no preference specified by user.
if [ -z $ACTIVE_VPN ]; then        # No ACTIVE VPN Client.....
   MATCH_VPN="1"        
   if [ -n $NEW_VPN ]; then        # .....and user arg supplied
      MATCH_VPN=$NEW_VPN
   fi
else
   MATCH_VPN=$ACTIVE_VPN
fi

# Check if VPN Client is actually configured.....
VPNADDR=$(Get_VPN_ADDR $MATCH_VPN)
if [ -z $VPNADDR ]; then   
   
    if [ "$1" = "1" -o "$1" = "2" -o "$1" = "3" -o "$1" = "4" -o "$1" = "5" ]; then   
        Say "**ERROR** VPN Client" $NEW_VPN "not configured?"
        Say "Aborted!"
        exit
    else
        if [ ! -z $1 ];then
            Say "**ERROR** VPN Client" $NEW_VPN "is INVALID"
            Say "Aborted!"
            exit
        fi
    fi
fi

# Switch or Start or Stop the VPN Client connection
Main $1 $2

Say "Complete."

exit

To save reinventing the wheel etc. I decided to exploit RMerlin's vpnrouting.sh script to enforce WAN Blocking whilst the VPN tunnel is 'UNAVAILABLE' rather than ONLY when an UP to DOWN state change is detected...see next post due to this post nearing the 10,000 char limit!...
 
PART 2

The following extreme examples show how a VPN connection can take 20 secs from UK to a New York node, yet only 9 secs to Hong Kong.

So I could in theory use cron to use this script to connect to different nodes to follow the sun...assuming that when certain nodes in the world are asleep, I should get better throughput?.

NOTE: I do acknowledge that the reason it takes less time to connect to the Hong Kong node could be down to the fact that no-ones uses it because the actual throughput is dismal! - but hopefully the West Coast vs. East Coast USA argument may be valid.

For demonstration purposes, both VPN Clients have the contentious/ambiguous 'Block routed clients if tunnel goes down' enabled in the VPN GUI.

admin@RT-AC68U:/tmp/home/root# x
admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh ?

(VPN_Client_Switch.sh): 14672 Starting..... [?]
(VPN_Client_Switch.sh): 14672 VPN Client Status:
(VPN_Client_Switch.sh): 14672 *NO VPN Clients connected*


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh

(VPN_Client_Switch.sh): 14710 Starting..... []
(VPN_Client_Switch.sh): 14710 Flushing VPN Client 1 route 113.29.228.130 (NewYork)
(VPN_Client_Switch.sh): 14710 Waiting for VPN Client 1 (NewYork) to connect.....
(VPN_Client_Switch.sh): 14710 VPN Client 1 (NewYork) connect'd in 20 secs
(VPN_Client_Switch.sh): 14710 Complete.

admin@RT-AC68U:/jffs/scripts# ip route show table NewYork
10.8.0.0/24 dev tun21 scope link
default via 10.200.5.12 dev tun11


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh 2 on

(VPN_Client_Switch.sh): 15185 Starting..... [2 on]
(VPN_Client_Switch.sh): 15185 Starting VPN Client 2
(VPN_Client_Switch.sh): 15185 Flushing VPN Client 2 route 192.157.56.146 (HongKong)
(VPN_Client_Switch.sh): 15185 Waiting for VPN Client 2 (HongKong) to connect.....
(VPN_Client_Switch.sh): 15185 VPN Client 2 (HongKong) connect'd in 9 secs
(VPN_Client_Switch.sh): 15185 Complete.


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh ?

(VPN_Client_Switch.sh): 15587 Starting..... [?]
(VPN_Client_Switch.sh): 15587 VPN Client Status:
(VPN_Client_Switch.sh): 15587 Client 2 connected (HongKong)
(VPN_Client_Switch.sh): 15587 Client 1 connected (NewYork)


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh 2 off

(VPN_Client_Switch.sh): 15634 Starting..... [2 off]
(VPN_Client_Switch.sh): 15634 Stopping VPN Client 2
(VPN_Client_Switch.sh): 15634 Blocking WAN for VPN Client 2 to 192.157.56.146
(vpnrouting.sh): 15690 Patched by John9527/Martineau /usr/sbin/vpnrouting.sh wan_block tun12
openvpn-routing: WAN access blocked for all VPN Client 2 (HongKong) devices/subnets.
(VPN_Client_Switch.sh): 15634 Waiting for VPN Client 2 (HongKong) to disconnect.....
(VPN_Client_Switch.sh): 15634 VPN Client 2 (HongKong) disconnect'd in 2 secs
(VPN_Client_Switch.sh): 15634 ....and VPN Client 'off' requested.
(VPN_Client_Switch.sh): 15634 Complete.

admin@RT-AC68U:/jffs/scripts# ip route show table HongKong
prohibit default

admin@RT-AC68U:/jffs/scripts# ip rule
0: from all lookup local
1101: from 172.0.0.1 lookup NewYork
1102: from 168.0.0.1 to 173.230.240.197 lookup NewYork
1301: from 172.0.0.2 lookup HongKong
32766: from all lookup main
32767: from all lookup default


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh ?

(VPN_Client_Switch.sh): 15949 Starting..... [?]
(VPN_Client_Switch.sh): 15949 VPN Client Status:
(VPN_Client_Switch.sh): 15949 Client 1 connected (NewYork)


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh 2

(VPN_Client_Switch.sh): 15990 Starting..... [2]
(VPN_Client_Switch.sh): 15990 Stopping VPN Client 1
(VPN_Client_Switch.sh): 15990 Blocking WAN for VPN Client 1 to 113.29.228.130
(vpnrouting.sh): 16049 Patched by John9527/Martineau /usr/sbin/vpnrouting.sh wan_block tun11
openvpn-routing: WAN access blocked for all VPN Client 1 (NewYork) devices/subnets.
(VPN_Client_Switch.sh): 15990 Waiting for VPN Client 1 (NewYork) to disconnect.....
(VPN_Client_Switch.sh): 15990 VPN Client 1 (NewYork) disconnect'd in 2 secs
(VPN_Client_Switch.sh): 15990 Starting VPN Client 2
(VPN_Client_Switch.sh): 15990 Flushing VPN Client 2 route 192.157.56.146 (HongKong)
(VPN_Client_Switch.sh): 15990 Waiting for VPN Client 2 (HongKong) to connect.....
(VPN_Client_Switch.sh): 15990 VPN Client 2 (HongKong) connect'd in 9 secs
(VPN_Client_Switch.sh): 15990 Complete.

admin@RT-AC68U:/jffs/scripts# ip route show table 111
prohibit default


admin@RT-AC68U:/jffs/scripts# ./VPN_Client_Switch.sh ?

(VPN_Client_Switch.sh): 16670 Starting..... [?]
(VPN_Client_Switch.sh): 16670 VPN Client Status:
(VPN_Client_Switch.sh): 16670 Client 2 connected (HongKong)


and to enforce WAN blocking during router boot and to apply cosmetic tagging of the VPN Client (as shown in the console log above) I use the following code in

init-start

Code:
# If RPDB name table exists then override RMerlin's defaults.
# Tables 111-115 reserved by RMerlin RPDB Selective Policy routing
# Tables 100/200 reserved by ASUS Dual WAN aka Primary and Secondary WAN
#
# Firmware 380.57+ RMerlin creates defaults
#    100 wan0
#    111 ovpnc1
#    112 ovpnc2
#    113 ovpnc3
#    114 ovpnc4
#    115 ovpnc5
#    200 wan1
if [ -f /jffs/configs/rt_tables ]; then
    # Use custom table e.g. Replace 'ovpnc1' with 'NewYork' etc.
    /usr/bin/logger -st "($(basename $0))" $$ "Custom RPDB name table /jffs/configs/rt_tables replaces /etc/iproute2/rt_tables"
    mount -o bind /jffs/configs/rt_tables /etc/iproute2/rt_tables
fi

# Check if any configured VPN Clients should be blocked from WAN @boot
# Apply patching of VPN script
/usr/bin/logger -st "($(basename $0))" $$ "Patching /usr/sbin/vpnrouting.sh"
mount -o bind /jffs/scripts/vpnrouting.sh /usr/sbin/vpnrouting.sh

VPNID_LIST="1 2 3 4 5"
for VPNID in $VPNID_LIST
do
    VPNADDR=$(nvram get "vpn_client"$VPNID"_addr")
    VPNFORCE=$(nvram get "vpn_client"$VPNID"_enforce")
    #logger -st "($(basename $0))" $$ "Debug: "$VPNADDR "block" $VPNFORCE
    if [ -n "$VPNADDR" ] && [ "$VPNFORCE" = "1" ]; then
        vpnrouting.sh wan_block tun1$VPNID                    # Requires Martineau Hacked /jffs/scripts/vpnrouting.sh
    fi
done


To allow VPN_Client_Switch.sh (and init-start) to enforce the WAN blocking, you need to modify vpnrouting.sh to allow the appropriate section of code to be called

i.e. insert the following 'if' statement to be executed as the first line of code

Code:
# Begin
########################################################################################## Martineau Hack Part 1 of 2
if [ "$1" = "wan_block" ]; then
   dev=$2
fi
##########################################################################################


and change the existing line:

Code:
# webui reports that vpn_force changed while vpn client was down
########################################################################################## Martineau Hack Part 2 of 2
#if [ $script_type = "rmupdate" ]
if [ "$script_type" = "rmupdate" -o "$1" == "wan_block" ]
##########################################################################################
 
Last edited:
Thanks Martineau.

I'm more interested in the wan blocking script for now.
Modify "vpnrouting.sh" you mean your file modified with Martineau Hack Part 1 and 2 together with the init script?
VPN_Client_Switch seems very interesting, will try a little later.
 
Thanks Martineau.

I'm more interested in the wan blocking script for now.
Modify "vpnrouting.sh" you mean your file modified with Martineau Hack Part 1 and 2 together with the init script?
VPN_Client_Switch seems very interesting, will try a little later.

Are you currently explicitly specifying the route-up directive in the VPN custom configuration?
If you already have a custom vpnrouting.sh script then there will be a conflict.

i.e. you need to take /usr/sbin/vpnrouting.sh and clone it to /jffs/scripts/vpnrouting.sh and add the two part Martineau hack to /jffs/scripts/vpnrouting.sh.

Once this is done, you simply execute

Code:
vpnrouting.sh   "wan_block"   "tun1X"

for whichever VPN client you want to enforce WAN blocking.

So you don't need my VPN_Client_Switching.sh script but in order to trigger a call from the VPN GUI when you manually switch a VPN Client OFF, then I will need the assistance of a friendly .asp/HTML guru

i.e. /www/Advanced_OpenVPNClient_Content.asp

contains the following

Code:
function() {

  document.form.action_script.value = "stop_vpnclient" + openvpn_unit;

  parent.showLoading();
  document.form.submit();
return true;


Would a generous guru who is familiar with .asp / HTML please advise on how best to (dynamically) enhance the single action

Code:
"stop_vpnclient + openvpn_unit"

to actually logically also trigger a pre-call to openvpn-event? such as

Code:
sh openvpn-event "vpngui_off + openvpn_unit"; stop_vpnclient" + openvpn_unit

Should be a simple 1 line addition/substitution - right? ;-)

NOTE: I can't remember if the discussions in the forum regarding the replacement of /www files is actually possible?
 
Last edited:
Would a generous guru who is familiar with .asp / HTML please advise on how best to (dynamically) enhance the single action

"stop_vpnclient + openvpn_unit"

to actually logically also trigger a pre-call to openvpn-event? such as

sh openvpn-event "vpngui_off + openvpn_unit"; stop_vpnclient" + openvpn_unit

Should be a simple 1 line addition/substitution - right? ;-)

NOTE: I can't remember if the discussions in the forum regarding the replacement of /www files is possible?

Can't be done from the webui content. The stop_vpnclientX is an rc event, which gets sent by httpd to the rc process, through a libshared function.
 
Can't be done from the webui content. The stop_vpnclientX is an rc event, which gets sent by httpd to the rc process, through a libshared function.
And....the code contains checks to prevent the running of unauthorized scripts from any of the web pages as a security measure.

Not having followed the whole discussion.....you might be able to have openvpn-event handle a call from script_type="route-pre-down" to do what you want.
 

Similar threads

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