Saturday, November 1, 2014

VPN Autoconnect at Startup in Ubuntu

I am using Ubuntu 12.04 with XFCE4 and the VPN Autoconnect option in the network configuration doesn't do any good. As far as I know this is a bug which causes the VPN autoconnect to malfunction if a new network is joined, be that ethernet or WiFi. This is kind of a big problem as one needs to connect to the internet first before the VPN connection can be established.

VPN Configuration - (Autoconnect checkbox does not work)
The solution I found best working is to create a shell script that manually connects to a VPN with a delay of 15 seconds. This delay allows sufficient time for the operating system to establish an internet connection, after which connecting to the VPN should be smooth. If you do not add a delay, the VPN connection may start before you have an internet connection and hence fail.

Tip: You can play around with the delay time, likely on a faster computer an internet connection may as well be established in under 10 seconds. My system takes a bit longer to boot and I found 15 seconds to be acceptable and working just fine.

List Available VPN Connections & Get UUID

nmcli con

This will give you an output with all your network connections, including the saved VPN profiles.
Copy the UUID of the VPN connection you want to establish. (I will refer to this as <UUID> further on)

Create a Shell Script that Manually Connects

Create a shell script, lets say call it with the following in it

#Script to automatically connect to VPN
sleep 15;nmcli con up uuid <UUID>
(<UUID> here is of course the UUID you copied in the previous step)
make the script executable by
sudo chmod +x

Adding Script to Startup in rc.local

Add script to /etc/rc.local to have it executed at system start. Your rc local file will look something like this,
nano /etc/rc.local

#!/bin/sh -e
# rc.local
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
# In order to enable or disable this script just change the execution
# bits.
# By default this script does nothing.
# Set screen backlight to 75%
xbacklight -set 75
#Connect to VPN after 15 seconds (allows connecting to the internet first)
sh /route/to/script/
exit 0
Save the file and you are done. The next time the computer starts up, after the delay of 15 seconds set in the script file a VPN connection will be initiated. 

Of course you can also directly add the command to rc.local, however if you have multiple VPNs and plan to change it in the future, a separate file might be better (little longer script) where you can set which VPN you want to connect to. Also, using a separate script can help you keeping your rc.local file more clean and organized.

Important: Place the script somewhere where you will not delete it accidentally or move it. If the file is moved then at the next startup rc.local won't be able to execute it (clearly). The problem arises when you trust the script and go ahead browse the web and find it out 30 minutes later that you are not using a VPN specifically because the file was moved and hence at boot no connection was made. Yeah. I personally like having a "Scripts" directory under my home that contains such small scripts.

Count the Occurence of All Words in a Number of Text Files

Recently I was given the task to analyse a range of files (around 300) and count the occurrence of all the words in each file. So the aim was to put together a piece of code that goes through all files in a directory, reads in a file, lists all the words occurring in it and counting how many time each word has occurred.

I quickly found out that in case of a single file the process is rather simple, the following code does a fine job,

for w in `cat FILE.txt`; do echo $w;done|sort|uniq -c >> results.out
This code reads in FILE.txt and for each word in it counts its occurrence and the creates a list from it.

However putting this into a recursive script was a little more complicated. So I took another direction and found a piece of code using sed to do the same job on a single file. With this and some scripting knowledge I was able to put together just what I needed.

Additionally, I used the command basename to output the name of the file so I know which file was which.

The final piece of code looks like this,

for file in `ls /PATH/TO/DIRECTORY/`
results.out        sed s/' '/\\n/g /PATH/TO/DIRECTORY/FILE | sort | uniq -c | sort -nr >>  results.out
echo "" >>  results.out

This does a perfect job and creates a single file with the output containing,
  • File name of each file
  • Occurrence of each word in the file, sorted from high to low
  • Empty line to separate data from each other
If anyone has any other suggestion or comment I am happy to hear it!