Just Another Person on the Internet's Rants

Menu

Tag Archives: nmcli

So, I had a pretty large problem to figure out: How to configure 170+ different OVPN (Swedish/English) configurations in NetworkManager, without having to enter my username and password over 170 friggin’, fraggin’ times.

(NOTE: If you’re highly security conscious, then this probably isn’t going to be very palatable for you. You have been warned.)

I use [REDACTED] VPN service and they offer a zip file that you can download with containing multiple OVPN configuration files; a unique file for each server that you can use. After filtering the list down to my targets, I had a resultant list to import into Network Manager.

In order to have NetworkManager leverage ovpn, though, you need to install two packages, first.

Now that we have the files imported, we need to modify them. To do this, the easiest way is to use Python to read in the files and write our changes. Modify the script below to include your username and password.

Now that the files are modified, we need to restart NetworkManager to allow the configurations to be re-read on the connection’s instantiation.

sudo service network-manager restart

(Personally, bouncing the machine was more of a formidable option, here, but that’s because I messed-up the initial script – due to indenting – and wiped all of my configuration files; thus, the warning in the script.)

Now that this has been configured, I needed a way to randomly choose which VPN connection to use, so as to not always land on a static connection. To do this, I used Python again and randomised the choice of which VPN server to connect to. (You’ll note that I’m using a pretty large seed and that’s because the default random.random() method isn’t random in a secure manner [read: it’s predictable].)

#!/usr/bin/env python
"""Randomly connections to a random VPN profile (if any are found).
Uses NetworkManager (https://developer.gnome.org/NetworkManager/stable/gdbus-org.freedesktop.NetworkManager.html#) to
enumerate the devices and connections. First, we enumerate the wireless devices to ensure that we have one. Next, we
enumerate the VPN connections and put them into a list. After that, we randomly select one of the VPN connections to
connect to. Once we've accomplished this, we disconnect the current VPN connection (if one is found) and connect to
the randomly chosen VPN connection.
REQUIREMENTS:
python-networkmanager
TO RUN:
python NetworkManager_VPN.py
"""
__author__ = "felsokning"
__copyright__ = "Copyright 2019"
__license__ = "MIT"
import os
import random
import time
# Externals
import NetworkManager
# Find all of the VPN connections on the machine.
vpns = list()
current_vpn = None
wireless_device = None
connections = NetworkManager.Settings.ListConnections()
for c in connections:
if "vpn" in c.GetSettings()['connection']['type']:
path = c.object_path
vpns.append(path)
# If there are no VPN connections, there's no point in proceeding.
if vpns.__len__() > 0:
# We find the Wireless Network Interface.
# If you're running some kind of weird, three wireless network cards situation, then...
# Change this code to work in your use-case scenario.
devices = NetworkManager.Device.all()
for d in devices:
if "wifi" in d.Driver:
wireless_device = d
# Validate that we found a wireless network interface
if wireless_device is not None:
# Get the currently active VPN connection.
# If you're running some kind of weird, three active VPNs scenario, then...
# Change this code to work in your use-case.
active = NetworkManager.NetworkManager.ActiveConnections
for a in active:
if "vpn" in a.Type:
current_vpn = a
# Choose a random one to connect to. We use the far more secure random method, with a larger seed,
# to try and prevent the random generation from being a predictable pattern (well, to try to make
# it far less predictable with our sample, at least).
rand = random.SystemRandom(os.urandom(99999999))
random_int = rand.randint(0, (vpns.__len__() - 1))
random_vpn = vpns.__getitem__(random_int)
new_connection = NetworkManager.Connection(random_vpn)
# Validate that we have a current VPN connection to disconnect from before we do.
if current_vpn is not None:
# Disconnect the old & busted.
NetworkManager.NetworkManager.DeactivateConnection(current_vpn)
# To prevent collision in NetworkManager, we allow background clean-up before reconnecting.
time.sleep(10)
# Connect the new hotness.
print("Connecting to: {}".format(random_vpn))
NetworkManager.NetworkManager.ActivateConnection(new_connection, wireless_device, "/")
# No wireless interfaces were found, so let's abort.
else:
raise Exception("No wireless interfaces were found.")
# No VPN connections were found, so let's abort.
else:
raise Exception("The hull has been breached and the science is leaking out! "
"(We didn't find any valid VPN connections on this machine via NetworkManager.)")

That should just about do it. …but WAIT! That’s not all! If you act now…

I’ve also written a script to remove all of the OVPN configurations from NetworkManager, in case you made a mistake somewhere (I know that I did and this came in pretty useful.)