OpenVPN Destination Port / Source Machine Based Routing

In OpenVPN I might want to route packets over the tunnel depending on certain metrics, such as the source port, source machine, destination IP or any combination thereof. This is quite simple with iptables:
The OpenVPN up script:
iptables -A forwarding_rule -o tun0 -j ACCEPT
iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE
ip rule add fwmark 1 table 1
ip route add default dev tun0 table 1
iptables -t mangle -A PREROUTING -s -j MARK –set-mark 1
iptables -t mangle -A PREROUTING -s -p tcp –dport 80 -j MARK –set-mark 1
# route all packets from eth0.2 to vpn
iptables -t mangle -A PREROUTING -i eth0.2 -j MARK –set-mark 1
# route packets from designated machines to vpn
iptables -t mangle -A PREROUTING -m mac –mac-source 00:23:10:00:44:44-p udp –dport 53 -j MARK –set-mark 1
Posted in Computers and Internet | Leave a comment

OpenVPN Bridge on CentOS (With br0 in /etc/sysconfig/network-scripts)

Having installed many OpenVPN systems I can almost configure it with my eyes closed… or so I thought! Whilst the previous statement might be true for routed setups, bridged configurations were an entirely different animal (for me at least).

The initial steps required installation of Sourceforge repositories (OpenVPN is not in the standarad CentOS repos), installation of OpenVPN, build of CA for the certificates, and installation of ntp to ensure time sync (if the time is wrong certificates will not validate).


rpm -K rpmforge-release-0.3.6-1.el5.rf.*.rpm
rpm -i rpmforge-release-0.3.6-1.el5.rf.*.rpm
yum update
yum install openvpn
cp -R /usr/share/doc/openvpn-2.0.9/easy-rsa/ /etc/openvpn/
cd /etc/openvpn/easy-rsa/
cd 2.0/
chmod +rwx *
. ../vars 
vi openssl.cnf 
vi vars 
./build-key-server um-hq1-svr1
./build-key road-warrior1
./build-key road-warrior2
cp -R keys/ /etc/openvpn/keys/
yum install ntp
chkconfig ntpd on
chkconfig openvpn on


We need to link the OpenVPN tap interface to the LAN port (in my case eth0). This is done below (for CentOS 5.x at least):

yum install bridge-utils 
cat /etc/sysconfig/network-scripts/ifcfg-br0
cat /etc/sysconfig/network-scripts/ifcfg-eth0

We then go onto add a script that will add the tap interface to the bridge when OpenVPN is started.

cat /etc/openvpn/bridge-start
# Set up Ethernet bridge on Linux
# Requires: bridge-utils
echo "adding $1 to bridge"
brctl addif br0 $1
ifconfig $1 up

OpenVPN Configuration

The server is setup to bridge using the tap interface below:

cat /etc/openvpn/roadwarrior-server.conf
dev tap0
ca /etc/openvpn/keys/ca.crt
cert /etc/openvpn/keys/um-hq1-svr1.crt
key /etc/openvpn/keys/um-hq1-svr1.key
dh /etc/openvpn/keys/dh2048.pem 
keepalive 10 60
user nobody
group nobody
verb 3 
up /etc/openvpn/bridge-start

Bridge Confirmation

To check everything is working we can check the interfaces and bridges. For starters, fire up OpenVPN (/etc/init.d/openvpn start) and you should see:

 brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.0004a70886d6       no              tap0

And also:

brctl show
bridge name     bridge id               STP enabled     interfaces
br0             8000.0004a70886d6       no              tap0
br0       Link encap:Ethernet  HWaddr 00:04:04:04:04:04
          inet addr:  Bcast:  Mask:
          inet6 addr: fe80::204:a7ff:fe08:86d6/64 Scope:Link
          RX packets:140288 errors:0 dropped:0 overruns:0 frame:0
          TX packets:129928 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:127719635 (121.8 MiB)  TX bytes:82040256 (78.2 MiB) 
eth0      Link encap:Ethernet  HWaddr 00:04:A7:04:84:04
          inet6 addr: fe80::204:a7ff:fe08:86d6/64 Scope:Link
          RX packets:140304 errors:0 dropped:0 overruns:0 frame:0
          TX packets:129950 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:129717057 (123.7 MiB)  TX bytes:82085992 (78.2 MiB)
          Interrupt:137 Base address:0x6c00 
lo        Link encap:Local Loopback
          inet addr:  Mask:
          inet6 addr: ::1/128 Scope:Host
          UP LOOPBACK RUNNING  MTU:16436  Metric:1
          RX packets:9 errors:0 dropped:0 overruns:0 frame:0
          TX packets:9 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:0
          RX bytes:1136 (1.1 KiB)  TX bytes:1136 (1.1 KiB) 
tap0      Link encap:Ethernet  HWaddr FE:38:CE:A4:4E:F1
          inet6 addr: fe80::fc38:ceff:fea4:4ef1/64 Scope:Link
          RX packets:0 errors:0 dropped:0 overruns:0 frame:0
          TX packets:466 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:100
          RX bytes:0 (0.0 b)  TX bytes:91883 (89.7 KiB) 
Posted in Uncategorized | Leave a comment

Low Overhead Console Based Torrent Client – rTorrent

Having used Java based torrent clients on older/embedded hardware (1GHz VIA processors) I have seen CPU utilisation saturate and systems grind to a halt. It is not practical to run GUIs or heavily emulated applications on these types of processors. Lets remember that in reality 1GHz is not all that slow, and coupled with plenty of RAM that processor makes an effective console server box without a clunky GUI to slow it down.
I am running CentOS 5.4 and came across rTorrent. As much as I love Linux, as usual there was something stopping the installation working out the box. The system pre-installed libcurl was causing rTorrent to timeout on its connections. This is a documented bug.

I was left with no choice but to build rTorrent and link it against custom libraries that it is compatible with. However I also needed to preserve the original version as the system libraries were linked against the older version. After lots of posts, environment variable fudges and hacks, finally a fellow Linux users helped out:

To group everything in one place I have put the steps below (again all credits to Markus for the help).

Additional Repos

First I setup sourceforge repositories and updated the system

rpm -K rpmforge-release-0.3.6-1.el5.rf.*.rpm
rpm -i rpmforge-release-0.3.6-1.el5.rf.*.rpm
yum update


yum install gcc gcc-c++ m4 make automake libtool pkgconfig perl openssl-devel ncurses-develwget
wget -xvzf curl-7.19.7.tar.gz
tar -xvzf libsigc++-2.2.4.tar.gz
tar -xvzf libtorrent-0.12.5.tar.gz
tar -xvzf rtorrent-0.8.5.tar.gzCompile Curl in /opt/curl-7.19.7


cd curl-7.19.7
./configure –prefix=/opt/curl-7.19.7
make install


Compile libsigc++ in /opt/libsigc-2.2.4

cd libsigc++-2.2.4
./configure –prefix=/opt/libsigc-2.2.4
make install


Compile libtorrent

cd libtorrent-0.12.5
rm -f scripts/{libtool,lt*}.m4
make install


To compile rTorrent we need to include the path to the libtorrent librarys as installed in the previous step.export PKG_CONFIG_PATH=/usr/local/lib/pkgconfig cd rtorrent-0.8.5
rm -f scripts/{libtool,lt*}.m4
./configure libcurl_CFLAGS=-I/opt/curl-7.19.7/include libcurl_LIBS=’-L/opt/curl-7.19.7/lib -lcurl -L/usr/kerberos/lib -lssl -lcrypto -lrt -lssl -lcrypto -ldl -lz -lz’
make install


The init.d scripts on the rtorrent wiki did not work for me (or broke at some point after reboot), after removing the redirection from the default script I saw the error “No screen session found.”  After digging around on the net came across another script that resolved this (apparently screen wasn’t running before the init.d script was called). I then added chkconfig lines and got the following config below:

# Comments to support chkconfig on RedHat Linux
# chkconfig: 345 85 15
# description: rtorrent – BitTorrent Client
# This script depends on screen.
# For the stop function to work, you must set an explicit session directory using absolute paths (no, ~ is not absolute) in your rtorrent.rc.
# If you typically just start rtorrent with just "rtorrent" on the command line, all you need to change is the "user" option. Attach to the
# screen session as your user with # "screen -dr rtorrent". Change "rtorrent" with srnname option. Licensed under the GPLv2 by lostnihilist:
# lostnihilist _at_ gmail _dot_ com

##Start Configuration##
#Do not put a space on either side of the equal signs e.g.

# system user to run as # not implemented, see d_start for beginning implementation
group=$(id -ng "$user")

# default directory for screen, needs to be an absolute path
base=$(su -c ‘echo $HOME’ $user)

# name of screen session

# file to log to (makes for easier debugging if something goes wrong)


case "$1" in
    echo "Starting $DESC: $NAME"
    [ -d "${base}" ] && cd "${base}"
    stty stop undef && stty start undef
    su $user -c ‘screen -d -m rtorrent’ &> /dev/null
    if [ $? -gt 0 ]; then
      echo "Failed to start $DESC: $NAME"
      echo "Started $DESC: $NAME"
    echo "Stopping $DESC: $NAME"
    killall -w -s 2 rtorrent &> /dev/null
    screen -wipe
    if [ $? -gt 0 ]; then
      echo "Failed to stop $DESC: $NAME"
      echo -n "Stopped $DESC: $NAME"
    $0 stop
    sleep 1
    $0 start
    echo "usage: $0 {start|stop|restart|force-reload}"
exit 0


Finally got Samba to enable pulling of files off the box, and to upload files to the watch directory so rtorrent would auto-start them.

yum install cups-libs samba samba-common
chkconfig smb on

And then edited the config file:

vi /etc/samba/smb.conf

        comment = Home Directories
        browseable = no
        writable = yes
        valid users = %S

Now downloading at nearly 900kB/sec with no more than 10% CPU utilisation (compared to 75% before at 120kB/sec with one particular Java based client I know!).

Posted in Uncategorized | 1 Comment

Dynamic DNS with your own domain name (for free!)

To date i have been using dyndns for dynamic dns hostnames using my own domain, whilst it works ok it costs and more importantly there is a limit on the number of hosts and it wasn’t clear if this could be increased.

So onto, its free for up to 50 hosts, provides many features, and if you want to add more its cheap to do so in additional blocks (starting from $60 per year).

Since I already have my DNS infrastructure on different servers I decided to delegated an entire subdomain for dynamic dns hosts called ‘sites’. So the FQDN for one of my hosts might be

With your DNS server delegate the subdomain to the nameservers by creating new nameserver records:

sites IN 14400 NS

sites IN 14400 NS

sites IN 14400 NS

sites IN 14400 NS

Next go to and create an account.

Create a new Domain, and enter something along the lines of (or whatever domain that suits you).

From there you can create dynamic hosts by clicking Dynamic DNS on the left menu, and then clicking Add to create new dynamic hosts.

In the destination field add (or other IP address you like), this will be updated by your dynamic DNS client.

Finally you need to configure your dynamic DNS client. This can be a wget script, or some devices have built in support for updates. For OpenWRT such support is built in, and its as simple as entering your username/password and the dyndns hostname. The rest will be automatically updated for you. That’s all there is to it, and all for free.

Posted in Uncategorized | Leave a comment

Installing CentOS 5.4 from Internet via PXE – Boot from Web!

Boot from USB eat your heart out – Standby for boot from Web!

Needed to get my embedded firewall up and running with CentOS 5.4, however it doesnt have a CD-ROM so brushed off the cobwebs on PXE boots which i havent done for years.

Spent 2 hours pulling my hair out as tftpd32 (build 335) running on Windows 7 wasn’t initialising pxe boot clients properly. Was getting ‘5184 Request 2 not processed’ errors, clients were getting an IP but didnt progress beyond that so not sure what the issue was.

Fired up the same config on Windows Vista and worked straight away. So much for those 2 hours of life wasted head scratching!! D$RT:F£$@""!

I stumbled across gPXE, from the website: "gPXE is an open source (GPL) network bootloader. It provides a direct replacement for proprietary PXE ROMs, with many extra features such as DNS, HTTP, iSCSI, etc". In summary its an advanced iSCSI, HTTP, FTP boot loader, that bootstraps from a PXE loader. With the normal PXE boot I would have to find pxelinux.0 (which isnt on CentOS CDs for some reason), configure pxelinux.cfg and all that stuff.

Thought it would be cool if the bootstrapped gPXE could boot from the internet server, so i gave it a try:

  1. Went to the following website to generate the PXE image:
  2. Added the following script (under advanced options):
    dhcp net0
  3. Hit ‘Get Image’ and downloaded the PXE file.
  4. Set the downloaded PXE file from the above steps to be served to via dhcp filename option in tftpd32 (in Vista not Windows 7!)
  5. Turned the clients on, hey presto the gPXE ran up after downloading from the tftp server, then proceeded to download and boot the kernels specified above.

The box is currently installing over the internet as i type… superb and no CDs needed!


Please dont laugh at the 70 mins install time… even though i pay best part of £100 a month my internet connection sucks!!

Posted in Computers and Internet | Leave a comment