I have a Netgate SG-1000 that serves as my firewall and router for my home network. I use it to protect my home network with my private VPN service and connect my work computer to my work VPN. PfSense makes it easy for me to write rules around what machines and services are allowed to go through which VPN. However, sometimes an OpenVPN will be in a state that it can’t recover from and require me to manually restart the client.
I’ve automated this with a script I’ve adapted from the article: Restarting a VPN Client on pfSense through the CLI, and using
cron. To do this, I had to setup SSH access to my device. I also created a new user and set it up with my public SSH key. Then I created this file
ensure_vpn.sh in my user’s home directory:
I noticed in the original article I based my script on, that the author said to look at the web interface for the VPN ID. However, I noticed that got me the wrong ID. Instead, I had to look at the number of the interface when running
ifconfig. For example, if the interface name is
ovpnc2 then I would use
2 as the VPN ID.
Since I have two OpenVPN clients that I want to monitor, I made the script so that it uses environment variables to be configured for each VPN. The environment variables are:
VPN_ID- the numeric ID of the OpenVPN client.
PING_HOST- the host to ping to test if the VPN is alive.
When running the script, it’ll check to see if these environment variables are set. Then it’ll look for the VPN interface that matches the VPN ID that were provided. If it finds the interface, it attempts to ping the host host provided. If everything succeeds, it will exit with code
0 and do nothing more; otherwise, it will restart the OpenVPN client using
pfSsh.php and exit with code
You can test this from the command line by running it like so:
$ env VPN_ID=1 PING_HOST=mit.edu ./ensure_vpn.sh
To get this to run periodically, I used
cron. First I went into the Web UI and installed the
cron package under System -> Package Manager. Then, under Services -> Cron, I added two entries.
For both, I configured both entries like so:
- Day of the Week:
- Month of the Year:
- Day of the Week:
/usr/bin/env VPN_ID=2 PING_HOST=work.com /home/kiba/ensure_vpn.sh
This adds an entry in
/etc/crontab like so:
*/5 * * * * root /usr/bin/env VPN_ID=2 PING_HOST=work.com /home/kiba/ensure_vpn.sh
This will run the script every 5 minutes to ensure that the OpenVPN client stays alive.