Adding a VPN “KillSwitch” to NetworkManager

I use a VPN connection most days, and leave it unattended. Sometimes, however, it is not as stable as I would like it to be, and it disconnects, for instance because of wireless network problems. The wireless connection is brought up again, but the VPN connection stays down, causing potentially sensible data to be exchanged through an insecure channel. Bad.

How can we solve this?

In jargon, a mechanism that disconnects you from the Internet when your VPN connection disconnects, is called a “VPN Kill Switch”. There is a simple way to add one to NetworkManager, thankfully, via a dispatcher script. These scripts will be automatically called when a connection goes up or down.

You can save the following in /etc/NetworkManager/dispatcher.d/99vpnkillswitch, and give it 0755 permissions (it must be owned by root):

#!/bin/sh

IFFILE=/var/run/vpnkillswitch.iface

interface=$1 status=$2
case $status in
    vpn-up)
        # Get the physical device associated with the VPN connection
        nmcli -f type,device c | awk '$1~/^vpn$/ && $2~/[^\-][^\-]/ { print $2; }' > "${IFFILE}"
    ;;
    vpn-down)
        xargs -n 1 -a "${IFFILE}" nmcli device disconnect
    ;;
esac

You’re good to go! Try stopping your VPN interface, and your associated physical interface should be brought down too.

Advertisements

7 Responses to Adding a VPN “KillSwitch” to NetworkManager

  1. wilson says:

    Looks like a simple script. I’m unsure about the device part. So type would be eth0(if thats my hardwire) and device being the mac address of eth0?
    Maybe give a couple of examples to make it easier for us greenhorns. Thanks.

    • tchernobog says:

      Hello Wilson,

      “nmcli -f type,device c” returns a list of connection types (such as ethernet, wireless, or vpn) along with their associated physical device (such as eth0, wlan0, etc.).

      In our case, when the connection goes up, we look for all lines where the first column equals “vpn”, and where the device different from “–” (which, being set, means the vpn connection is at the moment active).

      We write this value to a temporary file, so that when the connection goes down, we remember the interface it was associated with, and bring it down too.

      Cheers,
      Matteo

  2. dagrha says:

    Am I correct that this won’t work if there is more than one active device? In other words, if vpn tunnel uses eth0 device, gets disconnected, eth0 device would be brought down but wlan0 device would not be brought down?

    • tchernobog says:

      That is the original intent, yes. I don’t have my PC with me at the moment so I can’t try it out, but it should be easy to check.

  3. Hi,

    I posted a comment earlier today, NOPE that doesn’t actually work, my OpenVPN connection fell – the event I needed to test, it didn’t fall because I unplugged the optical fiber cable as I did earlier when doing the first tests – and I was still online, no attempt was made to reconnect, no kill switch to prevent the connection.

    Another approach might be with iptables, see this tutorial about OpenVPN on DD-WRT routers: https://nordvpn.com/tutorials/dd-wrt/openvpn-gui/

    WAN_IF=`nvram get wan_iface`
    iptables -I FORWARD -i br0 -o $WAN_IF -j REJECT –reject-with icmp-host-prohibited
    iptables -I FORWARD -i br0 -p tcp -o $WAN_IF -j REJECT –reject-with tcp-reset
    iptables -I FORWARD -i br0 -p udp -o $WAN_IF -j REJECT –reject-with udp-reset

    I found tutorials on iptables, I’ll have to learn.

  4. Ouch, my first comment is not visible, I might have avoided the second one LOL, anyway here it is, I REPEAT THIS DOES NOT WORK, somebody might find out how to make this approach work:

    Hi, nice solution, thanks a lot, I’ve been using it for months.

    However, it precludes OpenVPN any chance to reconnect (as OpenVPN on my DD-WRT router does, for instance). I’m unable to make an “extended” version of your script, capable of that.

    But under the Gnome Network Manager (I’m on Ubuntu), it seems to me – correct me if I’m wrong – that one way to achieve it all, “everything through VPN, no leaks in case the VPN connection goes down (I HAVE TO TEST MORE), reconnects when possible”, might be as follows:

    – Edit Connections…

    – “Add” button then select “import a saved VPN configuration”, where you import the OpenVPN definition for the server of your choice among the ones your VPN provides, let’s say server xxx001

    – “Add” button again and you create an ethernet connection with static IPv4 settings where the DNS IPs are the ones your VPN recommends (mine recommends to disable IPv6, I select “Link-Local Only” but I doubt that’s the correct way… I’m OK according to dnsleaktest.com anyway, I’ll also test selecting “Ignore”)

    – in the General tab, mark the checkbox for “Automatically connect to VPN when using this connection”, there you select server xxx001

    – in the same General tab, mark the checkbox “Automatically connect to this network when it is available”

  5. Well, coming back here I realize that by posting the first comment which had not apparently been recorded after the second one I made a mess here. When I say “NOPE that doesn’t work” and “THIS DOES NOT WORK” I’m referring to my first comment (actually I was thanking the author of this page saying I used his solution during months). MY COMMENTS ARE STILL AWAITING MODERATION BUT I CAN’T EDIT OR ERASE THEM, too bad.
    Anyway, MAYBE what I had suggested to try out purely with the Network Manager might work adding ping-restart option in the OpenVPN config file, I’ll know if that works the next time the VPN connection falls. However, some iptables lines might be necessary to avoid a leak while the reconnection hasn’t been accomplished (no idea yet if the ones I posted would do, they work on my DD-WRT router).

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

%d bloggers like this: