Article
0 comment

How to create OpenVPN config files for Witopia

I use a Dell laptop with Ubuntu 15.04 and the VPN NetworkManager seems to be sort of broken. So I guessed I just resort to plain old OpenVPN Config files. And since I’m a very lazy guy I wanted to have some sort of script generating all that stuff for me. First of all you need a prototype template for the config file. There is one that comes with the downloadable zip from Witopa and is called “SampleConfig.txt”. Copy that to “prototype.txt” and change the line

remote [REPLACE WITH SERVER NAME] 1194

to

remote SERVERNAME 1194

Our script will later on replace the “SERVERNAME” with the actual Witopia VPN server names. In the directory where “prototype.txt” lives, create a subdirectory and put the crypto files from the Witopia zip in. These are: ca.crt, ta.key, USERNAME.crt, USERNAME.key. “USERNAME” will be your username (think you guessed that :)
Now create in the prototype directory a file called “createConfigs.sh” with the following content:

#!/bin/bash

rm -f data/*.ovpn

serverlist=`curl -s https://www.witopia.net/?faq-item=openvpn-ssl-gateway-locations | sed -e "s/<[^>]*>//g" | egrep "^vpn"`

for server in $serverlist;
do 
  filename=data/`echo $server | cut -d . -f 2 - | sed 's/\([a-z]\)\([a-z]*\)/\U\1\L\2/g'`.ovpn;
  echo "Generating $filename";
  cat prototype.txt | sed "s/SERVERNAME/$server/g" > $filename
done

Line 3 cleans up the data directory for the files to come. Line 5 grabs the web page with the VPN server pages from Witopia.net, eliminates the HTML stuff via sed and greps lines starting with “vpn”. Then we loop through the server list and create an OpenVPN config file in data/ for each server, named “City.ovpn”. First we need to build the filename by grabbing the second field of the server name like “vpn.munich.witopia.net”. We cut the city name out and capitalize the first character. This is my personal preference, you can just leave it lower case if you like. Last part is replacing “SERVERNAME” with the actual server naame via sed and putting it in a file with the freshly created name. Thats it.

But if you are as lazy as me you also would like to have a start script which only needs the name of a city to connect you. Here we go:

#!/bin/bash

city=`echo $1 | sed "s/\.ovpn//g" | tr '[:upper:]' '[:lower:]' | sed 's/\([a-z]\)\([a-z]*\)/\U\1\L\2/g'`
filename="$city.ovpn"

if [ -e "$filename" ]
then
  echo "Starting OpenVPN with $city"
  sudo openvpn --client --config $filename --ca ca.crt
fi

This script called “start.sh” resides in the data/ directory takes one argument: the name of a city or of a *.ovpn config file. So valid start script calls are:

./start.sh munich
./start.sh Munich
./start.sh MUNICH
./start.sh munich.ovpn
./start.sh Munich.ovpn
./start.sh MUNICH.ovpn

As you can see line 3 of the script cuts out the city name, casts all characters to lower case and capitalizes the first character. Then we (re-)add the extension “.ovpn” in line 4 and if there is a config file with that name we start the openvpn client. We need to do that as root user so you problably will need to enter your root password when the openvpn is sudoed.

Thats it, folks. Happy networking :)

Article
0 comment

Separating structure and semantics

There is a great and simple rule, known as “Micha’s Golden Rule”, which goes back to Micha Gorelick (@mynameisfiber). It states:

Do not store data in the keys of a JSON blob.

This means, that instead of writing a JSON dataset holding people and their gaming scores like this:

{
  "Volker": 100,
  "John": 300
}

you should use something like:

[
  {
    "name": "Volker",
    "score": 100
  },
  {
    "name": "John",
    "score": 300
  }
]

First of all, it is good practice, to separate data and its meaning. Second it simplifies software development. And here is why:

One reason is, that in the first form you have no idea, what exactly the number associated with the name means. And when accessing the data you need to know the keys. But the keys are part of the data. So you first have to parse the whole file, separate the keys and iterate over them. In the second case you can iterate over a set of completely identical structured data sets and fetch names and scores.

This rule not only holds true for JSON but for any structured data like XML or yaml. Consider the following modified XML example from the SimpleXML section of the PHP manual:



 
  PHP: Behind the Parser
  Rasmus Lerdorf
  1
 

In PHP you would access the director in this way:

movie[0]->director;
?>

Now if you would like to use the directors name as a key to get the number of oscars he won, it would look like:



 
  PHP: Behind the Parser
  1
 

This is perfectly valid but stupid XML. And to access the data you need to know the name of the director:

movie[0]->RasmusLerdorf;
?>

Doesn’t make too much sense, hm? One additional drawback I didn’t mention but that you nevertheless saw: the keys of a data structure language often are subject to several limitaions. In XML element names e.g. there can’t be spaces. So you have to work around that e.g. by camelcasing the name. To get the name back in readable form, you would have to parse it and insert spaces at the correct positions. Which can be impossible with human names, since there are camelcased names like “DeLorean”.

Considering this rule is not always obvious but can save you a lot of nerves. Take care!

Article
0 comment

I wish I could look at that in my browser …

Sometimes you would like to see some information, which is readily available from a unix command in your browser. If it’s in a private network and / or the information doesn’t do any harm when read by unauthorized people or it’s for a rather short period of time, then ashttp does the trick.
ashttp is a python script by Julien Palard (@sizeof) using a headlesss vt100 terminal emulator to run a script each time the http server gets a request, grab the output and deliver it via http to the requesting browser.
For example the output of top:

ashttp -p 8081 top

This will start up an http server on port 8081 (you can also use –port) and every request to that server will deliver the output of a fresh top command:
ashttp_top
At the moment there seems to be a small problem with forwarding the command line parameters of the unix command, so you can circumvent that by putting your more complex statement into a shebang’ed shell script and calling this one from ashttp:

#!/bin/bash
watch -n1 ls -lah /tmp

Have fun!

Update: @n770 correctly mentioned, that having swig installed is a prerequisite to building the python hl_vt100 module.