One of the things I wanted to get from my OpenVPN Access Server was a usage report that would be emailed to me regularly. OpenVPN Access Server writes such logs to a file in /var/log on Ubuntu and Debian based systems. However it also writes a lot of other things. So I first started by examining the log. The key information I wanted was:
Date and Time of Successful Connections
Username
In my setup, OpenVPN connected users are put into a unique IP subnet and assigned an address by a DHCP server that is part of Access Server. All very easy to setup. In digging through the logs I found entries that are made whenever an IP address is assigned to a newly connected user.
An entry looked something like this:
As you can see from that we get date and time, username, and public IP address/port they are coming from in addition to the assigned internal IP address. The public IP and the assigned internal IP are more than just icing on the cake as that kind of info can be useful when correlating with logs from other security devices. So yay for extras!
One of the unique line items that appears consistently in each of these entries is “MULTI: primary virtual IP”. So to filter the entire log down to just show these entries we can use one of my favorite and most loved tools, GREP.
That outputs just those entries to the command line. However, each entry contained a lot of stuff I didn’t care about. So to clean it up I turned next to another wonderful tool called AWK.
And that cleans it up and leaves me a with list of entries that look like this:
Okay, so now I have a list of entries that I care about. What next? Well, I need to get these sent to me regularly in a report, preferably by email… so that means a SCRIPT! But there are a few considerations.
First, if I set a script to run on a schedule and I am always pulling from the active log I am probably going to get a lot of repeat entries… not very useful and lots of useless emails. However, Ubuntu Server does log rotation. The log rotates often enough that the info I pull will be recent enough if I grab it from the most recent rotated log file vs. the current active log file. So rather than pulling from /var/log/openvpnas.log, I will instead pull from openvpnas.log.1. This is great because this gives me a static file that gets updated/replaced regularly.
My script however is going to run on a schedule via cron. Say, hourly… I don’t want a bunch of the same emails coming in, I only want to email once the log has rotated. So that means I need to compare what I pulled in the past, to what is currently in the log.1 file. If they are the same, don’t email, if they are different, send the email. That required logic means I need an if/then statement.
Once it is all put together the end result looks something like this:
logchk="$(cat /var/log/ovpn.log.1.chk)"
logoutput="$(cat /var/log/openvpnas.log.1 | grep "MULTI: primary virtual IP" | awk '{print $7,$8,$9,$10,$11,$18,$19}')"
server="$(hostname)"
email="[email protected]"
if [ "$logoutput" != "$logchk" ];
then
echo "not equal"
echo -e "OpenVPN Usage For:\n\nserver: $server\n\n ${logoutput}" | mail -s "$server, OpenVPN Usage Report" $email
echo "${logoutput}" > /var/log/ovpn.log.1.chk
fi
A few other notes. You can see that I declare a variable at the very top called “logchk” and it is going to contain the output from a file called ovpn.log.1.chk. That file doesn’t exist at the start of all of this so you need to create it (seed it?).
That command creates an empty file in the right location. The first time the script runs it will send an email because the contents of that file (empty) are different from the contents of the logoutput variable (which contains the current contents of our cat/grep/awk command I talked about earlier).
The very last command of the “then” statement writes the contents of the current log to that file so if this script runs again, and the logs haven’t rotated yet, the script just exits and doesn’t send anything.
It should also be noted that your server needs to be able to send email. I recommend Exim and if you just need it for send-only email operations I have a very easy-to-follow guide for getting it setup here: Install Exim4 MTA with One Command
There is also an email variable in the script and you need to change it to hold the email address where you want to receive reports.
Once your are all done configuring your script, save it, chmod +x it, then drop it in the /etc/cron.hourly folder. Make sure the file name of the script doesn’t have an extension. So it should be “script” –not– “script.sh”. If it has an extension, cron will ignore it.
That wraps it up! This should help you keep an eye on usage of your OpenVPN Access Server!