Scheduled Automatic Server Randomization with Mullvad VPN CLI
In this tutorial we will show you how to increase your VPN OpSec by setting up a scheduled daily cron
job that will pick a random time once a day and switch your VPN connection to random servers.
Why would I want this?
As we know, the key to successful anonymity is randomization. TOR uses this as its foundational principle for operation. We can also accomplish this on our own as well! Here you can see the potential added complexity for your network pathway even with just a daily VPN server switch on a 7-day multihop stint:
Pre-Requisites and Setup
This tutorial assumes that you have some basic experience with Linux.
It also assumes you have Mullvad installed and have logged into your account. You can find those details on Mullvad's website: Clearweb | Onion
Be sure that your cron and Mullvad services are both running and enabled:
systemctl status cron # might also be called crond
systemctl status mullvad-daemon
There is a utility you'll need to use in this tutorial, shuf
, which you can check if you have it by running shuf --version
. Most mainstream linux distros have it, but if you don't, you'll need to install GNU Core Utilities. It will likely be available to your package manager, so for example, Debian-based systems, you'll install it like so: sudo apt install coreutils
Finally, to prevent leaks, be sure to switch Mullvad to Lockdown mode, so that you will never make connections outside of the VPN tunnel:
mullvad lockdown-mode set on
During any time in this tutorial, you can check the connection status of Mullvad using:
mullvad status
You can also see what's going on by starting the Mullvad GUI from your launcher, this makes it very easy and updates automatically with whatever you do on the CLI
Setting Server Constraints
When you connect to Mullvad, you will use the command mullvad connect
if disconnected or mullvad reconnect
if already connected. This by default will pick a random server based on whatever the current constraints are set to. Constraints are essentially filters that tell Mullvad which servers you want to use and which to avoid. You can view what your current constraints are by running mullvad relay get
If you want to view all the constraints that are available you can run:
$ mullvad relay set
Set relay constraints, such as location and port
Usage: mullvad relay set <COMMAND>
Commands:
location Select a relay using country, city or hostname. The 'mullvad relay list' command shows the available relays and their geographical location
custom-list Set custom list to select relays from. Use the 'custom-lists list' command to show available alternatives
provider Set hosting provider(s) to select relays from. The 'list' command shows the available relays and their providers
ownership Filter relays based on ownership. The 'list' command shows the available relays and whether they're rented
tunnel Set tunnel protocol specific constraints
tunnel-protocol Set tunnel protocol to use: 'wireguard', or 'openvpn'
custom Set a custom VPN relay to use
help Print this message or the help of the given subcommand(s)
# Only use wireguard servers
mullvad relay set tunnel-protocol wireguard
# Always use multihop
mullvad relay set tunnel wireguard -m on
# Only use servers whose hardware is owned and controlled by Mullvad:
mullvad relay set ownership owned
# By default the entry server will always be Sweden. You can remove this by running:
mullvad relay set tunnel wireguard entry location any
Now let's view all our current constraints:
$ mullvad relay get
Generic constraints
Location: any
Tunnel protocol: WireGuard
Provider(s): any
Ownership: Mullvad-owned servers
OpenVPN constraints
Port: any
Transport: any
WireGuard constraints
Port: any
IP protocol: any
Multihop state: enabled
Multihop entry: any
Now, assuming you're already connected to the VPN by using mullvad connect
, try reconnecting a few times and see the servers change each time:
$ mullvad reconnect
$ mullvad status
Connected
Relay: fr-par-wg-006 via nl-ams-wg-004
Features: Lockdown Mode, Multihop, Quantum Resistance
Visible location: France, Paris
$ mullvad reconnect
$ mullvad status
Connected
Relay: se-sto-wg-004 via no-osl-wg-001
Features: Lockdown Mode, Multihop, Quantum Resistance
Visible location: Sweden, Stockholm
Creating the randomized cronjob
If you don't already know, cron
is a scheduler system that pretty much every single Linux distro has. However, as it does not have built-in randomization capabilities, we will tell cron to run a custom script that does some randomization for us.
In this tutorial we'll show you how to configure the script to run do once per day at a random time sometime after noon, but also show you how to customize it the way you like.
First, create a new text file in your home directory called connect_rand.sh
. Or you can call it what you like or place it somewhere else. In this file, you'll paste this script:
#!/bin/bash
RANDNUM=$(shuf -i 1-43200 -n 1)
sleep $((RANDNUM))s
mullvad reconnect
#!/bin/bash
denotes that the shell program to be used is bash
. Be sure to include this or it won't work
RANDNUM=$(shuf -i 1-43200 -n 1)
grabs a random number between the specified number range using the shuf
command and assigns it to the variable RANDNUM
. In this case these numbers correspond to a number of seconds between 1 second and 12 hours.
sleep $((RANDNUM))s
gets that random number and will pause the script for that many seconds before executing the reconnect command.
mullvad reconnect
will, of course reconnect the VPN tunnel and change the current server(s) to something else. Keep in mind that if the VPN is disconnected, this WON'T establish a new connection. You will just remain disconnected.
Save your file. Now we're going to edit our crontab file. This file tells cron what jobs to run and when, such as running our script we just made. In your terminal open the file with sudo
privileges (you can use something else if you don't like nano
)
sudo nano /etc/crontab
So at the bottom we'll add this line:
0 12 * * * myuser /home/myuser/connect_rand.sh
For the purpose of this tutorial all you need to know is that 0 12 * * *
says to run the job at exactly 12:00 (noon) each day. When the job runs the script, you see by looking back at our script that it will first sleep for some random amount of hours up to 12 hours. Combined with the cron schedule, this amount will determine that the Mullvad servers will rotate at a random time of the day between 12:00 Noon and 00:00 Midnight.
For example, if the random sleep number chosen was 16200 seconds (4.5 hours), we can say that 12:00 + 4.5 hours = 16:30 (4:30pm).
This is of course totally customizable to you. Let's give another example. Say you want to run the script twice a day. You could give a cron schedule of 0 6,18 * * *
and keep the sleep number range at 1-43200
. So the job would run at 6:00 and also at 18:00, plus whatever the random sleep interval is each time.
Going back to our crontab file, the next part of the cronjob line, myuser
you need to replace with the name of your linux user. And the final part is the job, in this case, running the script at the path specified. If your script is somewhere else you need to change the path. Do you not use ~/myuser....
to specify your HOME either, always use absolute paths.
After you save and exit your editor, you are done. You can view the cronjob logs in realtime with this command:
journalctl /usr/sbin/cron -f
Conclusion
Congrats, so you have a scheduled script that will always change to random VPN servers at random times!
Suggest changes
loki_opsec_inc 2025-07-17
8AaLSmixWFJhgMmrBvqi6827v27YYT6H8C6SjUasHySBKna2JDk1dtEf2ZAUpXue64JDEBxkTL9oZGaoKtcWppWKHLSkTLM Donate XMR to the author: