Tuesday, November 12, 2013

Nmcli and keeping an eye on the VPN

Virtual Private Network (VPN) connections are often used by particular applications such as P2P clients. If, for some reason, the VPN connection goes down while the underlying non-VPN connection to the ISP is still up, the P2P client may continue operating "in the open", which may be undesirable e.g. because the use of the client is illegal in the ISP's country.

Below is a small script that regularly checks the VPN connection and, if the connection is down, stops the application that we wish to only operate over the VPN.

Landstander wrote a bash script to do just that. It contained a few errors, which were corrected by sgleo87 here.

Thanks to this script, I learned that the (in)famous NetworkManager used by Ubuntu can be accessed using a command line program, called nmcli. The program can operate on 3 objects: 'dev' (devices), 'con' (connections) and 'nm' (the network manager proper). The main operations that can be performed on an object are 'status', 'enable' and 'sleep'. The script below uses the 'status' operation on 'con', which outputs a table containing data on each connection. One of the columns is called 'VPN' and for each connection there'll be a 'yes' or 'no' entry indicating whether the connection represented by the row is a VPN connection or not.

My version of the script is shown below. The main change is that this version does not attempt to restart the application when the VPN connection is back. The rationale is that since the admin needs to take action to restart the VPN, she might as well restart the application. There are also some more sanity checks and comments.

#!/bin/bash
PROGRAM=myprogram # the program to be stopped if VPN does
EMAIL_ADDRESS=jj@gmail.com # the admin's email address

function fatal() {
  echo "fatal error: $1" 2>&1; exit 1
}

while true 
do
  pid=$(pidof ${PROGRAM}) || fatal "pidof ${PROGRAM}"
  # nmcli 
  #   -t : terse
  #   -f VPN: print 'VPN' column
  #   con: object, the connections
  #   status: command, output status table
  # grep -c: prints count of matching lines
  ok=$(nmcli -t -f VPN con status |  grep -c yes) 
  echo -n "$(date): "
  if [ $ok -gt 0 ]
  then
    echo "ok"
  else
    echo "ERROR: VPN DOWN, KILLING ${PROGRAM}"
    kill -9 ${pid}
    # warn the admin
    mutt -s "VPN DOWN" ${EMAIL_ADDRESS} </dev/null
    exit 1
  fi
  sleep 1 # seconds to wait between checks
done

No comments:

Post a Comment