Pages

Sunday, July 11, 2010

Bridged openvpn on ubuntu

At my work we use ubuntu "lucid lynx" as the operating system for openvpn. Our "lynx" is  a vmguest running on linx/qemu/kvm. We have linux and windows clients. Actually, all possible clients which support openvpn client mode.

First I setup our internet-facing shorewall firewall to allow 1194 and port-forward it to our internal openvpn (vm)hosts, using shorewall-rules. We use shorewall version 4.4.6.

#ACTION SOURCE DEST PROTO DEST_PORT ...
DNAT wan lan:192.168.11.3:1194 udp 1194 #network alpha
DNAT wan lan:192.168.22.3:1194 udp 1294 #network beta

We have a multi-isp setup, that is denoted by the wan (wide area network) under SOURCE. We also have two lans (local area networks) which use this shorewall machine as the gateway to the internet, using two different subnets to communicate within each lan. So I wrote two rules to port-forward from the firewall to the correct openvpn server.

This is called dNATing (destination network address translation + ing); in practical terms, an openvpn client knocks on a specific port on the firewall, giving the illusion that this whole business is between the firewall and the client, but in fact, the firewall is only passing messages to and fro between the openvpn server inside a lan and the remote client somewhere on the internet, regardless of whether the client itself is behind a firewall or directly on the internet. It just works.

As I have mentioned earlier we use openvpn, the specific version is 2.1.0.
I looked far and wide on the internet for openvpn bridging and only found this tutorial to be the easiest to setup. The weird thing is, that the tutorial supposed to be used with a N900 mobile phone from nokia.

1) Install the software. See the tutorial first.
2) I also setup the bridge first. As recommended by the tutorial.


auto lo br0
iface lo inet loopback

iface br0 inet static
address 192.168.11.3
network 192.168.11.0
broadcast 192.168.11.255
netmask 255.255.255.0
gateway 192.168.11.254
bridge_ports eth0
bridge_fd 9
bridge_hello 2
bridge_maxage 12
bridge_stp off

iface eth0 inet manual
up ifconfig $IFACE 0.0.0.0 up
up ip link set $IFACE promisc on
down ip link set $IFACE promisc off
down ifconfig $IFACE down
# do this in /etc/network/interfaces


3) Next you need to create the keys and certificates. This is the least difficult part.


sudo cp -a /etc/openvpn/easy-rsa ~/

chown -R user ~/easy-rsa
cd ~/easy-rsa
sudo chmod g+w . ; source ./vars ## execute your new vars file
./clean-all ## setup the easy-rsa directory (deletes all keys)
./build-dh ## takes a while consider backgrounding
./pkitool –initca ## creates ca cert and key
./pkitool –server server ## creates a server cert and key
cd keys
openvpn –genkey –secret ta.key ## Build a TLS key
sudo cp {server,ca}.crt {server,ta}.key dh1024.pem /etc/openvpn


4) Enable ip forwarding in /etc/sysctl.conf

5) Create the up.sh and down.sh shell scripts to create and kill the tap devices when a openvpn client logs on or off. Mind you that more parameters are passed to the scripts by the openvpn server than what the tutorial lets on. I found this out by turning on the debugging facilities of the openvpn script in /etc/init.d/openvpn, like this:


#!/bin/sh
set -e -x
..



Fix the permissions of the up.sh and down.sh files with this:

user@ovpnubuntu~/ sudo chmod go+rwx /etc/openvpn/{up,down}.sh


6) Modify the server.conf to reflect your lan's settings; for instance change the ip address of the "local" parameter. In our case it's 192.168.11.3. Port 1194.

local 192.168.11.3 1194


Openvpn has a built-in dhcp server, that distributes local ip addresses to openvpn clients. Make sure this is provisioned in your main dhcp server, so there is no chance of ip address collisions.

# openvpn server configuration file - server.conf
mode server
tls-server

local 192.168.11.3 1194
proto udp

dev tap0
up "/etc/openvpn/up.sh br0"
down "/etc/openvpn/down.sh br0"

persist-key
persist-tun

#certs
ca ca.crt
cert server.crt
key server.key
dh dh1024.pem
tls-auth ta.key 0

#cipher and compression
cipher AES-256-CBC
comp-lzo

#DHCP
ifconfig-pool-persist ipp.txt
## settings for openvpn dhcp server
server-bridge 192.168.11.254 255.255.255.0 192.168.11.216 192.168.11.224
push "dhcp-option DNS 192.168.11.5" # DNS
push "dhcp-option WINS 192.168.11.5" # windows-flavor DNS
push "dhcp-option DOMAIN ad.local" # for windows active directory objects or samba4!
max-clients 8

#log security
user nobody
group nogroup
keepalive 10 60
status openvpn-status.log
log-append server.log
verb 5


7) Configure /etc/defaults/openvpn; if you need to change the parameters passed to the openvpn server, modify OPTARGS:


OPTARGS="--fast-io --verb 5" # fast io for fast connections; verb for verbose debug output


After that you'll be able to restart the openvpn server automagically when the server goes down and has to reboot for some reason.

8) Create some keys for openvpn clients; as described in the tutorial:cd ~/easy-rsa ; source ./vars ; ./pkitool {user1,user2,user3,user4,joe,satch,bob,marilyn}

8a) If for some reason you want to prevent people from getting to your keys and/or certificates in cleartext; you can use openssl to encrypt your certificates and keys, while sending them across some unencrypted medium.

In my case, I wanted to send myself the keys etc. via e-mail, but I'm ultra-paranoid about big-brother sticking its nose in my beeswax. So I tarred and compressed my files first.

tar cf ~/openvpn-keys-certs.tar ~/easy-rsa ; bzip -z9 ~/openvpn-keys-certs.tar


Then I proceeded with encrypting the bzip2 file:

openssl aes-256-cbc -in openvpn-keys-certs.tar.bz2 -out openvpn-keys-certs.tar.bz2.enc


This is a form of symmetric encryption, so that means if someone finds out your passphrase you recently wrote down on a piece of paper, anyone who finds that paper can decode your message. Use hard passwords with a handful of these "!@#$%^&*();<>' in different cases with numbers in them.
Theoretically everything is brute-forceable, if one ignores the cost to crack the code. Unless there is some invariant loop-hole in the encryption algorithm to crack the dictionary of the compression algorithm.

Decrypt with this command:

openssl enc -d -aes-256-cbc -in openvpn-keys-certs.tar.bz2.enc -out openvpn-keys-certs.tar.bz2 ; tar xjf openvpn-keys-certs.tar.bz2


8b) Use asymmetric encryption like gpg. Send the encrypted keys and certificates to the user using her public key. Let her worry about the private key and passphrase. There is gpg4win for windows users.

9) Write a template client configuration file.

# template client configuration file - client.ovpn.txt
# Specify that this is a client
client

# Bridge device setting
dev tap

# Host name and port for the server (default port is 1194)
# note: replace with the correct values your server set up
remote firewall_ip_addr 1194

# Client does not need to bind to a specific local port
nobind

# Keep trying to resolve the host name of OpenVPN server.
## The windows GUI seems to dislike the following rule.
##You may need to comment it out.
resolv-retry infinite

# Preserve state across restarts
persist-key
persist-tun

# SSL/TLS parameters files created previously
ca ca.crt
cert replace.crt
key replace.key

# Since we specified the tls-auth for server, we need it for the client
# note: 0 = server, 1 = client
tls-auth ta.key 1

# Specify same cipher as server
cipher AES-256-CBC

# Use compression
comp-lzo

# Log verbosity (to help if there are problems)
verb 3


Each client requires three 4 files in total in our setup to connect; a) The common shared (ca.crt) certificate with the server; b) The client certificate; c) The client key; d) A configuration file.

You need to activate the template by replacing some parameters in the template with some real values. For instance there is no "replace.crt" nor "replace.key". This must be changed to some file name intended to be used by some user. For instance "bob".

So, given that you already created the key and certificate for "bob", you can create a configuration file using the template like this:

sed 's/replace/bob/g' client.ovpn.txt > bob-client.ovpn ; sed -i 's/firewall_ip_addr/real_firewall_ip_addr/' bob-client.ovpn

Working at home with ssh port-forwarding, qemu/kvm and vnc

Sometimes I work at home because I don't want to get constantly bothered by people barging into my room with trivial requests etc. Every time someone barges into my room, I find that regaining my focus takes too much effort.

To actually get any work done, I made it possible for me to log into the system by punching a hole in the firewall for ssh traffic. I increased the security by disallowing password authentication and forcing asymmetric encryption authentication, i.e. 2048-bit rsa public key authentication, where I am the sole owner of the private key. Above all, I also limited the number of (internet) locations where this private key can be used, by putting this in the public key (authorized_keys):

from="*.this.is.my.isp.tld" ssh-rsa MEH...

At my work we work a lot with ssh and virtual machines. We use linux/qemu/kvm. Kvm can be initialized with the "-vnc :N" parameter, where N is a positive integer. This creates a vnc session on the vmhost. For instance, if one were to use krdc and N is 1, the invocation command would look like something like this:

user@vmhost~$ krdc vnc://vmhost:5901

The rule is to add N to 5900. That's how you find the port. You can also run a vnc client on the local network to view the vnc stream. This is very convenient because you're not stuck with one port for multiple vmguests.

user@somewhere~$ krdc vnc://vmhost:5901

To make things easier for yourself when working at home, you could port-forward this very remote vnc port to your own localhost with this invocation:

user@athome~$ ssh -f -N -L 6001:vmhost_internal_ip_addr:5901 firewall_ip_addr
user@athome~$ krdc vnc://localhost:6001

The parameters "-f -N" forces this ssh client session in the background. The relevant part is the "-L" parameter. The L probably stands for local, there is also an R counterpart that port-forwards a local port to a remote port.

This is a form of tunneling where a remote port in some remote (local) area network,  could be plugged in directly into your localhost as if this service is running on your local machine.

This trick also applies to other tcp-based protocols, for instance the standard rdp (remote desktop protocol) port. For instance you have some windows machines you would like to log on to, as if they are running on you local machine, you do the following:

user@athome~$ ssh -f -N -L 4489:windows_machine_ip_addr:3389 firewall_ip_addr
user@athome~$ krdc rdp://localhost:4489


Voila! Instant connection to a worksite windows machine. This trick also applies to windows machines using putty.

Thursday, June 24, 2010

Create a bridge (software switch)

To expedite the setup of a vmhost, where vmguests can be installed and initialized, I created two projects to facilitate the creation of bridges on vmhosts:

git clone git://github.com/Buggaboo/slackware-kvm-scripts.git
git clone git://github.com/Buggaboo/ubuntu-kvm-scripts.git

The ubuntu one works on ubuntu and all debian-based systems. The slackware one works on all slackware -based systems. The can be fetched by git cloning as described above. To setup both, you need the binaries brctl and tunctl. Brctl and tunctl.

Read the README file and have fun!

Tuesday, June 22, 2010

Make ubuntu's screen play nice with nano shortcuts

I use nano a lot either for programming or editing configuration files on linux. At work we use both ubuntu servers for vmguests and vmhosts.

The main reason I use nano is because they have a preconfigured shortcut-key on your keyboard to save your current document: F3.

You will not catch me hitting esc,colon,w; escape to non-insert mode; :w to write from edits on memory to file in vim. Nor will I do whatever they do in emacs.

I'd rather gain mastery of the language, than mastery of an editor, with my limited time.

Since I have to do stuff simultaneously, I use screen a lot to switch between shells and tasks.

Anyways, in ubuntu the maintainers accidentally hijacked the F3  shortcut with a conflicting shortcut F3 in screen; So, what happened is this, I edit a file with nano, I attempt to save, it but find myself in another screen. You could imagine why that would piss me off. Context-switching craziness.


What you do next to fix the unintentional context-switching is to attack screen. Namely, the configuration files.


In ubuntu they put this in your home dir.

You want to find change your keybindings file.


find ~/ -name "keybindings"


When you crack the file open you'll find something like this:


source /usr/share/screen-profiles/keybindings/common


All I needed to do was to copy that common file up there to /home/user/.screen-profiles/user-common-keys and adapt keybindings to reflect the change.

All I wanted was to regain the ability to save my files with F3 function key. So I smote away this line from the file:


bindkey -k k3 prev ...


and change the keybindings file.


source /home/user/.screen-profiles/user-common-keys


Then they lived happily ever after.

Arithmetic mind hacking, part 1: addition

I have a bad memory for numbers. Really bad. It has improved since I started studying arithmetic strategies. I wish I started earlier, but we didn't have the internets when I was younger, o, also my social standing did not depend on my number-crunching abilities then.

Let's talk about addition. I think this is the easiest concept to absorb for most people.

You have one cookie, then you get another cookie from a loving spoiling parent/guardian, then you have how many cookies?

Zero; because before you considered the metaphysical abstract notion of numbers you already ate the cookies.

To crunch numbers quickly we need to get practical. Brutally practical, if it doesn't work for you, practice. If it still doesn't work for you, simplify, adapt, remould, evolve; stir and shake; rinse and repeat.

Say I have... 2512 cookies and I find 3467 cookies stored in a jar. How many cookies do I have in total?

First strategy proposal:

I round off the trickiest looking number, to me that would be 3467, upwards to 3500; that would be a difference of 33.

I add 3500 to 2500 and add 12 later.

3500 + 2500 = 6000

Then I take 33, I round that off to 40.

6000 - 40 = 5960

I took too much so I give back 7.

5960 + 7 = 5967

I almost forgot I suspended 12 from the game; so I gotta get it back.

5967 + 12 = 5979.

2nd strategy proposal:

That previous strategy took 4 steps. It could get simplified.

How about starting by subtracting 12 from the rounded up difference of 33?
Conceptually it's like this: I borrowed 33 to get a nice round number, but instead of paying back in full, I pay back some right now (12).

33 - 12 = 21 (I still owe)

So I add as we did previously.

3500 + 2500 = 6000

We pay back the 21 by subtracting.

6000 - 21 = 5979

The difference

The first is more explicit, but it requires more memory, because of the 12.

The 2nd requires a wee less memory for numbers but it requires some practice because it requires the use concepts of borrowing and repayment in the rounding-of-the-numbers phase; but the payoff is in the number of steps.

It's one of those memory vs. time trade-offs.

The third and final strategy proposal

Go into heuristic mode. Check whether 10 and 60 make a hundred, 2 and 7 make a ten. No?

Now just add those up

(10 + 60) + (2+7) = 79

3400 + 2500 = 6000


This one requires a heuristic, in contrast with the previous proposals, that checks if a sum of decimal numbers go over 9.

Final note

The previous strategies were overkill for this problem.

For instance 789 + 837 and the previous strategies would work out great with this example.

Round off the number which contains a combination which add up to more than 9.  The one closest to 9; which would be 789. We have a debt of 11; in other words, we borrowed 11.

800 + 837 = 1637
1637 - 11 = 1626

During addition, check for sums larger than nine. Round off or just add the numbers. It's quite simple really. Some people have the innate ability to figure out these strategies, but other people need a tiny push in the right direction.

Portscanner: nmap

Recently, I wanted to list all the mac addresses of all our voip telephones (not to be confused with softphones) and reserve a block of addresses from our ip-address space and map each macaddy to an ip addy.

I already knew of nmap and I wondered how one could get all the mac addresses.

So I scanned with nmap.

I dug around on the net and bumped into this mindmap. Since I was scanning locally and not sniffing around someone else's stuff, I could get aggressive (-T5).


sudo nmap -T5 ... ip_addr_range


I wanted output I could grep, so I picked a typical output format (-oG).


sudo nmap ... -oG grepme.txt ...


I found out from the nmap man page, that nmap can do fingerprinting with the -O switch.


sudo nmap -O ip_addr_range -T5 -oG grepme.txt ...


Then I found out that the -oG option did not output the mac address. I was bummed out.

Some monkeying around I found out one could sed using multiple patterns, but that would take effort.

Update 23-07-2010: Some googling led to this command (from this blog)

First try:

nmap -T5 -sP -n ip_addr_range | tee log.txt | sed -n '1!H;${;g;s/Host \([0-9.]\+\) is up.*MAC Address: \([0-9A-F:]\+\)/\1 \2/g;p;}'

Way too greedy.

2nd try:
... still working on it...

Sunday, June 6, 2010

Alternative input devices and udev

If you have or own:
  1. an alternative character input device, e.g. typematrix keyboard (why);
  2. a keyboard with its own unique layout e.g. dvorak;
  3. a family where most of the members use the same computer;
  4. a gnu/linux computer with udev support, where you have root permission;
  5. a desire to automate changing the keyboard layout when plugging your alternative device in;
Udev is this nice system in linux where you can use certain attributes of devices to write rules so you could run certain scripts, mount devices etc. i.e. give behaviour to certain devices, when they are introduced to your operating system (Linux).

There might be predefined rules already in your /etc/udev/rules.d, check it out.

To gather info about your device, hit lsusb for usb devices and hit lspci for more info about any other non-usb devices.

You need the following command to figure out the attributes required to create the conditions for a certain rule:

$ udevadm info -a -p $(udevadm info -q path -n /dev/input/eventX) --walk-attributes

# NOTE: /dev/input is where your mouse or keyboard is usually put.

You can create general rules or device-specific rules for certain devices; For instance you can figure out what the ATTRS{idVendor} of a certain device and it would match with every device made by this vendor (in theory).
 You could also match with ATTRS{serial} and only that device containing that serial number would make the rule fire (in theory).

In udev rules file, only a rule per line is allowed. You can test the validity of a rule by writing a dummy function, i.e. echo to a file in /tmp/udevtest.txt. While plugging and unplugging the device (in my case a keyboard), check if the 'add' and 'remove' ACTION(s) are actually firing, by checking 'udevadm trigger'.

Next step is to write decide what to do with the rule. Recall I mentioned dvorak (pronounced as: dvor-zh-ak, it's czech), if you want to load a certain keyboard layout try writing a udev rule like this in /etc/udev/rules.d/111-typematrix-kb.rules:

## via Xorg
ACTION=="add", KERNEL=="event?", SUBSYSTEMS=="usb",ATTRS{idVendor}=="ffff", ATTRS{idProduct}=="8081",RUN+="/usr/bin/setxkbmap -model 102 -layout dvorak"

ACTION=="remove", KERNEL=="event?", SUBSYSTEMS=="usb", ATTRS{idVendor}=="ffff", ATTRS{idProduct}=="8081", RUN+="/usr/bin/setxkbmap -model 102 -layout us_intl"


If your rule fires repeatedly for no apparent reason, try writing less general rules and change the wildcard * to ? so it matches with only a single character. Hit man udev when you're clueless about how your rule should look like. Also use ATTR instead of ATTRS where appropriate, hit the --walk-attributes in udevadm I just mentioned.

Next post: How to setup udev and OCZ NIA to control your computer with your mind. (TODO)