What's new

VPN Connectivity test and reconnect script

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

TheSNAKE

New Around Here
Hi,

I thought to share this useful script with the community and see if there are some useful improvements to be made.

This script checks your enabled VPN connections and will restart in case of an issue like interface down or unable to ping the external source. You add this script to cron and run it e.g. every 5 minutes. It'll add log entries in the system log.

Bash:
#!/bin/sh
for i in 1 2 3 4 5
do
  if [ `nvram get vpn_client"$i"_state` -gt 0 ]
  then
    logger -s -p user.notice "VPN $i Enabled"
    if [ `ip route add to 103.224.182.212 dev tun1"$i" | grep "Network is down" | wc -l` -eq 0 ]
    then
      if [ `ping -c 1 103.224.182.212 | grep "100% packet loss" | wc -l` -eq 1 ]
      then
        logger -s -p user.notice "VPN $i down, restarting..."
        service restart_vpnclient"$i"
      else
        logger -s -p user.notice "VPN $i up, no action required..."
      fi
    else
      logger -s -p user.notice "VPN $i down, restarting..."
      service restart_vpnclient"$i"
    fi
    ip route delete to 103.224.182.212 dev tun1"$i"
  fi
done

Enjoy!
 
Seems to me this could be simplified a wee bit.

Bash:
#!/bin/sh
{
for i in 1 2 3 4 5
do
  if [ `nvram get vpn_client"$i"_state` -gt 0 ]
  then
    echo "VPN $i Enabled"
    if ! ping -c1 -I tun1"$i" 8.8.8.8 &>/dev/null
    then
      echo "VPN $i down, restarting..."
      service restart_vpnclient"$i"
    else
      echo "VPN $i up, no action required"
    fi
  fi
done
} 2>&1 | logger -t $(basename $0)[$$]

For one thing, anytime you alter the routing tables, you should (at least technically) flush the routing table cache.

Code:
ip route flush cache

But frankly, I don't see the need to be constantly adding and removing the route anyway. You can just ping the relevant network interface directly, and if it fails for *any* reason, restart the VPN client. Might be different if you were trying to report *how* it failed, but since you're NOT, it's better to avoid messing w/ the routing tables.

There's also a secondary (and fatal) problem. You're assuming the router itself will always be bound to the main routing table, since that's where you're adding the route. But that's NOT necessarily the case. Depending upon the configuration, it's possible the router may be bound to one of the alternate routing tables (ovpnc1, ovpnc2, etc.) (typically when "Redirect Internet traffic through tunnel" is set to Yes (all)), NOT the main routing table. And if that happens, the route will never be referenced anyway. The router will end up testing that IP address against whatever OpenVPN client it happens to be currently bound to, which is obviously NOT what you want.

All in all, that's why I believe it's better to reference the network interface directly via the ping command. You avoid all these issues.

I also find it easier to bracket the entire script and have its output (stdout and stderr) redirected to the syslog.

Finally, I personally prefer to NOT use the scheduler (cron) for anything that will be restarted in 5 minutes or less, but instead place the script in a loop w/ an appropriate sleep interval. Starting and stopping processes adds more overhead than simply putting the one and only running process to sleep for short periods.

To be honest, the only real stickler for me is the use of the special route. The rest is just minor issues and personal preferences.

P.S. I'm assuming the use of Merlin here, given the reference to the 5 OpenVPN clients and end-user scripting. And if that's the case, it probably would be better if it was posted in the Merlin forum, despite the fact it's a VPN issue.
 
Last edited:
Seems to me this could be simplified a wee bit.

Bash:
#!/bin/sh
{
for i in 1 2 3 4 5
do
  if [ `nvram get vpn_client"$i"_state` -gt 0 ]
  then
    echo "VPN $i Enabled"
    if ! ping -c1 -I tun1"$i" 8.8.8.8 &>/dev/null
    then
      echo "VPN $i down, restarting..."
      service restart_vpnclient"$i"
    else
      echo "VPN $i up, no action required..."
    fi
  fi
done
} 2>&1 | logger -t $(basename $0)[$$]

For one thing, anytime you alter the routing tables, you should (at least technically) flush the routing table cache.

Code:
ip route flush cache

But frankly, I don't see the need to be constantly adding and removing the route anyway. You can just ping the relevant network interface directly, and if it fails for *any* reason, restart the VPN client. Might be different if you were trying to report *how* it failed, but since you're NOT, it's better to avoid messing w/ the routing tables.

There's also a secondary (and fatal) problem. You're assuming the router itself will always be bound to the main routing table, since that's where you're adding the route. But that's NOT necessarily the case. Depending upon the configuration, it's possible the router may be bound to one of the alternate routing tables (ovpnc1, ovpnc2, etc.) (typically when "Redirect Internet traffic through tunnel" is set to Yes (all)), NOT the main routing table. And if that happens, the route will never be referenced anyway. The router will end up testing that IP address against whatever OpenVPN client it happens to be currently bound to, which is obviously NOT what you want.

All in all, that's why I believe it's better to reference the network interface directly via the ping command. You avoid all these issues.

I also find it easier to bracket the entire script and have its output (stdout and stderr) redirected to the syslog.

Finally, I personally prefer to NOT use the scheduler (cron) for anything that will be restarted in 5 minutes or less, but instead place the script in a loop w/ an appropriate sleep interval. Starting and stopping processes adds more overhead than simply putting the one and only running process to sleep for short periods.

To be honest, the only real stickler for me is the use of the special route. The rest is just minor issues and personal preferences.

P.S. I'm assuming the use of Merlin here, given the reference to the 5 OpenVPN clients and end-user scripting. And if that's the case, it probably would be better if it was posted in the Merlin forum, despite the fact it's a VPN issue.
Thanks @eibgrad!

Yes, running Merlin indeed.

Wasn't aware that you could ping the interface directly, this indeed takes away complexity!
 

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