Compiling OPENVPN for NSLU

The pre-compiled OPENVPN package works fine except that if you want to have your username and password credentials to be automatically supplied via the command line option –auth-user-pass your out of luck.

If you don't care about this then you can just use the default package.

ipkg install openvpn

To enable this additional command line option you need to recompile the openvpn source with the –enable-password-save option present.

First you need a native development environment: Natively Compile Unslung Packages

ipkg install optware-devel

Then you need to obtain the source code. If the information below is out of date then refer to for the latest SVN location.

ipkg install svn

mkdir source
cd source
svn co

Then make sure some additional libraries are also present

ipkg install openssl-dev
ipkg install lzo

There are many options that can be supplied to the configuration program.

# cd openvpn
# ./configure --help
`configure' configures OpenVPN 2.1_rc7b to adapt to many kinds of systems.

Usage: ./configure [OPTION]... [VAR=VALUE]...

To assign environment variables (e.g., CC, CFLAGS...), specify them as
VAR=VALUE.  See below for descriptions of some of the useful variables.

Defaults for the options are specified in brackets.

  -h, --help              display this help and exit
      --help=short        display options specific to this package
      --help=recursive    display the short help of all the included packages
  -V, --version           display version information and exit
  -q, --quiet, --silent   do not print `checking...' messages
      --cache-file=FILE   cache test results in FILE [disabled]
  -C, --config-cache      alias for `--cache-file=config.cache'
  -n, --no-create         do not create output files
      --srcdir=DIR        find the sources in DIR [configure dir or `..']

Installation directories:
  --prefix=PREFIX         install architecture-independent files in PREFIX
  --exec-prefix=EPREFIX   install architecture-dependent files in EPREFIX

By default, `make install' will install all the files in
`/usr/local/bin', `/usr/local/lib' etc.  You can specify
an installation prefix other than `/usr/local' using `--prefix',
for instance `--prefix=$HOME'.

For better control, use the options below.

Fine tuning of the installation directories:
  --bindir=DIR           user executables [EPREFIX/bin]
  --sbindir=DIR          system admin executables [EPREFIX/sbin]
  --libexecdir=DIR       program executables [EPREFIX/libexec]
  --sysconfdir=DIR       read-only single-machine data [PREFIX/etc]
  --sharedstatedir=DIR   modifiable architecture-independent data [PREFIX/com]
  --localstatedir=DIR    modifiable single-machine data [PREFIX/var]
  --libdir=DIR           object code libraries [EPREFIX/lib]
  --includedir=DIR       C header files [PREFIX/include]
  --oldincludedir=DIR    C header files for non-gcc [/usr/include]
  --datarootdir=DIR      read-only arch.-independent data root [PREFIX/share]
  --datadir=DIR          read-only architecture-independent data [DATAROOTDIR]
  --infodir=DIR          info documentation [DATAROOTDIR/info]
  --localedir=DIR        locale-dependent data [DATAROOTDIR/locale]
  --mandir=DIR           man documentation [DATAROOTDIR/man]
  --docdir=DIR           documentation root [DATAROOTDIR/doc/openvpn]
  --htmldir=DIR          html documentation [DOCDIR]
  --dvidir=DIR           dvi documentation [DOCDIR]
  --pdfdir=DIR           pdf documentation [DOCDIR]
  --psdir=DIR            ps documentation [DOCDIR]

Program names:
  --program-prefix=PREFIX            prepend PREFIX to installed program names
  --program-suffix=SUFFIX            append SUFFIX to installed program names
  --program-transform-name=PROGRAM   run sed PROGRAM on installed program names

System types:
  --build=BUILD     configure for building on BUILD [guessed]
  --host=HOST       cross-compile to build programs to run on HOST [BUILD]
  --target=TARGET   configure for building compilers for TARGET [HOST]

Optional Features:
  --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
  --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
  --disable-lzo           Disable LZO compression support
  --disable-crypto        Disable OpenSSL crypto support
  --disable-ssl           Disable OpenSSL SSL support for TLS-based key exchange
  --disable-multi         Disable client/server support (--mode server + client mode)
  --disable-server        Disable server support only (but retain client support)
  --disable-plugins       Disable plug-in support
  --disable-management    Disable management server support
  --disable-pkcs11        Disable pkcs11 support
  --disable-socks         Disable Socks support
  --disable-http          Disable HTTP proxy support
  --disable-fragment      Disable internal fragmentation support (--fragment)
  --disable-multihome     Disable multi-homed UDP server support (--multihome)
  --disable-port-share    Disable TCP server port-share support (--port-share)
  --disable-debug         Disable debugging support (disable gremlin and verb 7+ messages)
  --enable-small          Enable smaller executable size (disable OCC, usage message, and verb 4 parm list)
  --enable-pthread        Enable pthread support (Experimental for OpenVPN 2.0)
  --enable-password-save  Allow --askpass and --auth-user-pass passwords to be read from a file
  --enable-iproute2       Enable support for iproute2
  --enable-strict         Enable strict compiler warnings (debugging option)
  --enable-pedantic       Enable pedantic compiler warnings, will not generate a working executable (debugging option)
  --enable-profiling      Enable profiling (debugging option)
  --enable-strict-options Enable strict options check between peers (debugging option)
  --disable-dependency-tracking  speeds up one-time build
  --enable-dependency-tracking   do not reject slow dependency extractors

Optional Packages:
  --with-PACKAGE[=ARG]    use PACKAGE [ARG=yes]
  --without-PACKAGE       do not use PACKAGE (same as --with-PACKAGE=no)
  --with-ssl-headers=DIR  Crypto/SSL Include files location
  --with-ssl-lib=DIR      Crypto/SSL Library location
  --with-lzo-headers=DIR  LZO Include files location
  --with-lzo-lib=DIR      LZO Library location
  --with-ifconfig-path=PATH   Path to ifconfig tool
  --with-iproute-path=PATH    Path to iproute tool
  --with-route-path=PATH  Path to route tool
  --with-mem-check=TYPE  Build with debug memory checking, TYPE = dmalloc or valgrind

Some influential environment variables:
  CC          C compiler command
  CFLAGS      C compiler flags
  LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
              nonstandard directory <lib dir>
  LIBS        libraries to pass to the linker, e.g. -l<library>
  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
              you have headers in a nonstandard directory <include dir>
  CPP         C preprocessor

Use these variables to override the choices made by `configure' or to help
it to find libraries and programs with nonstandard names/locations.

Report bugs to <>.

One problem that we need to address before doing anything is to avoid LD_LIBRARY_PATH hell. So we check to see what library paths will be searched by default by the linker.

# ld --verbose | fgrep SEARCH
SEARCH_DIR("=/usr/local/lib"); SEARCH_DIR("=/lib"); SEARCH_DIR("=/usr/lib");

On an UnSlugged NSLU the libraries live in /opt/lib and this is not in the path. We will need to provide some additional runtime path (rpath) hints to the linker. This can be done by including switches in the LDFLAGS environment variable before compilation.

# LDFLAGS="-Wl,--rpath -Wl,/opt/lib"

I found that if openvpn uses /opt/bin/ifconfig instead of /sbin/ifconfig the link does not come up correctly. So we need to explicitly tell configure which program to use in addition to the non standard locations for the dynamic link libraries and their headers.

Now we can proceed with the compilation

# ./configure --enable-password-save --prefix=/opt --with-ssl-headers=/opt/include --with-ssl-lib=/opt/lib --with-lzo-headers=/opt/include --with-lzo-lib=/opt/lib --with-ifconfig-path=/sbin/ifconfig

After the compilation we will end up with an executable that contains symbol table information useful for debugging however we don't need this so it can be safely removed.

strip openvpn

If everything goes well running it should produce the following

# ./openvpn --version
OpenVPN 2.1_rc7b armv5b-unknown-linux-gnu [SSL] [LZO1] built on May  7 2008
Developed by James Yonan
Copyright (C) 2002-2005 OpenVPN Solutions LLC <>

Now we are able to configure OPENVPN to use this new feature. We start by creating a new /opt/etc/init.d/S20openvpn startup file.

# Startup script for openvpn as standalone server
# Make sure IP forwarding is enabled
echo 1 > /proc/sys/net/ipv4/ip_forward
# Make device if not present (not devfs)
if ( [ ! -c /dev/net/tun ] ) then
  # Make /dev/net directory if needed
  if ( [ ! -d /dev/net ] ) then
        mkdir -m 755 /dev/net
  mknod /dev/net/tun c 10 200
# Make sure the tunnel driver is loaded
if ( !(lsmod | grep -q "^tun") ); then
        insmod /opt/lib/modules/tun.o
# I you want a standalone server (not xinetd), comment out the return statement below
#return 0
## This is for standalone servers only!!!!
# Kill old server if still there
if [ -n "`pidof openvpn`" ]; then
    /bin/killall openvpn 2>/dev/null
# Start afresh - add as many daemons as you want
/opt/sbin/openvpn --daemon --cd /opt/etc/openvpn --config openvpn.conf --auth-user-pass vpn.password

For details of how to configure openvpn.conf and this new option see

Routing via the NSLU

Once the NSLU has a tunnel to a remote host we want to be able to use this device as a gateway. To do this we will use iptables

ipkg install iptables
ipkg install kernel-module-ip-tables
ipkg install kernel-module-iptable-filter
ipkg install kernel-module-ip-conntrack
ipkg install kernel-module-ipt-masquerade
ipkg install kernel-module-ipt-state
ipkg install kernel-module-iptable-nat

Then we need to setup the NSLU so that it will forward packets. The follow code will achieve this.

insmod ip_tables
insmod iptable_filter
insmod ip_conntrack
insmod iptable_nat
insmod ipt_state
insmod ipt_MASQUERADE
# Set IP-Forwarding
echo "1" > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o $WLAN -j MASQUERADE
# Clear all chains
iptables -F
iptables -F -t nat
# In the NAT table (-t nat), Append a rule (-A) after routing
# (POSTROUTING) for all packets going out the outside interface
# (-o $WLAN) which says to masquerade the connection
iptables -t nat -A POSTROUTING -o $WLAN -j MASQUERADE
# Create chain which blocks new connections, except if coming from inside.
iptables -N block
iptables -A block -m state --state ESTABLISHED,RELATED -j ACCEPT
iptables -A block -m state --state NEW -i ! $WLAN -j ACCEPT
# Logging is turned off
#iptables -A block -j LOG --log-ip-options
iptables -A block -j DROP
# Jump to that chain from INPUT and FORWARD chains.
iptables -A INPUT -j block
iptables -A FORWARD -j block

We will want this script to be started once the tunnel has come up so it will form part of the /opt/etc/openvpn/openvpn.conf configuration.

The snippet in the openvpn.conf will look like this and the openvpn.up file will contain the above script.

up ./openvpn.up