Automatically reconnect to your VPN on Linux

Introduction

This article is aimed at those who configured their VPN connection using the Network Manager applet, and by extension those who configured their VPN connection so that it is available in the nmcli command. It does not apply if you use gOpenVPN or GADMIN-OPENVPN-Client.

VPN connections become more and more popular, for a variety of reasons. If you are using a VPN connection for privacy or any other reasons, you probably fear to be disconnected while you are not in front of your computer, because this could leave your activity unencrypted on your ISP network. The Gnome Network Manager applet doesn’t offer a way to reconnect automatically. Fortunately, there is a solution. I will show you a little Bash script that adds this functionality.

Here is the script:

#!/bin/bash
while [ "true" ]
do
	VPNCON=$(nmcli con status)
	if [[ $VPNCON != *MyVPNConnectionName* ]]; then
		echo "Disconnected, trying to reconnect..."
		(sleep 1s && nmcli con up uuid df648abc-d8f7-4ce4-bdd6-3e12cdf0f494)
	else
		echo "Already connected !"
	fi
	sleep 30
done

Where:

  • MyVPNConnectionName is the name of you VPN connection in the Network Manager applet
  • df648abc-d8f7-4ce4-bdd6-3e12cdf0f494 is the uuid of your VPN connection. You can find it using the following command:
nmcli con

Save this script in your user personal directory, for example.

Do not forget to make this script executable by running the following command:

chmod +x /path/to/my/script/my_script

Explanation:

This script will check if you are connected to the VPN by testing if the $VPNCON variable contains the line corresponding to your VPN connection. If the $VPNCON variable doesn’t contain it, then the VPN is not connected and the script attempt to connect. Otherwise we just wait for 30 seconds (you can change this delay, but you should give enough time to fully reconnect).

Just save this script in your home directory and run it when you need.

How to run this script automatically when a user has logged in?

It’s very easy. Just append the following line to your .profile (in the root of your user directory):

/path/to/your/script/my_script &

In some distributions, it may be the .bashrc file. In Debian it’s .profile (it doesn’t work as expected with .bashrc). Just choose what works for you.

Finally, save your changes, logout from your session, and login again. The script should be automatically started, and your VPN should connect immediately. Hurray!

FAQ

Q: It doesn’ t work with my Linux distribution! What can I do?

A: This script has been tested with Debian Squeeze (6.0.3) and works like a charm. Please refer to your distribution documentation.

View Comments (28)

  • This script is actually no easier than just doing a couple of clicks with the mouse by opening the networkmanager and restarting the VPN manually.

    It isn't checking the VPN connection constantly to make sure it needs to 'reconnect', so it's really not a lot of help.

    The only way I can think of to make this script more usefull is to put in a cron job of something making the script constantly execute every x seconds/minutes to check if ones VPN connection is up and if not it executes.

    The only problem with that though is that it'd make an awful lot of cpu usage (or something, I'm sure) drag down the system by constantly checking if the VPN connection is up.

    Does this make sense? Am I seeing it wrongly? Is there an easier way to have something checking the VPN connection all the time (or at some set interval I can use) that will then utilize this script when it finds the VPN down?

    • Well what you describe is pretty much what my script does... Polling the status of the connection every 30 secs, and reconnect if necessary... Sure it could be improved but it does what it says.

      • Yes, I got to thinking about it a little while ago and you're right, except that with your solution one has to leave the konsole open on the taskbar.

        Is there a way to make it run in the background without having to keep konsole open all the time?

        • You won't see any console if you follow the advice of executing the script automatically by putting it in your .profile.

  • Hey everyone,

    thank you for the working script.

    Is there a way to make it so when it attempts to reconnect, and perhaps the server is down, it would choose another connection instead? If that one is also down, another one?

  • I'm using Debian Jessie and
    [code]nmcli con status[/code]
    doesn't work anymore. However I think
    [code]nmcli con show --active[/code]
    should do the trick.

  • Fedora 24 you have to do something more like:
    [code]
    VPNCON=$(nmcli con show --active | grep My\ VPN | cut --fields=1,2 -d " ")
    if [[ "$VPNCON" != "My VPN" ]]; then
    [/code]
    This handles this seemingly different nmcli (no con status command) and how a two word VPN could be handled.

  • Hi, I also use a firewall rule to prevent any DNS leaks in the case of a drop out. So this looks like a good solution for me except I'm not good enough with scripts yet to know where to edit. My VPN won't connect with my firewall rules set, so I have a script that "unfirewalls" which allows me to connect to VPN, once connected I activate the firewall rules and now only traffic through the VPN will be accepted. For start up I just used the start up applications in settings and that allowed me to unfirewall, connect and refirewall all automtically. So now all I need is somewhere within this script to say (pardon my rubbish computer language) "VPN disconnected, run unfirewall, connect to vpn, run firewall". I do have little scripts for those commands just where to insert them here.

    #!/bin/bash
    while [ "true" ]
    do
    VPNCON=$(nmcli con status | grep *VPN* | cut -f1 -d " "))
    if [[ $VPNCON != *VPN* ]]; then
    echo "Disconnected, trying to reconnect..."
    (sleep 1s && nmcli con up uuid c8013f1e-615b-4900-80ac-01ccef317c78)
    else
    echo "Already connected !"
    fi
    sleep 30
    done

    my firewall script is ./firewall.sh and unfirewall is ./unfirewall.sh

    Any help on this would be great

  • I use pon and poff for my VPN, as NM seems to barf all over my routing tables for some weird reason I haven't yet figured out. So I bodged this together:
    [code]
    #!/bin/bash
    WIFIUUID=f3b57d7a-701e-46f2-8b95-74b61851c65b
    WIFICON=`nmcli -t -fields uuid con show --active`
    while [[ $WIFICON = $WIFIUUID ]]; do
    PINGRES=`ping -c 2 192.168.1.254`
    PLOSS=`echo $PINGRES : | grep -oP '\d+(?=% packet loss)'`
    echo "`date` : Loss Result : $PLOSS"
    if [ "100" -eq "$PLOSS" ]; then
    echo "`date` : Starting VPN"
    pon home updetach && route add -net 192.168.1.0 netmask 255.255.255.0 dev ppp0
    echo "`date` : VPN Started"
    else
    echo "`date` : VPN Already Running"
    fi
    sleep 30
    done
    echo "WiFi Disconnected, Terminating VPN"
    poff
    [/code]
    Basically it just watches my WiFi, and if it's connected it babysits the VPN.

    You'll have to change the VPN name, network particulars, and pinged IP address to match your network. Either the router IP or some server that's only reachable via the VPN and always up should work fine for this purpose.

  • thank you very very much and also you can this script :

    #!/bin/bash
    YOUR_VPN_NAME="speed"
    while [ "true" ]
    do
    VPNCON=$(nmcli con show --active)

    ############### the contains of $VPNCON is :
    # NAME UUID TYPE DEVICE
    # Wired connection 1 59be4e24-ef52-3288-8611-062a2e4866aa ethernet enp0s31f6
    # speed b449281e-b683-4952-bb3d-d2c33aa7090f vpn enp0s31f6

    if [[ ($VPNCON != *"vpn"*) && ($VPNCON != *"$YOUR_VPN_NAME"*) ]];then
    echo "Disconnected, trying to reconnect..."
    (sleep 1s && nmcli con up $YOUR_VPN_NAME)
    else
    echo "Already connected !"
    fi
    sleep 5
    done

  • Hi Gabriel (and maybe Antoniy),
    my VPN-Router is a headless VM, so there is no users to login locally.
    My NIC is autoconnecting at boot time.
    Which would be the right place and/or instructions to start this script at boot time respectively after the network ist running?
    Many thanks in advance,
    Gerald

1 2