Page 1 of 1
Portable OpenVPN for Linux.
Posted: Mon Aug 01, 2011 9:07 am
by Mimiko
Hello all.
From time when I discovered the portability, I've liked the way it's easy to use. So in production I decided to portable even services needed for a corporate LAN. Till now I succeded in make portable of a lot of things and service, even initially they are only installers. All was made on Windows servers. Using this method benefits me a lot. For example, moving services around the different servers. When some windows server become unstable, and the only solution is to reinstall, moving services are a matter of minutes. Running some *.bat files to uninstall drivers and service and copy the whole folder with all the needed files, configs and logs. Backup is also a easy, backing working snapshots with the config and working version of binaries.
For OpenVPN I made a folder where all files and configs reside in one folder under different subfolders. I made a script for installation, that installs tap driver, configure openvpn to run as a service and add some keys in registry, without going thru all normal installation. So is uninstalling, just uninstall tap driver, remove service and registry keys.
But as an expert in windows, all was done in this system. For now I plan to move to linux systems. So I am looking in using same portability in linux. I ask for help in clarifying the method to do the portable version from sources or precompiled binaries, because keeping needing files in different folders and subfolders seems to me a bit harder to maintain in the way I do. In windows its a help that all linked *.dll files are searced in the same folder as main *.exe file, then in path folders. In linux I came to knowledge that lineked files path a precompiled in binaries as absolute path from root. I would like the files to be searched starting relatively in same folder as main executable.
It will be great to make such a portable to work on minimum linux installation which have basic function like networking, routing, firewall. Also, portable application must have a script that will install tap interface, OpenVPN service as deamon.
I plan on make a new ext2 partition that in linux I will mount in something like /services. Every needed service will be in its directory, so OpenVPN will reside in /services/OpenVPN. But this can be changed without affecting the installation process. After installing service from script, the folder's names will not be changed.
Also in OpenVPN folder there will be subfolders (something like in windows):
bin - all executables and linked files;
config - all configurations and sript files;
log - all logs and temporary files like PID files;
doc - all documentation and help files of OpenVPN, used only to manual reading;
driver - all files related to tap virtual device, that will be copied in system folders at installation time;
install - all scripts used only to install or uninstal OpenVPN.
Re: Portable OpenVPN for Linux.
Posted: Mon Aug 01, 2011 10:19 pm
by Bebop
Mimiko wrote:
bin - all executables and linked files;
config - all configurations and sript files;
log - all logs and temporary files like PID files;
doc - all documentation and help files of OpenVPN, used only to manual reading;
driver - all files related to tap virtual device, that will be copied in system folders at installation time;
install - all scripts used only to install or uninstal OpenVPN.
Heya Mimi. Interesting topic. You want all of this stuff to be on one folder, so its portable to another machine? My Linux knowledge about 'best practices' and whatnot is actually quite shallow. I would have thought that binaries can always just be ported to any system, by installing them with "apt-get...." or "yum install....". Wait for an expert such as
JJ to shed some light on this.
Re: Portable OpenVPN for Linux.
Posted: Mon Aug 01, 2011 11:00 pm
by Mimiko
Hi Bebob
yes, all this directories are related to OpenVPN, and I want them all to be under one folder, let say "OpenVPNsrv", which may be changed before service is installed.
I've tryied to move all executables to bin, but when I start openvpn from console, it's says about missing pck*something.so.1 I found this library and copied the files to bin directory of OpenVPN folder, but anyway it doesnot find the file.
Re: Portable OpenVPN for Linux.
Posted: Tue Aug 02, 2011 9:28 am
by maikcat
you can always build openvpn binary as static...
Michael.
Re: Portable OpenVPN for Linux.
Posted: Tue Aug 02, 2011 2:22 pm
by Mimiko
The thing is that I can't install OpenVPN on linux, not build it. I've never done something like this. On windows standart bianaries are easy to portable. Why is not so on linux?
The static - what means this when building OpenVPN?
Re: Portable OpenVPN for Linux.
Posted: Tue Aug 02, 2011 3:16 pm
by dazo
Normally software is built with dynamic bindings in Linux (and most *nix platforms). That means that it will only carry library references to external libraries it needs. This is why you have some specific library dependencies when installing pre-compiled software.
Static builds means that the library OpenVPN depends on is included into the binary, and don't depend on external libraries. However static binaries will always be dependent on the "C library", usually glibc, uclibc, libc or similar. On Linux this is again tightly connected to ld-linux/ld. So you will not escape these two dependencies easily. The reason for this is that the C library is the library which mainly talks to the kernel.
Having that said, there will always be a dependency on the kernel and C library. So kicking out the C library gains you nothing. And the ABI (Application Binary Interface) is pretty stable nowadays, so if you have something built for say Red Hat Enterprise Linux (RHEL)/CentOS/ScientificLinux 5, it will most likely work on RHEL6 and newer Fedora, Debian, Ubuntu versions too ... but of course, spanning more than 7-10 years of distribution versions is probably very much challenging in this aspect.
I don't think OpenVPN supports static building "out-of-the-box" currently ... but that shouldn't be too difficult to change, if you're keen on looking into this. You just need to have the static lzo2 and openssl libraries available, and the pkcs11 library if you want this support too.
The only drawback static building has, is that you need to rebuild it each time the needed libraries are updated due to security and/or bug fixes.
Re: Portable OpenVPN for Linux.
Posted: Tue Aug 02, 2011 3:37 pm
by Mimiko
Thank for a good explanation, dazo. Even I don't understand a lot, the main idea I got. Of course, I don't intent to run OpenVPN and libraies compiled now on linux systems build at ten years in future. From time to time it can be renewed. I see it from windows perspective where I have a compiled snapshot. Would it be great having such snapshots binaries procompiled for linuxes?
Oke, let lzo2, openssl and pcks11 libraries are not compiled in OpenVPN binarie. But how to make OpenVPN to lock for this libraries in same directory as main OpenVPn binary? Like in windows, where *.dll files reside in same folder as openvpn.exe. In this case, if an update to one the library is easy to deploy by simply copying *.so files into the directory replacing old ones.
Re: Portable OpenVPN for Linux.
Posted: Wed Aug 03, 2011 10:51 am
by janjust
I'd recommend to recompile openvpn statically, so that the external libraries are not needed.
It is possible to use external libraries by setting the environment variable LD_LIBRARY_PATH to point to the right directory. In your case this would be
Code: Select all
export LD_LIBRARY_PATH=/services/bin
(I'd use /services/lib).
As dazo pointed out, it is quite tricky to build a single openvpn executable for "all" linux platforms. Linux runs on
- * 32bit Intel/AMD systems
* 64bit Intel/AMD systems
* ARM
* PowerPC
* SPARC
also notice that different linux distros using different mechanisms for setting up network connections : some use 'iproute2' , others use '/sbin/ip' etc.
Re: Portable OpenVPN for Linux.
Posted: Wed Aug 03, 2011 12:24 pm
by Mimiko
Yes, I see that it must be recompiled, because default compiled binaries are set to search libs in specified folders.
Could it be to use:
?
Because after compiled, folder names can be whatever I want. Let OpenVPN search lib files in the same folder. Also can be used relative paths, like ./../lib. Not absolute.
I'm not intending to use same compiled binaries on different platforms. When needed to move to another server - it will be same platform. I just want that files concerning OpenVPN are not spread on different system folders, except of those needed for making as deamon and make tap interface.
As for iproute2 - there is an option to give in config file indicating what command to use for routing.
Now is the problem on getting hand on how to compile. Janjust, could you write a guide on compiling OpenVPN from scratch, indicating what is needed, which parameters are important to set, and how to write a script that will install tap driver and create the deamon.
Re: Portable OpenVPN for Linux.
Posted: Wed Aug 03, 2011 12:47 pm
by dazo
Yes, I see that it must be recompiled, because default compiled binaries are set to search libs in specified folders.
Could it be to use:
Code:
export LD_LIBRARY_PATH=./
The lib search path is not compiled into the binary. It's based upon what /etc/ld.so.conf is set up to use. The cache which libdl uses is update by running the ldconfig program.
Setting LD_LIBRARY_PATH=. should work.
As for iproute2 - there is an option to give in config file indicating what command to use for routing.
That's a compile-time option. So if compiled with iproute2, it depends on /sbin/ip. If not compiled with this, it depends on /sbin/ifconfig and /sbin/route.
Now is the problem on getting hand on how to compile. Janjust, could you write a guide on compiling OpenVPN from scratch, indicating what is needed, which parameters are important to set, and how to write a script that will install tap driver and create the deamon.
On Linux this is pretty much straight forward. Install the openssl, liblzo2 and pkcs11-helper development packages and you have what you need to compile OpenVPN. You don't need to care for the tun/tap driver on Linux, as that's already available in the OS. To compile the tun.ko module, you anyway need to do this from the kernel source code and not OpenVPN. On most distros tun.ko is loaded automatically when it is needed.
Re: Portable OpenVPN for Linux.
Posted: Wed Aug 03, 2011 4:17 pm
by Mimiko
Thank you dazo for some explanation, 'cause I didn't knew where to use export LD_LIBRARY_PATH.
As for iproute2 - there is an option to give in config file indicating what command to use for routing.
That's a compile-time option. So if compiled with iproute2, it depends on /sbin/ip. If not compiled with this, it depends on /sbin/ifconfig and /sbin/route.
How about option --iproute?
For now I made something to work and its connecting to the OpenVPN server. For this I got my fingers on coLinux - a simple low-level emulator for linux machines on windows. And attached preinstalled minimal Debian linux, dowloaded from same site as coLinux.
After powering up, I didn't get any flavors and utilities. Just command line. So, for Debian, I've vizited the packages pages of Debian, and downloaded openvpn_2.2-RC2-debian0_i386, and needed libs. In windows I extraxted data.tar and copyied on my local http server, from where I wget on linux. Untarred and moved all files from usr/include, usr/lib, usr/sbin to /openvpn/bin. Then trying to start openvpn, there were needed two libs: libpkcs11-helper.so.1, libpkcs11-helper.so.1.0.0, liblzo2.so.2, liblzo2.so.2.0.0 (these four files I coppied to /openvpn/bin).
Then I coppied config files from working client on windows to /openvpn/config.
I created a startup script with this:
Code: Select all
#!/bin/bash
export LD_LIBRARY_PATH=$PWD/bin
bin/openvpn --config config/client.ovpn
Which I saved in /openvpn.
And client.ovpn has:
Code: Select all
client
dev tun
proto udp
remote x
nobind
;user nobody
;group nobody
persist-key
persist-tun
ca config/ca.crt
cert config/mimiko.crt
key config/mimiko.key
ns-cert-type server
comp-lzo
;log openvpn.log
log-append log/openvpn.log
verb 2
keepalive 10 120
route-delay 20 20
First time I started the openvpn normally - tap driver was installed and configured. After that, It's starting and stays until I break it. In log except some warning related to linux, shows everything normal. I couldn ping anything, because command line was not available when starting openvpn.
Now, to make some tweaking. On windows in registry are placed the directory of config files. When openvpn service is started, it cds to that directory and starts all *.ovpn files creating different listeners. Well, when finding how to indicate lib files directiry, how to indicate where to find additional files of openvpn from bin directory, like openvpn-down-root.so, openvpn-plugin.h, openvpn-auth-pam.so. Or this file is automaticcaly used from directory where main openvpn binary resides? As for config files, I saw in init.d that script itself starts a deamon for every config, insteed letting openvpn manage this.
Also would like to use in config file direcotory variables. For example:
conf_dir=config, log_dir=log
Code: Select all
ca conf_dir/ca.crt
cert conf_dir/mimiko.crt
key conf_dir/mimiko.key
ns-cert-type server
comp-lzo
;log openvpn.log
log-append log_dir/openvpn.log
So this variables could be set in start up script before and used by openvpn when reading config file. Or indicating as a command line.
Also, OpenVPN didn't asked for ssl library, why?
First time when openvpn is started I saw a tap install and configure. How to unconfigure and uninstall everything that openvpn did. So I would see that thig again.
Re: Portable OpenVPN for Linux.
Posted: Wed Aug 03, 2011 4:49 pm
by Mimiko
Found something interesting. Removing log-append I see the log outpuy in real-time, but remote openvpn is down for now, so local openvpn client stuck on that UDPv4 link remote: a.b.c.d:1194. On windows after some time there is logged time out and are trying to connect again. Is this normal in linux to stuck here when remote server is down?
Re: Portable OpenVPN for Linux.
Posted: Wed Aug 03, 2011 5:58 pm
by Mimiko
Previous. Because a limited screen buffer, I can see only last 25 lines of log. It seems that on this build the default time out is 60 sec insteed of 5 sec as describet in help. On windows its 5 sec.
Also found some interesting to use with openvpn as daemon:
--cd dir
Change directory to dir prior to reading any files such as configuration files, key files, scripts, etc. dir should be an absolute path, with a leading "/", and without any references to the current directory such as "." or "..".
This option is useful when you are running OpenVPN in --daemon mode, and you want to consolidate all of your OpenVPN control files in one location.
I undestand that this option cannot be used from within config file itself, like --chroot also. First it cds to that directory and after that the config file are read. Is it true?
How to identify options that are not usefull in config file and works only as command line?
Re: Portable OpenVPN for Linux.
Posted: Mon Aug 15, 2011 8:01 pm
by Mimiko
Nyan.
After spending some days, I made it working. And also made samba and sshd portable. The Debian-lenny build for coLinux is very, very limited with preinstalled libs. Will see from the dirs bellow. What I did with OpenVPN. First, the directory content:
.:
bin
config
doc
driver
easy-rsa
install_files
lib
log
./bin:
openvpn
openvpn-auth-pam.so
openvpn-down-root.so
openvpn-plugin.h
./config:
ccd
openvpn.default
openvpn.init.d
server.ovpn
./doc:
openvpn.8.gz
....
./doc/examples/easy-rsa/1.0:
README.gz
build-ca
build-dh
build-inter
build-key
build-key-pass
build-key-pkcs12
build-key-server
build-req
build-req-pass
clean-all
list-crl
make-crl
openssl.cnf
revoke-crt
revoke-full
sign-req
vars
./doc/examples/easy-rsa/2.0:
Makefile
README.gz
build-ca
build-dh
build-inter
build-key
build-key-pass
build-key-pkcs12
build-key-server
build-req
build-req-pass
clean-all
inherit-inter
list-crl
openssl-0.9.6.cnf.gz
openssl.cnf
pkitool
revoke-full
sign-req
vars
whichopensslcnf
./driver:
./easy-rsa:
verify-cn
./install_files:
openvpn_2.2-RC2-debian0_i386.deb
./lib:
liblzo2.so.2
liblzo2.so.2.0.0
libpkcs11-helper.so.1
libpkcs11-helper.so.1.0.0
./log:
ipp.server.txt
openvpn.server.log
openvpn.server.pid
openvpn.server.status.log
OpenVPN specific configs, like "ovpn", keys, ccd are not important. Except for server.ovpn:
Code: Select all
ifconfig-pool-persist log/ipp.server.txt
;user nobody
;group nobody
status log/openvpn.server.status.log
log-append log/openvpn.server.log
The user and group "nobody" does not exists on this Debian build, so using them gives error.
The content of openvpn.default is:
Code: Select all
# This is the configuration file for /etc/init.d/openvpn
#
# Start only these VPNs automatically via init script.
# Allowed values are "all", "none" or space separated list of
# names of the VPNs. If empty, "all" is assumed.
#
#AUTOSTART="all"
#AUTOSTART="none"
#AUTOSTART="home office"
#
# Refresh interval (in seconds) of default status files
# located in /var/run/openvpn.$NAME.status
# Defaults to 10, 0 disables status file generation
#
#STATUSREFRESH=10
#STATUSREFRESH=0
# Optional arguments to openvpn's command line
OPTARGS=""
Will use to give command line options to OpenVPN.
The content of openvpn.init.d is:
Code: Select all
#!/bin/sh -e
### BEGIN INIT INFO
# Provides: vpn
# Required-Start: $network $local_fs
# Required-Stop: $network $local_fs
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Openvpn VPN service
### END INIT INFO
# Original version by Robert Leslie
# <rob@mars.org>, edited by iwj and cs
# Modified for openvpn by Alberto Gonzalez Iniesta <agi@inittab.org>
# Modified for restarting / starting / stopping single tunnels by Richard Mueller <mueller@teamix.net>
cd $(dirname $(readlink -f $0))
cd ..
OPENVPN_DIR=$PWD
BIN_DIR=bin
CONFIG_DIR=config
CONFIG_EXT=ovpn
LOG_DIR=log
LIB_DIR=lib
export LD_LIBRARY_PATH=$OPENVPN_DIR/$BIN_DIR:$OPENVPN_DIR/$LIB_DIR
. /lib/lsb/init-functions
test $DEBIAN_SCRIPT_DEBUG && set -v -x
DAEMON=$OPENVPN_DIR/$BIN_DIR/openvpn
DESC="virtual private network daemon"
# CONFIG_DIR=/etc/openvpn
test -x $DAEMON || exit 0
test -d $OPENVPN_DIR/$CONFIG_DIR || exit 0
# Source defaults file; edit that file to configure this script.
AUTOSTART="all"
STATUSREFRESH=10
if test -e $OPENVPN_DIR/$CONFIG_DIR/openvpn.default ; then
. $OPENVPN_DIR/$CONFIG_DIR/openvpn.default
fi
start_vpn () {
if grep -q '^[ ]*daemon' $OPENVPN_DIR/$CONFIG_DIR/$NAME.$CONFIG_EXT ; then
# daemon already given in config file
DAEMONARG=
else
# need to daemonize
DAEMONARG="--daemon ovpn-$NAME"
fi
if grep -q '^[ ]*status ' $CONFIG_DIR/$NAME.$CONFIG_EXT ; then
# status file already given in config file
STATUSARG=""
elif test $STATUSREFRESH -eq 0 ; then
# default status file disabled in /etc/default/openvpn
STATUSARG=""
else
# prepare default status file
STATUSARG="--status $OPENVPN_DIR/$LOG_DIR/openvpn.$NAME.status $STATUSREFRESH"
fi
log_progress_msg "$NAME"
STATUS=0
# Check to see if it's already started...
if test -e $OPENVPN_DIR/$LOG_DIR/openvpn.$NAME.pid ; then
log_failure_msg "Already running (PID file exists)"
STATUS=0
else
$DAEMON $OPTARGS --writepid $OPENVPN_DIR/$LOG_DIR/openvpn.$NAME.pid \
$DAEMONARG $STATUSARG --cd $OPENVPN_DIR \
--config $CONFIG_DIR/$NAME.$CONFIG_EXT || STATUS=1
fi
}
stop_vpn () {
kill `cat $PIDFILE` || true
rm -f $PIDFILE
rm -f $OPENVPN_DIR/$LOG_DIR/openvpn.$NAME.status 2> /dev/null
}
case "$1" in
start)
log_daemon_msg "Starting $DESC"
# autostart VPNs
if test -z "$2" ; then
# check if automatic startup is disabled by AUTOSTART=none
if test "x$AUTOSTART" = "xnone" -o -z "$AUTOSTART" ; then
log_warning_msg " Autostart disabled."
exit 0
fi
if test -z "$AUTOSTART" -o "x$AUTOSTART" = "xall" ; then
# all VPNs shall be started automatically
for CONFIG in `cd $OPENVPN_DIR/$CONFIG_DIR; ls *.$CONFIG_EXT 2> /dev/null`; do
NAME=${CONFIG%%.$CONFIG_EXT}
start_vpn
done
else
# start only specified VPNs
for NAME in $AUTOSTART ; do
if test -e $OPENVPN_DIR/$CONFIG_DIR/$NAME.$CONFIG_EXT ; then
start_vpn
else
log_failure_msg "No such VPN: $NAME"
STATUS=1
fi
done
fi
#start VPNs from command line
else
while shift ; do
[ -z "$1" ] && break
if test -e $OPENVPN_DIR/$CONFIG_DIR/$1.$CONFIG_EXT ; then
NAME=$1
start_vpn
else
log_failure_msg " No such VPN: $1"
STATUS=1
fi
done
fi
log_end_msg ${STATUS:-0}
;;
stop)
log_daemon_msg "Stopping $DESC"
if test -z "$2" ; then
for PIDFILE in `ls $OPENVPN_DIR/$LOG_DIR/openvpn.*.pid 2> /dev/null`; do
NAME=`echo $PIDFILE | cut -c18-`
NAME=${NAME%%.pid}
stop_vpn
log_progress_msg "$NAME"
done
else
while shift ; do
[ -z "$1" ] && break
if test -e $OPENVPN_DIR/$LOG_DIR/openvpn.$1.pid ; then
PIDFILE=`ls $OPENVPN_DIR/$LOG_DIR/openvpn.$1.pid 2> /dev/null`
NAME=`echo $PIDFILE | cut -c18-`
NAME=${NAME%%.pid}
stop_vpn
log_progress_msg "$NAME"
else
log_failure_msg " (failure: No such VPN is running: $1)"
fi
done
fi
log_end_msg 0
;;
# Only 'reload' running VPNs. New ones will only start with 'start' or 'restart'.
reload|force-reload)
log_daemon_msg "Reloading $DESC"
for PIDFILE in `ls $OPENVPN_DIR/$LOG_DIR/openvpn.*.pid 2> /dev/null`; do
NAME=`echo $PIDFILE | cut -c18-`
NAME=${NAME%%.pid}
# If openvpn if running under a different user than root we'll need to restart
if egrep '^[[:blank:]]*user[[:blank:]]' $OPENVPN_DIR/$CONFIG_DIR/$NAME.conf > /dev/null 2>&1 ; then
stop_vpn
sleep 1
start_vpn
log_progress_msg "(restarted)"
else
kill -HUP `cat $PIDFILE` || true
log_progress_msg "$NAME"
fi
done
log_end_msg 0
;;
# Only 'soft-restart' running VPNs. New ones will only start with 'start' or 'restart'.
soft-restart)
log_daemon_msg "$DESC sending SIGUSR1"
for PIDFILE in `ls $OPENVPN_DIR/$LOG_DIR/openvpn.*.pid 2> /dev/null`; do
NAME=`echo $PIDFILE | cut -c18-`
NAME=${NAME%%.pid}
kill -USR1 `cat $PIDFILE` || true
log_progress_msg "$NAME"
done
log_end_msg 0
;;
restart)
shift
$0 stop ${@}
sleep 1
$0 start ${@}
;;
cond-restart)
log_daemon_msg "Restarting $DESC."
for PIDFILE in `ls $OPENVPN_DIR/$LOG_DIR/openvpn.*.pid 2> /dev/null`; do
NAME=`echo $PIDFILE | cut -c18-`
NAME=${NAME%%.pid}
stop_vpn
sleep 1
start_vpn
done
log_end_msg 0
;;
*)
echo "Usage: $0 {start|stop|reload|restart|force-reload|cond-restart}" >&2
exit 1
;;
esac
exit 0
# vim:set ai sts=2 sw=2 tw=0:
And in order to make it run form init.d, I did a symlink:
Code: Select all
ln -s /services/openvpn/config/openvon.init.d /etc/init.d/openvpn
So for other services - openvpn start/stop script is in right place.
For auto start on system boot I've get the command from cotrol/postinst file of deb package:
Code: Select all
update-rc.d openvpn defaults 16 80
The things I have to do, is to automate symlink creation, tun device creation, update-rc.d running - for install, and symlink removing, tun device removing and other - when uninstall. There is other tasks in installing time to do automatically, like network/in-up.d, network/if-down.d - file modifying or so.
Any feedback and improvments to bash scripts are welcome.