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.
So how do you go about recompiling this package?
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 http://svn.openvpn.net/ for the latest SVN location.
ipkg install svn mkdir source cd source svn co http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn
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. Configuration: -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 [/usr/local] --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX [PREFIX] 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 <openvpn-users@lists.sourceforge.net>.
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 <info@openvpn.net> #
OpenVPN Client configuration
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.
#!/bin/sh # # 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 fi mknod /dev/net/tun c 10 200 fi # Make sure the tunnel driver is loaded if ( !(lsmod | grep -q "^tun") ); then insmod /opt/lib/modules/tun.o fi # 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 fi # 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 http://openvpn.net/howto.html
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.
#!/bin/sh 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 WLAN=$1 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 # (-j MASQUERADE) 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