Skip to content

Instantly share code, notes, and snippets.

@antoniy
Last active February 4, 2022 09:04
Show Gist options
  • Star 9 You must be signed in to star a gist
  • Fork 3 You must be signed in to fork a gist
  • Save antoniy/9310092 to your computer and use it in GitHub Desktop.
Save antoniy/9310092 to your computer and use it in GitHub Desktop.
Auto reconnect to OpenVPN via NetworkManager
#!/bin/bash +x
# Source: http://www.gabsoftware.com/tips/automatically-reconnect-to-your-vpn-on-linux/
# Description:
# Make the script executable "chmod +x /path/to/the/script.sh
# Put the script in .profile or .bashrc so it can be run on user login:
# Example: echo "/path/to/the/script.sh start &" >> .bashrc
# The script can be bound to shortcut keys with these commands:
# /path/to/the/script.sh start # starts and monitors VPN connection
# /path/to/the/script.sh stop # stops the monitor and also the VPN connection
##########
# Config #
##########
# You can see those with "nmcli con" command
VPN_NAME="VPN-NAME-HERE"
VPN_UID="VPN-UID-HERE"
# Delay in secconds
DELAY=30
# File path with write permission to the executing user to store script status information
LOG="/path/to/log/file.log"
# Enable/disable ping connection check
PING_CHECK_ENABLED=true
# Check IP/Hostname
CHECK_HOST="8.8.8.8"
# Configure DISPLAY variable for desktop notifications
DISPLAY=0.0
##################
# Implementation #
##################
if [[ $1 == "stop" ]]; then
nmcli con down uuid $VPN_UID
echo "VPN monitoring service STOPPED!"
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> VPN monitoring service STOPPED!" >> $LOG
notify-send "VPN monitoring service STOPPED!"
SCRIPT_FILE_NAME=`basename $0`
PID=`pgrep -f $SCRIPT_FILE_NAME`
kill $PID
elif [[ $1 == "start" ]]; then
while [ "true" ]
do
VPNCON=$(nmcli con status | grep $VPN_NAME | cut -f1 -d " ")
if [[ $VPNCON != $VPN_NAME ]]; then
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> Disconnected from $VPN_NAME, trying to reconnect..." >> $LOG
(sleep 1s && nmcli con up uuid $VPN_UID)
else
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> Already connected to $VPN_NAME!" >> $LOG
fi
sleep $DELAY
if [[ $PING_CHECK_ENABLED = true ]]; then
PINGCON=$(ping $CHECK_HOST -c2 -q -W 3 |grep "2 received")
if [[ $PINGCON != *2*received* ]]; then
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> Ping check timeout ($CHECK_HOST), trying to reconnect..." >> $LOG
(nmcli con down uuid $VPN_UID)
(sleep 1s && nmcli con up uuid $VPN_UID)
else
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> Ping check ($CHECK_HOST) - OK!" >> $LOG
fi
fi
done
echo "VPN monitoring service STARTED!"
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> VPN monitoring service STARTED!" >> $LOG
notify-send "VPN monitoring service STARTED!"
else
echo "$(date +%Y/%m/%d\ %H:%M:%S) -> Unrecognised command: $0 $@" >> $LOG
echo "Please use $0 [start|stop]"
notify-send "UNRECOGNIZED COMMAND" "VPN monitoring service could not recognise the command!"
fi
@numericOverflow
Copy link

FYI - can't create a pull request because it's a gist, but I forked & updated your script to work with nmcli 0.9.10+which has a changed syntax a bit. Seems to be working for me now on Mint 18.

Slick script BTW, thanks!

@Sarumannet
Copy link

Great Scriptt !! Thanks!!

I suggest you a more relaxed Ping Check. It assumes lost connections on slow lines quickly!.
--------------------
Suggested Logic Test Change.
---------------------
# Original: sends 2, IF NO 2 were received, assumes connection dropped.
PINGCON=$(ping $CHECK_HOST -c2 -q -W 3 |grep "2 received")
if [[ $PINGCON != 2received* ]]; then

# New: sends 3, If it receives zero it assumes a dropped connection.
PINGCON=$(ping $CHECK_HOST -c3 -q -W 3 |grep "0 received")
if [[ $PINGCON == "0 received" ]]; then
--------------------

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment