openvpn script options
I have asked me several times which scripts can I call in OpenVPN. The documentation is very detailed but it’s big and not intend to be a step by step tutorial, AFAIS (=As far as I see). I write this blog post for me and all others which have the same issue.
Introduction
OpenVPN is a great tool for VPN’s from my point of view. It’s open source, it’s mature, it’s flexible and just great 😍 .
I use it for several solutions and therefore the scripting options are quiet important for me. I read the manual Openvpn24ManPage serveral times and always see some new possibilies like start/stop some process when a route/interface goes up or down.
OpenVPN Script hooks
I will describe here how you can run a NFS mount and unmount when a VPN Connection will be created and more important when the connections goes down for reconnect.
There are several sections in the Openvpn24ManPage which are important for scripts.
- Script Order of Execution
- Environmental Variables
config | context | script_type | Info |
---|---|---|---|
--up cmd |
init | up | this script will be called when the tunnel will be created |
--up-restart |
restart | up | this script will be called when the tunnel will be recreated |
--route-pre-down cmd |
init | route-pre-down | this script will be called when routes are removed |
--down cmd |
init | down | this script will be called when the tunnel goes down |
--up-restart |
restart | down | this script will be called when the tunnel goes down and up |
--route-up cmd |
not defined | route-up | this script will be called when the route is created |
--ipchange cmd |
not defined | ipchange | see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage and search for ipchange |
--learn-address cmd |
not defined | learn-address | see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage and search for learn-address |
--client-connect cmd |
not defined | client-connect | see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage and search for client-connect |
--client-disconnect cmd |
not defined | client-disconnect | see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage and search for client-disconnect |
--tls-verify cmd |
not defined | tls-verify | see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage and search for tls-verify |
--auth-user-pass-verify cmd method |
not defined | auth-user-pass-verify | see https://community.openvpn.net/openvpn/wiki/Openvpn24ManPage and search for auth-user-pass-verify |
With all this hooks I was not able to mount the NFS Share at OpenVPN startup time.
Setup
First of all you will need to create a working openvpn setup. The setup depends on your Plattform and use case so please search for the right solution in the internet Search startpage.
check and mount script
After a successful VPN connection can you run the following script to mount the NFS share
#!/usr/bin/env bash
OPENVPN_ROOT=/etc/openvpn
SCRIPT_ROOT="${OPENVPN_ROOT}/scripts"
if [[ ! -s "${SCRIPT_ROOT}/vpn2server.txt" ]]; then
echo "Can't read config file"
exit 1
fi
CONFIG="${SCRIPT_ROOT}/vpn2server.txt"
MNT_EXEC=/bin/mount
# This doesen't work as expected
MNT_ARGS=" -v -t nfs -o proto=tcp,noatime,nodev,noexec,hard"
UMOUNT_EXEC="/bin/umount"
# This doesen't work as expected
UMOUNT_ARGS=" -f "
SYSTEMCTL_EXEC="/bin/systemctl"
LOGGER_EXEC="/usr/bin/logger"
EGREP_EXEC="/bin/egrep"
SLEEP_EXEC="/bin/sleep"
function log {
${LOGGER_EXEC} "check_mount $(date "+%Y-%m-%d %H:%M:%S") $1"
}
if [[ ${DEBUG} == "true" ]]; then
log "$0 start"
fi
function mymount {
log "Mount ${1}":"${2} to ${3}"
${MNT_EXEC} -v -t nfs -o proto=tcp,noatime,nodev,noexec,hard,clientaddr=${1},addr=${1} ${1}":"${2} ${3}
}
function myumount {
log "Umount ${1}"
${UMOUNT_EXEC} -f ${1}
}
for i in $(< "${SCRIPT_ROOT}/vpn2server.txt" ); do
set -- ${i}
# change here the delimiter for the config file
IFS=_ ; declare -a MYLINE=($*)
SIP=$(awk -F"," '/^10.*'${MYLINE[0]}'/{print $1}' < ${OPENVPN_ROOT}/openvpn-status.log)
echo "test"|curl -sS --max-time 3 telnet://${SIP}:2049
if [[ $? -eq 0 ]] ; then
if [[ ${DEBUG} == "true" ]]; then
log "Server Reachable"
fi
${MNT_EXEC} | ${EGREP_EXEC} -q ${SIP}
if [[ $? -eq 0 ]] ; then
if [[ ${DEBUG} == "true" ]]; then
log "NFS Mounted"
fi
break 5
else
mymount ${SIP} ${MYLINE[1]} ${MYLINE[2]}
break 5
fi
else
myumount ${MYLINE[2]}
log "Stop openvpn@${MYLINE[3]}.service"
${SYSTEMCTL_EXEC} stop openvpn@${MYLINE[3]}.service
${SLEEP_EXEC} 5
log "Start openvpn@${MYLINE[3]}.service"
${SYSTEMCTL_EXEC} start openvpn@${MYLINE[3]}.service
counter=0
# 120 s / 4 s = 30 iterations
while [[ ${counter} -lt 30 ]] ; do
echo "test"|curl -sS --max-time 3 telnet://${SIP}:2049
if [[ $? -eq 0 ]] ; then
if [[ ${DEBUG} == "true" ]]; then
log "Server Reachable after restart"
fi
mymount ${SIP} ${MYLINE[1]} ${MYLINE[2]}
break 5
else
${SLEEP_EXEC} 4
(( counter++ ))
fi
done
exit 0
fi
done
if [[ ${DEBUG} == "true" ]]; then
log "$0 stop"
fi
exit 0
The configuration file looks like this
client-server002_/webroot/nfs-export_/mnt/nfsdata10_openvpn-config
This line have al neccessary information for the script to check and mount the NFS share.
The delimiter for the fields is _
client name | remote exported fs | local mountpoint | openvpn configuration |
---|---|---|---|
client-server002 | /webroot/nfs-export | /mnt/nfsdata10 | openvpn-config |
Why do I need a extra script
The main reason why you can’t mount the NFS share at OpenVPN start up is that the routing information will not be available after a successful VPN connection was created.
ovpn-openvpn[19858]: xxx:33299 [client-server002] Peer Connection Initiated with [AF_INET]xxx:33299
ovpn-openvpn[19858]: client-server002/xxx:33299 MULTI_sva: pool returned IPv4=10.9.0.2, IPv6=(Not enabled)
root[20642]: openvpn-script 2018-02-11 15:01:49 /etc/openvpn/scripts/openvpn-start-stop.sh start
root[20647]: openvpn-script 2018-02-11 15:01:49 ENV: PWD=/etc/openvpn
SHLVL=1
X509_0_C=XX
X509_0_CN=client-server002
X509_0_L=xxx
X509_0_O=xxx
X509_0_OU=xxx
X509_0_ST=X
X509_0_emailAddress=xxx
X509_0_name=xxx
X509_1_C=XX
X509_1_CN=xxx
X509_1_L=xxx
X509_1_O=xxx
X509_1_OU=
X509_1_ST=X
X509_1_emailAddress=xxx
X509_1_name=xxx
_=/usr/bin/env
common_name=client-server002
config=/etc/openvpn/openvpn-xxx.conf
daemon=1
daemon_log_redirect=0
daemon_pid=19858
daemon_start_time=1518357704
dev=tun0
dev_type=tun
ifconfig_broadcast=10.9.0.255
ifconfig_local=10.9.0.1
ifconfig_netmask=255.255.255.0
ifconfig_pool_netmask=255.255.255.0
ifconfig_pool_remote_ip=10.9.0.2
link_mtu=1542
local_port_1=1194
proto_1=udp
redirect_gateway=0
remote_port_1=1194
script_context=init
script_type=client-connect
time_ascii=Sun Feb 11 15:01:49 2018
time_unix=1518357709
tls_digest_0=2c:fb:48:46:e1:3e:f7:db:72:a4:c8:d2:d3:22:2
root[20650]: openvpn-script 2018-02-11 15:01:49 ARGS: /tmp/openvpn_cc_c20c1e44fa27703683ed6f589dc9727f.tmp
root[20846]: openvpn-script 2018-02-11 15:01:51 Mount 10.9.0.2:/webroot/nfs-export
root[20848]: openvpn-script 2018-02-11 15:01:51 /bin/mount -v -t nfs -o proto=tcp,noatime,nodev,noexec,hard,clientaddr=10.9.0.2,addr=10.9.0.2 10.9.0.2:/webroot/nfs-export /mnt/localdir
root[20850]: openvpn-script 2018-02-11 15:01:51 /etc/openvpn/scripts/openvpn-start-stop.sh stop
ovpn-openvpn[19858]: client-server002/xxx:33299 OPTIONS IMPORT: reading client specific options from: /tmp/openvpn_cc_c20c1e44fa27703683ed6f589dc9727f.tmp
ovpn-openvpn[19858]: client-server002/xxx:33299 MULTI: Learn: 10.9.0.2 -> client-server002/xxx:33299
ovpn-openvpn[19858]: client-server002/xxx:33299 MULTI: primary virtual IP for client-server002/xxx:33299: 10.9.0.2
ovpn-openvpn[19858]: client-server002/xxx:33299 PUSH: Received control message: 'PUSH_REQUEST'
ovpn-openvpn[19858]: client-server002/xxx:33299 send_push_reply(): safe_cap=940