Ok, I have modified the /etc/init.d/openvpn script to support both the original Gentoo symlinked style and the multiple .conf file style.
The script is below.
Best,
Steve
#!/sbin/runscript
# OpenVPN start/stop script
# Adapted to Gentoo by James Yonan
# Modified by Steve Fink to support /etc/conf.d/openvpn
# and to support multiple .conf files or Gentoo style symlinks
# USAGE:
# If the file openvpn.conf exists then it is assumed that you are
# using the Gentoo style symlinking way of starting
#
# If the file openvpn.conf does not exist ie you have your files named
# server.conf client.conf or anythingelse.conf then all tunnels are started
# This has been modified so it does the following if no openvpn.conf
# file exists:
#
# - Starts an OpenVPN process for each .conf file in $CONFDIR
#
# - If /etc/openvpn/xxx.start exists for a xxx.conf file then it executes
# it before starting OpenVPN (useful for doing openvpn --mktun...).
#
# - If /etc/openvpn/xxx.stop exists for a xxx.conf file then it executes
# it after stopping OpenVPN (useful for doing openvpn --rmtun...).
#
# OpenRC options
opts="start stop restart"
# Determine which variables to set for Gentoo symlinked or multiple .conf files
if [ ! -e /etc/openvpn/openvpn.conf ]; then
# Set variables for multiple .conf files
# Default location of openvpn
DEF_OPENVPN=/usr/sbin/openvpn
# Default pid directory
DEF_PIDDIR=/var/run/openvpn
# Default conf directory
DEF_CONFDIR=/etc/openvpn
else
# Set variables for Gentoo symlinked
VPNDIR="/etc/openvpn"
VPN="${SVCNAME#*.}"
if [ -n "${VPN}" ] && [ "${SVCNAME}" != "openvpn" ]; then
VPNPID="/var/run/openvpn.${VPN}.pid"
else
VPNPID="/var/run/openvpn.pid"
fi
VPNCONF="${VPNDIR}/${VPN}.conf"
fi
depend() {
need net
use dns
after sshd
}
chkconfd() {
if [ -z $PIDDIR ]; then
PIDDIR=$DEF_PIDDIR
einfo "No pid file directory defined in /etc/conf.d/openvpn using default $PIDDIR."
fi
if [ -z $OPENVPN ]; then
OPENVPN=$DEF_OPENVPN
einfo "No path to OpenVPN defined in /etc/conf.d/openvpn using default $OPENVPN."
fi
if [ -z $CONFDIR ]; then
CONFDIR=$DEF_CONFDIR
einfo "No config file directory defined in /etc/conf.d/openvpn using default $CONFDIR."
fi
}
chktundev() {
if [ ! -e /dev/net/tun ]; then
if ! modprobe tun ; then
eerror "TUN/TAP module unable to load into kernel"
return 1
fi
fi
if [ -h /dev/net/tun ] && [ -c /dev/misc/net/tun ]; then
ebegin "Detected broken /dev/net/tun symlink, fixing..."
rm -f /dev/net/tun
ln -s /dev/misc/net/tun /dev/net/tun
eend $?
fi
}
start() {
# Determine whether it's Gentoo symlinked or multiple .conf files
if [ ! -e /etc/openvpn/openvpn.conf ]; then
# Start multiple .conf files
chkconfd
chktundev || return 1
ebegin "Starting OpenVPN"
# Load the TUN/TAP module
/sbin/modprobe tun >/dev/null 2>&1
if [ ! -d $PIDDIR ]; then
mkdir $PIDDIR
fi
cd $CONFDIR
# Start every .conf file in $CONFDIR and run .start if available
local errors=0
local successes=0
local retstatus=0
for c in `/bin/ls *.conf 2>/dev/null`; do
VPN=${c%%.conf}
ebegin "Starting VPN: $VPN"
if [ -f "$VPN.start" ]; then
. $VPN.start
fi
rm -f $PIDDIR/$VPN.pid
$OPENVPN --daemon OpenVPN-$VPN --writepid $PIDDIR/$VPN.pid --config $CONFDIR/$c --cd $CONFDIR
result=$?
if [ $result = 0 ]; then
successes=1
else
errors=1
FAILED="$FAILED $VPN"
fi
eend $result
done
# Decide status based on errors/successes.
# If at least one tunnel succeeded, we return success.
# If some tunnels succeeded and some failed, we return success but give a warning.
if [ $successes = 1 ]; then
if [ $errors = 1 ]; then
ewarn "The VPN$FAILED failed to start"
fi
else
retstatus=1
if [ $errors = 0 ]; then
ewarn "Note: No OpenVPN configuration files were found in $CONFDIR"
fi
fi
eend $retstatus "Error starting OpenVPN"
else
# Start Gentoo symlinked openvpn.conf
ebegin "Starting ${SVCNAME}"
chktundev || return 1
if [ ! -e "${VPNCONF}" ]; then
eend 1 "${VPNCONF} does not exist"
return 1
fi
local args=""
# If the config file does not specify the cd option, we do
# But if we specify it, we override the config option which we do not want
if ! grep -q "^[ \t]*cd[ \t].*" "${VPNCONF}" ; then
args="${args} --cd ${VPNDIR}"
fi
start-stop-daemon --start --exec /usr/sbin/openvpn --pidfile "${VPNPID}" \
-- --config "${VPNCONF}" --writepid "${VPNPID}" --daemon ${args}
eend $? "Check your logs to see why startup failed"
fi
}
stop() {
# Determine if it's Gentoo symlinked or multiple .conf files
if [ ! -e /etc/openvpn/openvpn.conf ]; then
# Stop multiple .conf files
ebegin "Stopping OpenVPN"
for PIDF in `find $PIDDIR -name '*.pid' 2>/dev/null`; do
if [ -s $PIDF ]; then
VPN=${PIDF%%.pid}
VPN=${VPN##$PIDDIR/}
einfo "Stopping VPN: $VPN ..."
kill `cat $PIDF` >/dev/null 2>&1
if [ -f "${CONFDIR}/${VPN}.stop" ]; then
. ${CONFDIR}/${VPN}.stop
fi
eend $?
rm -rf $PIDF >/dev/null 2>&1
if [ `ls -A "$PIDDIR"|wc -w` = 0 ]; then
rm -rf "$PIDDIR"
fi
fi
done
eend 0
else
# Stop Gentoo symlinked
ebegin "Stopping ${SVCNAME}"
start-stop-daemon --stop --exec /usr/sbin/openvpn --pidfile "${VPNPID}"
eend $?
fi
}
Natanael,
Thanks for the feed back.
I believe I do understand the Gentoo symlink approach. I tested it with this script and multiple VPN symlinks and it works fine, provided that the main openvpn file is openvpn.conf.
I chose to look for the openvpn.conf because the default file is openvpn.conf and acf-openvpn creates openvpn.conf when the system is configured via the web browser. If you have a better method, please advise.
I was thinking we would have to modify the documentation on the wiki to explain the two different methodologies and how to configure both for multiple tunnels. Currently the wiki shows only the method I use which does not work for the original init.d script.
I created a pid directory for openvpn when using the non-symlink method for the purpose of organization of the .pid files and keep /var/run from having potentially dozens of openvpn .pid's strewn about. I was trying to make the symlink method as close to what was currently happening as possible, this can be changed to /var/run/openvpn as well if you like.
I moved it after sshd because I've seen times where OpenVPN failed and stopped anything further from starting. Failing to start before sshd would lock an admin out of sshd, therefore unable to connect and fix the problem. I believe removing before netmount was an oversight.
Best,
Steve
> Ok, I have modified the /etc/init.d/openvpn script to support both > the original Gentoo symlinked style and the multiple .conf file > style. > > The script is below.
Thanks!
Finally I took some time to look at it. I still think the script needs
some work.
> # OpenVPN start/stop script > # Adapted to Gentoo by James Yonan > # Modified by Steve Fink to support /etc/conf.d/openvpn > # and to support multiple .conf files or Gentoo style symlinks
I'm not sure you really understand how the gentoo symlink approach
works. Gentoo style symlinks means you can have multiple .conf files.
ln -s openvpn /etc/init.d/openvpn.server
ln -s openvpn /etc/init.d/openvpn.client
will use server.conf and client.conf in /etc/openvpn dir.
You start the server.conf setup with '/etc/init.d/openvpn.server start',
you start the client.conf with '/etc/init.d/openvpn.client start' and
stop them similarily.
This works prefectly fine without any /etc/openvpn/openvpn.conf
> > # USAGE: > # If the file openvpn.conf exists then it is assumed that you are > # using the Gentoo style symlinking way of starting > # > # If the file openvpn.conf does not exist ie you have your files > named # server.conf client.conf or anythingelse.conf then all tunnels > are started
you could have a gentoo link style system
with no /etc/openvpnc/openvpn.conf file
at all, a /etc/openvpn/anythingelse.conf and a
'openvpn.anythingelse' symlink in /etc/init.d that points to 'openvpn'
Then you 'rc-update add openvpn.anythingelse' and on boot only the
anythingelse.conf will be started.
> # This has been modified so it does the following if no openvpn.conf > # file exists:
Checking for openvpn.conf is bad since you could have a gentoo style
symlink without any openvpnc.conf.
> # > # - Starts an OpenVPN process for each .conf file in $CONFDIR > # > # - If /etc/openvpn/xxx.start exists for a xxx.conf file then it > executes # it before starting OpenVPN (useful for doing openvpn > --mktun...). # > # - If /etc/openvpn/xxx.stop exists for a xxx.conf file then it > executes # it after stopping OpenVPN (useful for doing openvpn > --rmtun...). # > > # OpenRC options > opts="start stop restart" > > # Determine which variables to set for Gentoo symlinked or > multiple .conf files if [ ! -e /etc/openvpn/openvpn.conf ]; then > # Set variables for multiple .conf files > # Default location of openvpn > DEF_OPENVPN=/usr/sbin/openvpn > > # Default pid directory > DEF_PIDDIR=/var/run/openvpn
Why not use same pid directory for both gentoo style all-or-nothing
style?
> # Default conf directory > DEF_CONFDIR=/etc/openvpn > else > # Set variables for Gentoo symlinked > VPNDIR="/etc/openvpn" > VPN="${SVCNAME#*.}" > if [ -n "${VPN}" ] && [ "${SVCNAME}" != "openvpn" ]; then > VPNPID="/var/run/openvpn.${VPN}.pid" > else > VPNPID="/var/run/openvpn.pid" > fi > VPNCONF="${VPNDIR}/${VPN}.conf" > fi > > depend() { > need net > use dns > after sshd
Why does it need to start after sshd?
Why did you remove the "before netmount" (which i assume is needed if
you want mount a network filesystem over openvpn tunnels)
> } > > chkconfd() { > if [ -z $PIDDIR ]; then
I think script will choke here if PIDDIR is really zero. (maybe not but
older versions of ash did so. should be in "": if [ -z "$PIDDIR" ]....
> PIDDIR=$DEF_PIDDIR > einfo "No pid file directory defined in /etc/conf.d/openvpn using > default $PIDDIR." fi
I dont think that info is useful. You normally dont mess with pid file
locations (why would you?).
> if [ -z $OPENVPN ]; then > OPENVPN=$DEF_OPENVPN > einfo "No path to OpenVPN defined in /etc/conf.d/openvpn using > default $OPENVPN." fi > if [ -z $CONFDIR ]; then > CONFDIR=$DEF_CONFDIR > einfo "No config file directory defined in /etc/conf.d/openvpn using > default $CONFDIR." fi
I dont think we need to tell that defaults are beeing used.
> > } > > chktundev() { > if [ ! -e /dev/net/tun ]; then > if ! modprobe tun ; then > eerror "TUN/TAP module unable to load into kernel" > return 1 > fi > fi > if [ -h /dev/net/tun ] && [ -c /dev/misc/net/tun ]; then > ebegin "Detected broken /dev/net/tun symlink, fixing..." > rm -f /dev/net/tun > ln -s /dev/misc/net/tun /dev/net/tun > eend $? > fi > } > > start() { > > # Determine whether it's Gentoo symlinked or multiple .conf files > if [ ! -e /etc/openvpn/openvpn.conf ]; then > # Start multiple .conf files > chkconfd > chktundev || return 1 > ebegin "Starting OpenVPN" > > # Load the TUN/TAP module > /sbin/modprobe tun >/dev/null 2>&1 > > if [ ! -d $PIDDIR ]; then > mkdir $PIDDIR > fi > > cd $CONFDIR > > # Start every .conf file in $CONFDIR and run .start if available > local errors=0 > local successes=0 > local retstatus=0 > for c in `/bin/ls *.conf 2>/dev/null`; do > VPN=${c%%.conf} > ebegin "Starting VPN: $VPN" > if [ -f "$VPN.start" ]; then > . $VPN.start > fi > rm -f $PIDDIR/$VPN.pid > $OPENVPN --daemon OpenVPN-$VPN --writepid $PIDDIR/$VPN.pid --config > $CONFDIR/$c --cd $CONFDIR result=$? > if [ $result = 0 ]; then > successes=1 > else > errors=1 > FAILED="$FAILED $VPN" > fi > eend $result > done > > # Decide status based on errors/successes. > # If at least one tunnel succeeded, we return success. > # If some tunnels succeeded and some failed, we return success but > give a warning. if [ $successes = 1 ]; then > if [ $errors = 1 ]; then > ewarn "The VPN$FAILED failed to start" > fi > else > retstatus=1 > if [ $errors = 0 ]; then > ewarn "Note: No OpenVPN configuration files were found in $CONFDIR" > fi > fi > eend $retstatus "Error starting OpenVPN" > else > # Start Gentoo symlinked openvpn.conf > ebegin "Starting ${SVCNAME}" > > chktundev || return 1 > > if [ ! -e "${VPNCONF}" ]; then > eend 1 "${VPNCONF} does not exist" > return 1 > fi > > local args="" > # If the config file does not specify the cd option, we do > # But if we specify it, we override the config option which we do not > want if ! grep -q "^[ \t]*cd[ \t].*" "${VPNCONF}" ; then > args="${args} --cd ${VPNDIR}" > fi > > start-stop-daemon --start --exec /usr/sbin/openvpn --pidfile > "${VPNPID}" \ -- --config "${VPNCONF}" --writepid "${VPNPID}" > --daemon ${args} eend $? "Check your logs to see why startup failed" > fi > } > > stop() { > # Determine if it's Gentoo symlinked or multiple .conf files > if [ ! -e /etc/openvpn/openvpn.conf ]; then > # Stop multiple .conf files > ebegin "Stopping OpenVPN" > for PIDF in `find $PIDDIR -name '*.pid' 2>/dev/null`; do > if [ -s $PIDF ]; then > VPN=${PIDF%%.pid} > VPN=${VPN##$PIDDIR/} > einfo "Stopping VPN: $VPN ..." > kill `cat $PIDF` >/dev/null 2>&1 > if [ -f "${CONFDIR}/${VPN}.stop" ]; then > . ${CONFDIR}/${VPN}.stop > fi > eend $? > rm -rf $PIDF >/dev/null 2>&1 > if [ `ls -A "$PIDDIR"|wc -w` = 0 ]; then > rm -rf "$PIDDIR" > fi > fi > done > eend 0 > else > # Stop Gentoo symlinked > ebegin "Stopping ${SVCNAME}" > start-stop-daemon --stop --exec /usr/sbin/openvpn --pidfile > "${VPNPID}" eend $? > fi > } > >
On Wed, 22 Dec 2010 13:21:13 -0700 (MST)
Steve Fink <sfink@netvantix.com> wrote:
> Ok, I have modified the /etc/init.d/openvpn script to support both> the original Gentoo symlinked style and the multiple .conf file> style. > > The script is below.
Thanks!
Finally I took some time to look at it. I still think the script needs
some work.
> # OpenVPN start/stop script > # Adapted to Gentoo by James Yonan > # Modified by Steve Fink to support /etc/conf.d/openvpn > # and to support multiple .conf files or Gentoo style symlinks
I'm not sure you really understand how the gentoo symlink approach
works. Gentoo style symlinks means you can have multiple .conf files.
ln -s openvpn /etc/init.d/openvpn.server
ln -s openvpn /etc/init.d/openvpn.client
will use server.conf and client.conf in /etc/openvpn dir.
You start the server.conf setup with '/etc/init.d/openvpn.server start',
you start the client.conf with '/etc/init.d/openvpn.client start' and
stop them similarily.
This works prefectly fine without any /etc/openvpn/openvpn.conf
> > # USAGE: > # If the file openvpn.conf exists then it is assumed that you are > # using the Gentoo style symlinking way of starting > # > # If the file openvpn.conf does not exist ie you have your files> named # server.conf client.conf or anythingelse.conf then all tunnels> are started
you could have a gentoo link style system
with no /etc/openvpnc/openvpn.conf file
at all, a /etc/openvpn/anythingelse.conf and a
'openvpn.anythingelse' symlink in /etc/init.d that points to 'openvpn'
Then you 'rc-update add openvpn.anythingelse' and on boot only the
anythingelse.conf will be started.
> # This has been modified so it does the following if no openvpn.conf > # file exists:
Checking for openvpn.conf is bad since you could have a gentoo style
symlink without any openvpnc.conf.
> # > # - Starts an OpenVPN process for each .conf file in $CONFDIR> # > # - If /etc/openvpn/xxx.start exists for a xxx.conf file then it> executes # it before starting OpenVPN (useful for doing openvpn> --mktun...). # > # - If /etc/openvpn/xxx.stop exists for a xxx.conf file then it> executes # it after stopping OpenVPN (useful for doing openvpn> --rmtun...). # > > # OpenRC options > opts="start stop restart" > > # Determine which variables to set for Gentoo symlinked or> multiple .conf files if [ ! -e /etc/openvpn/openvpn.conf ]; then > # Set variables for multiple .conf files > # Default location of openvpn > DEF_OPENVPN=/usr/sbin/openvpn > > # Default pid directory > DEF_PIDDIR=/var/run/openvpn
Why not use same pid directory for both gentoo style all-or-nothing
style?
> # Default conf directory > DEF_CONFDIR=/etc/openvpn > else > # Set variables for Gentoo symlinked > VPNDIR="/etc/openvpn" > VPN="${SVCNAME#*.}" > if [ -n "${VPN}" ] && [ "${SVCNAME}" != "openvpn" ]; then > VPNPID="/var/run/openvpn.${VPN}.pid" > else > VPNPID="/var/run/openvpn.pid" > fi > VPNCONF="${VPNDIR}/${VPN}.conf" > fi > > depend() { > need net > use dns > after sshd
Why does it need to start after sshd?
Why did you remove the "before netmount" (which i assume is needed if
you want mount a network filesystem over openvpn tunnels)
> } > > chkconfd() { > if [ -z $PIDDIR ]; then
I think script will choke here if PIDDIR is really zero. (maybe not but
older versions of ash did so. should be in "": if [ -z "$PIDDIR" ]....
> PIDDIR=$DEF_PIDDIR > einfo "No pid file directory defined in /etc/conf.d/openvpn using> default $PIDDIR." fi
I dont think that info is useful. You normally dont mess with pid file
locations (why would you?).
> if [ -z $OPENVPN ]; then > OPENVPN=$DEF_OPENVPN > einfo "No path to OpenVPN defined in /etc/conf.d/openvpn using> default $OPENVPN." fi > if [ -z $CONFDIR ]; then > CONFDIR=$DEF_CONFDIR > einfo "No config file directory defined in /etc/conf.d/openvpn using> default $CONFDIR." fi
I dont think we need to tell that defaults are beeing used.
> > } > > chktundev() { > if [ ! -e /dev/net/tun ]; then > if ! modprobe tun ; then > eerror "TUN/TAP module unable to load into kernel" > return 1 > fi > fi > if [ -h /dev/net/tun ] && [ -c /dev/misc/net/tun ]; then > ebegin "Detected broken /dev/net/tun symlink, fixing..." > rm -f /dev/net/tun > ln -s /dev/misc/net/tun /dev/net/tun > eend $? > fi > } > > start() { > > # Determine whether it's Gentoo symlinked or multiple .conf files > if [ ! -e /etc/openvpn/openvpn.conf ]; then > # Start multiple .conf files > chkconfd > chktundev || return 1 > ebegin "Starting OpenVPN" > > # Load the TUN/TAP module > /sbin/modprobe tun >/dev/null 2>&1 > > if [ ! -d $PIDDIR ]; then > mkdir $PIDDIR > fi > > cd $CONFDIR > > # Start every .conf file in $CONFDIR and run .start if available > local errors=0 > local successes=0 > local retstatus=0 > for c in `/bin/ls *.conf 2>/dev/null`; do > VPN=${c%%.conf} > ebegin "Starting VPN: $VPN" > if [ -f "$VPN.start" ]; then > . $VPN.start > fi > rm -f $PIDDIR/$VPN.pid > $OPENVPN --daemon OpenVPN-$VPN --writepid $PIDDIR/$VPN.pid --config> $CONFDIR/$c --cd $CONFDIR result=$? > if [ $result = 0 ]; then > successes=1 > else > errors=1 > FAILED="$FAILED $VPN" > fi > eend $result > done > > # Decide status based on errors/successes. > # If at least one tunnel succeeded, we return success. > # If some tunnels succeeded and some failed, we return success but> give a warning. if [ $successes = 1 ]; then > if [ $errors = 1 ]; then > ewarn "The VPN$FAILED failed to start" > fi > else > retstatus=1 > if [ $errors = 0 ]; then > ewarn "Note: No OpenVPN configuration files were found in $CONFDIR" > fi > fi > eend $retstatus "Error starting OpenVPN" > else > # Start Gentoo symlinked openvpn.conf > ebegin "Starting ${SVCNAME}" > > chktundev || return 1 > > if [ ! -e "${VPNCONF}" ]; then > eend 1 "${VPNCONF} does not exist" > return 1 > fi > > local args="" > # If the config file does not specify the cd option, we do > # But if we specify it, we override the config option which we do not> want if ! grep -q "^[ \t]*cd[ \t].*" "${VPNCONF}" ; then > args="${args} --cd ${VPNDIR}" > fi > > start-stop-daemon --start --exec /usr/sbin/openvpn --pidfile> "${VPNPID}" \ -- --config "${VPNCONF}" --writepid "${VPNPID}"> --daemon ${args} eend $? "Check your logs to see why startup failed" > fi > } > > stop() { > # Determine if it's Gentoo symlinked or multiple .conf files > if [ ! -e /etc/openvpn/openvpn.conf ]; then > # Stop multiple .conf files > ebegin "Stopping OpenVPN" > for PIDF in `find $PIDDIR -name '*.pid' 2>/dev/null`; do > if [ -s $PIDF ]; then > VPN=${PIDF%%.pid} > VPN=${VPN##$PIDDIR/} > einfo "Stopping VPN: $VPN ..." > kill `cat $PIDF` >/dev/null 2>&1 > if [ -f "${CONFDIR}/${VPN}.stop" ]; then > . ${CONFDIR}/${VPN}.stop > fi > eend $? > rm -rf $PIDF >/dev/null 2>&1 > if [ `ls -A "$PIDDIR"|wc -w` = 0 ]; then > rm -rf "$PIDDIR" > fi > fi > done > eend 0 > else > # Stop Gentoo symlinked > ebegin "Stopping ${SVCNAME}" > start-stop-daemon --stop --exec /usr/sbin/openvpn --pidfile> "${VPNPID}" eend $? > fi > } > >
---
Unsubscribe: alpine-devel+unsubscribe@lists.alpinelinux.org
Help: alpine-devel+help@lists.alpinelinux.org
---