OpenVPN reconnect shell script

I would like to share a script that I use to make sure that my OpenVPN client connection keeps running in the background. I just could not get it to work with the built in options.

This guide includes installing some tools with apt-get and changing system files and is intended for advanced linux users only. Also this is just my very own approach to connect to VPN since this script avoids any system.d services and might be incompatible with certain configurations (connman, which is used by OSMC, might have problems with resolvconf if using the dnsproxy option as I was told).
My system that works fine with the script is the following:

  • Raspberry Pi 3 with OSMC (2017.03-1)
  • Only one network interface activated (onboard LAN - eth0), but also tested with onboard WiFi (wlan0)
  • OpenVPN runs as a client
  • VPN-Provider is PIA
  • SSH enabled and ports opened for remote access via my script

Also tested it on Raspbian and Debian jessie (x86) in VirtualBox.

Before installing my files you should try if the “keepalive” option in the openvpn configuration works for you. For me it was not reliably reconnecting or restarted the openvpn service too often.


What the script does is simple: it pings 5 manually defined addresses and kills and restarts the OpenVPN process after the last address has failed.
To make that simpler it runs openvpn directly avoiding any additional services.

Also the script allows to open ports bypassing the VPN connection. All (incoming) traffic through these ports uses your real IP address then. (Found here)
This should be necessary if you want to use SSH remotely or host a web server or similar services.
There is an option to enable the port knocking daemon knockd too.
These options can easily be changed through the config file

/etc/default/openvpn-reconnect

All output of the script can be followed through its own log file. I added this just for fun but it is useful to find out how often and why the VPN connection restarts.


Preparation:

To avoid IP/DNS leaks or failure of the script you should follow these steps carefully:

1. Set your IP address, gateway and DNS manually or let your router give you a permanent IP. Write them down for later.
If you want to be most secure change your dns server to 127.0.0.1 or sth. non existent.

These settings can be done in kodi using the osmc addon. OSMC uses the network manager connman - others should also work with the script.
The used network manager must be changed in my config file.

2. If you have more than one interface (eth0 and wlan0) enabled at the same time it may be necessary to change the following for the script/openvpn to work (but better disable the unneeded device):

Make sure that you list the interface intended for Internet/VPN first in /etc/connman.conf:

PreferredTechnologies=wifi,ethernet

Also edit the OpenVPN configuration file and tell openvpn to only listen to one interface:

/etc/openvpn/yourconfig.ovpn:

#nobind
local 192.168.178.201

The next steps require a shell or ssh session (to exit to a shell from Kodi: Power - Leave - hit ESC as soon as you see the OSMC logo - wait till you can login (user: osmc password: osmc) - do so and quickly type: sudo service mediacenter stop):

3. Important: if installed remove any applications that change /etc/resolv.conf or edit the corresponding config files.
The following should work fine if no such applications are installed (just tested on freshly installed OSMC):

Create /etc/dhcp/dhclient-enter-hooks.d/nodnsupdate:

sudo nano /etc/dhcp/dhclient-enter-hooks.d/nodnsupdate

With:

#!/bin/sh
make_resolv_conf() {
     :
}

Make it executable:

sudo chmod +x /etc/dhcp/dhclient-enter-hooks.d/nodnsupdate

4. Install the necessary tools:

sudo apt-get install openvpn resolvconf nano curl wget knockd iptables

If you want to use the knockd daemon edit

/etc/knockd.conf:

[options]
UseSyslog
LogFile = /var/log/knockd.log
#
[openCloseSSH]
sequence = 9000,7000,8000
seq_timeout = 5
start_command = iptables -t mangle -A PREROUTING -s %IP% -p tcp --dport 22 -j MARK --set-mark 2
cmd_timeout = 30
stop_command = iptables -t mangle -A PREROUTING -s %IP% -p tcp  --dport 22 -j MARK --set-mark 0/2
tcpflags = syn

Change the port sequence and open these ports in your router.

5. activate resolvconf

sudo dpkg-reconfigure resolvconf

say yes/ok twice

6. reboot (seems necessary)
Your network manager should be running normally - now check your /etc/resolv.conf

cat /etc/resolv.conf

it must only contain a single line except the comments which is your manually set DNS server.

7. Configure OpenVPN

get the login information from your VPN provider. If you did not set a valid DNS server like suggested above you will need the IP address of the vpn server/country you want to connect to because name resolving is then deactivated with non running VPN. My provider (PIA VPN) offers zip files with examples in many variants:

PIA config examples

I took the ip tcp variant

You can surely use them as templates for your own provider but better visit it’s web site.
Also get the ssl cert files and put everything in /etc/openvpn (no sub folders!).

You will just need to add a few lines to the configuration file so it looks like (udp might need a different port than 443 - possibly 1194):

/etc/openvpn/yourconfig.ovpn:

client 
dev tun
proto tcp
remote IP.IP.IP.IP 443 # change
resolv-retry infinite 
nobind 
persist-key 
persist-tun 
ca /etc/openvpn/ca.crt 
tls-client 
remote-cert-tls server 
auth-user-pass /etc/openvpn/pass.txt
comp-lzo 
verb 1 
reneg-sec 0 
crl-verify /etc/openvpn/crl.pem
management localhost 1337
log-append /var/log/openvpn.log
script-security 2
up /etc/openvpn/update-resolv-conf
down /etc/openvpn/update-resolv-conf

8. create the vpn password file:

sudo nano /etc/openvpn/pass.txt

Fill in like this:

username
password

Installation of the scripts:

1. Create the script files

The main script:

sudo nano /usr/local/bin/openvpn-reconnect.sh
#!/bin/bash
. /etc/default/openvpn-reconnect
echo >> $LOGFILE
echo `date "$DATEFORMAT"` "INFO:    Script Started! Starting tests...">> $LOGFILE
messages () {
       MSG_TESTOK1="NOTE:    Internet is reachable at 1st try. Using interface $IFACE"
       MSG_TESTOK2="NOTE:    Internet is reachable at 2nd try. Using interface $IFACE"
       MSG_TESTOK3="NOTE:    Internet is reachable at 3rd try. Using interface $IFACE"
       MSG_TESTOK4="NOTE:    Internet is reachable at 4th try. Using interface $IFACE"
       MSG_TESTOK5="NOTE:    Internet is reachable at 5th try. Using interface $IFACE"
    MSG_TESTNOTOK1="WARNING: Could not reach IP #1: $TESTADDR1"
    MSG_TESTNOTOK2="WARNING: Could not reach IP #2: $TESTADDR2"
    MSG_TESTNOTOK3="WARNING: Could not reach IP #3: $TESTADDR3"
    MSG_TESTNOTOK4="WARNING: Could not reach IP #4: $TESTADDR4"
    MSG_TESTNOTOK5="ERROR:   Could not reach IP #5: $TESTADDR5"
     MSG_NOTONLINE="NOTE:    Internet not reachable, restarting OpenVPN..."
     MSG_VPNNOTACT="WARNING: OpenVPN Service is not running! Restarting OpenVPN..."
     MSG_DNSNOTACT="WARNING: VPN-DNS-Server is not active! Restarting OpenVPN..."
    MSG_ROUTERSEEN="ERROR:   Router-IP seen in resolv.conf! Clearing resolv.conf for safety."
  MSG_NOROUTEFOUND="ERROR:   Could not get default route for $IFACE, check your internet connection!"
 MSG_NETMANRESTART="WARNING: Restarting $NETWORKMAN..."
    MSG_IPROUTETRY="NOTE:    Trying to recover the routing table for interface $IFACE..."
     MSG_IPROUTEOK="NOTE:    Recreated $IPROUTESHOW with original routing table..."
       MSG_SUCCESS="SUCCESS: All fine! VPN is active."
}
routetest () {
if [ "`cat $IPROUTESHOW 2> /dev/null | grep default | grep $IFACE`" == "" ]; then
	echo `date "$DATEFORMAT"` "$MSG_NETMANRESTART" >> $LOGFILE
	pkill -x openvpn
	service $NETWORKMAN restart
	if [ "$NETWORKMAN" == "connman" ]; then
		service connman-wait-for-network restart
	fi
	echo `date "$DATEFORMAT"` "$MSG_IPROUTETRY" >> $LOGFILE
	ROUTEOK=2
	for ((i=1; i<=10; i++)); do
		ip route show | grep default | grep $ROUTERIP > /dev/null
		if [ "$?" == "0" ]; then
			ROUTEOK=1
			break
		else
			sleep 2
		fi
		if [ "$i" == "10" ]; then
			ROUTEOK=0
			echo `date "$DATEFORMAT"` "$MSG_NOROUTEFOUND" >> $LOGFILE
			return 1
		fi
	done
	if [ "$ROUTEOK" == "1" ]; then
		sleep 5
		ip route show > $IPROUTESHOW
		echo `date "$DATEFORMAT"` "$MSG_IPROUTEOK" >> $LOGFILE
		return 0
	fi
fi
}
onlinetestcmd () {
ping -c1 -W$TESTTIMEOUT $1 > /dev/null 2>&1
if [ $? -eq 0 ]; then
	return 0
else
	return 1
fi
}
#onlinetestcmd () {
#case "$(curl -s --max-time $TESTTIMEOUT -I $1 | sed 's/^[^ ]*  *\([0-9]\).*/\1/; 1q')" in
#	[23])
#		return 0;;
#	*)
#		return 1;;
#esac
#}
onlinetest () {
onlinetestcmd $TESTADDR1
if [ $? -eq 0 ]; then
	! [ "`tail -n1 $LOGFILE | grep "$MSG_SUCCESS"`" ] && \
	! [ "`tail -n1 $LOGFILE | grep "$MSG_VPNNOTACT"`" ] && \
	! [ "`tail -n1 $LOGFILE | grep "Internet is reachable"`" ] && \
	echo `date "$DATEFORMAT"` "$MSG_TESTOK1" >> $LOGFILE
	return 0
else
	echo `date "$DATEFORMAT"` "$MSG_TESTNOTOK1" >> $LOGFILE
	onlinetestcmd $TESTADDR2
	if [ $? -eq 0 ]; then
		! [ "`tail -n1 $LOGFILE | grep "$MSG_SUCCESS"`" ] && \
		! [ "`tail -n1 $LOGFILE | grep "$MSG_VPNNOTACT"`" ] && \
		echo `date "$DATEFORMAT"` "$MSG_TESTOK2" >> $LOGFILE
		return 0
	else
		echo `date "$DATEFORMAT"` "$MSG_TESTNOTOK2" >> $LOGFILE
		onlinetestcmd $TESTADDR3
		if [ $? -eq 0 ]; then
			! [ "`tail -n1 $LOGFILE | grep "$MSG_SUCCESS"`" ] && \
			! [ "`tail -n1 $LOGFILE | grep "$MSG_VPNNOTACT"`" ] && \
			echo `date "$DATEFORMAT"` "$MSG_TESTOK3" >> $LOGFILE
			return 0
		else
			echo `date "$DATEFORMAT"` "$MSG_TESTNOTOK3" >> $LOGFILE
			onlinetestcmd $TESTADDR4
			if [ $? -eq 0 ]; then
				! [ "`tail -n1 $LOGFILE | grep "$MSG_SUCCESS"`" ] && \
				! [ "`tail -n1 $LOGFILE | grep "$MSG_VPNNOTACT"`" ] && \
				echo `date "$DATEFORMAT"` "$MSG_TESTOK4" >> $LOGFILE
				return 0
			else
				echo `date "$DATEFORMAT"` "$MSG_TESTNOTOK4" >> $LOGFILE
				onlinetestcmd $TESTADDR5
				if [ $? -eq 0 ]; then
					! [ "`tail -n1 $LOGFILE | grep "$MSG_SUCCESS"`" ] && \
					! [ "`tail -n1 $LOGFILE | grep "$MSG_VPNNOTACT"`" ] && \
					echo `date "$DATEFORMAT"` "$MSG_TESTOK5" >> $LOGFILE
					return 0
				else
					echo `date "$DATEFORMAT"` "$MSG_TESTNOTOK5" >> $LOGFILE
					! [ "`tail -n1 $LOGFILE | grep "$MSG_NOTONLINE"`" ] && \
					echo `date "$DATEFORMAT"` "$MSG_NOTONLINE" >> $LOGFILE
					pkill -x openvpn
					#echo `date "$DATEFORMAT"` "$MSG_NETMANRESTART" >> $LOGFILE
					#service $NETWORKMAN restart
					sleep 1
					return 1
				fi
			fi
		fi
	fi
fi
}
vpntest () {
if [ "`pgrep -x openvpn`" != "" ]; then
	if [ "`cat $RESOLVCONF | grep $VPNDNSIP`" ]; then
		if ! [ "`cat $RESOLVCONF | grep $ROUTERIP`" ]; then
			! [ "`tail -n1 $LOGFILE | grep "$MSG_SUCCESS"`" ] && \
			echo `date "$DATEFORMAT"` "$MSG_SUCCESS" >> $LOGFILE
			return 0
		else
			echo `date "$DATEFORMAT"` "$MSG_ROUTERSEEN" >> $LOGFILE
			echo "" > $RESOLVCONF
			return 1
		fi
	else
		echo `date "$DATEFORMAT"` "$MSG_DNSNOTACT" >> $LOGFILE
		pkill -x openvpn
		sleep 1
		$CMD
		return 1
	fi
else
	echo `date "$DATEFORMAT"` "$MSG_VPNNOTACT" >> $LOGFILE
	pkill -x openvpn
	sleep 1
	$CMD
	return 1
fi
}
portknocker () {
if [ "$ENABLE_KNOCKD" == "1" ]; then
        if [ "`ps ax | grep knockd | grep $IFACE`" == "" ]; then
                pkill -x knockd
                knockd -d -Dv -i $IFACE >/dev/null 2>&1
        fi
fi
}
main () {
while true; do
	. /etc/default/openvpn-reconnect
	messages
	routetest &&  \
	onlinetest &&  \
	ln -sfn /etc/resolvconf/run/resolv.conf /etc/resolv.conf && \
	vpntest && \
	portknocker
	sleep $DELAY
done
}
main

The Helper script to keep it running:

sudo nano /usr/local/bin/openvpn-reconnect-watchdog.sh
#!/bin/bash
while true; do
        if [ "`ps ax | grep "/bin/bash /usr/local/bin/openvpn-reconnect.sh" | grep -v grep`" == "" ]; then
            openvpn-reconnect.sh > /dev/null 2>&1 &
        fi
        sleep 3
done

Shortcut to start the script:

sudo nano /usr/local/bin/ostart
#!/bin/sh
ostop
sudo openvpn-reconnect-watchdog.sh > /dev/null 2>&1 &

Shortcut to stop the script and openvpn:

sudo nano /usr/local/bin/ostop
#!/bin/sh
. /etc/default/openvpn-reconnect
for i in `pgrep -f "/bin/bash /usr/local/bin/openvpn-reconnect-watchdog.sh"`; do sudo kill $i; done
for i in `pgrep -f "/bin/bash /usr/local/bin/openvpn-reconnect.sh"`; do sudo kill $i; KILLED=1; done && \
[ "$KILLED" ] && echo `date +%Y-%m-%d\ %H:%M:%S` INFO:"    "Script stopped by user. | sudo tee -a $LOGFILE > /dev/null
sudo pkill -x knockd
sudo pkill -x openvpn

The configuration file:

sudo nano /etc/default/openvpn-reconnect
### Configuration file for openvpn-reconnect.sh ###
#
# OpenVPN configuration to be used.
VPNCONFIG=/etc/openvpn/custom.conf
#
# OpenVPN command to run after performing online checks
CMD="openvpn --config $VPNCONFIG --daemon"
#
# The interface that connects to the internet
#IFACE=eth0
IFACE=wlan0
#
# Some user specific IPs
ROUTERIP=192.168.178.1
NORMALDNSIP=127.0.0.1
#NORMALDNSIP=192.168.178.1
VPNDNSIP=209.222.18.222
#
TESTADDR1=5.153.231.4
TESTADDR2=151.101.193.5
TESTADDR3=162.255.119.237
TESTADDR4=8.8.8.8
TESTADDR5=8.8.4.4
#
NETWORKMAN="connman"
#
# Time between tests in seconds.
DELAY=10
#
TESTTIMEOUT=10
#
# If using tools modifying resolv.conf like dnsmasq, set this accordingly
#RESOLVCONF=/var/run/dnsmasq/resolv.conf
RESOLVCONF=/etc/resolv.conf
#
# You can use "owatch" to monitor the logs
LOGFILE=/var/log/openvpn-reconnect.log
#
# Format for the date and time in the logfile
DATEFORMAT="+%Y-%m-%d %H:%M:%S"
#
# Enable port bypassing
ENABLE_BYPASSING=0
#
# Ports to be opened (bypasses the VPN connection):
# All traffic through these ports uses the original route of your interface _before_ OpenVPN was running.
# You will want this for web servers and other services that need a unique public IP address.
#
# Needs modified "update-resolv-conf" in /etc/openvpn
# Needs "vpn-bypass-start" and "vpn-bypass-stop" in /etc/openvpn
#
TCP_PORTS=""
# 
UDP_PORTS=""
# 
# Port knocker daemon installed? Must configure /etc/knockd.conf:
# You will need to set the following in knockd.conf to work with OpenVPN...
# Of course delete the corresponding port in the variable TCP_PORTS if you use port knocking.

# /etc/knockd.conf: (Example for SSH standard port 22)
#
#	start_command = iptables -t mangle -A PREROUTING -s %IP% -p tcp --dport 22 -j MARK --set-mark 2
#	cmd_timeout = 10
#	stop_command	= iptables -t mangle -A PREROUTING -s %IP% -p tcp  --dport 22 -j MARK --set-mark 0/2
#
ENABLE_KNOCKD=0
#
# This is the backup of the original pre-VPN route used for port opening
# Will be created dynamically at boot and on interface name changes
IPROUTESHOW=/tmp/openvpn-reconnect.tmp

The up and down scripts for openvpn:

sudo nano /etc/openvpn/update-resolv-conf
#!/bin/bash
# 
# Parses DHCP options from openvpn to update resolv.conf
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-resolv-conf
# down /etc/openvpn/update-resolv-conf
#
# Used snippets of resolvconf script by Thomas Hood and Chris Hanson.
# Licensed under the GNU GPL.  See /usr/share/common-licenses/GPL. 
# 
# Example envs set from openvpn:
#
#     foreign_option_1='dhcp-option DNS 193.43.27.132'
#     foreign_option_2='dhcp-option DNS 193.43.27.133'
#     foreign_option_3='dhcp-option DOMAIN be.bnc.ch'
#

. /etc/default/openvpn-reconnect

[ -x /sbin/resolvconf ] || exit 0
[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0

split_into_parts()
{
	part1="$1"
	part2="$2"
	part3="$3"
}

case "$script_type" in
  up)
	NMSRVRS=""
	SRCHS=""
	for optionvarname in ${!foreign_option_*} ; do
		option="${!optionvarname}"
		echo "$option"
		split_into_parts $option
		if [ "$part1" = "dhcp-option" ] ; then
			if [ "$part2" = "DNS" ] ; then
				NMSRVRS="${NMSRVRS:+$NMSRVRS }$part3"
			elif [ "$part2" = "DOMAIN" ] ; then
				SRCHS="${SRCHS:+$SRCHS }$part3"
			fi
		fi
	done
	R=""
	[ "$SRCHS" ] && R="search $SRCHS
"
	for NS in $NMSRVRS ; do
        	R="${R}nameserver $NS
"
	done
	echo -n "$R" | /sbin/resolvconf -a "${dev}.openvpn"
        if [ "$ENABLE_BYPASSING" == "1" ] || [ "$ENABLE_KNOCKD" == "1" ]; then
                /etc/openvpn/vpn-bypass-start
        fi
	;;
  down)
	/sbin/resolvconf -d "${dev}.openvpn"
        /etc/openvpn/vpn-bypass-stop
        echo nameserver $NORMALDNSIP > $RESOLVCONF
 	;;
esac
sudo nano /etc/openvpn/vpn-bypass-start
#!/bin/bash

. /etc/default/openvpn-reconnect

if [ "$ENABLE_BYPASSING" == "1" ]; then

[ "`cat $VPNCONFIG | grep tun`" ] && VPNMODE=tun0
[ "`cat $VPNCONFIG | grep tap`" ] && VPNMODE=tap0

export LC_ALL=C

#---SET KERNEL OPTIONS
sysctl -w net.ipv4.conf.$IFACE.rp_filter=0 1>/dev/null
sysctl -w net.ipv4.conf.$VPNMODE.rp_filter=0 1>/dev/null
sysctl -w net.ipv4.conf.all.rp_filter=0 1>/dev/null
sysctl -w net.ipv4.conf.default.rp_filter=0 1>/dev/null
sysctl -w net.ipv4.conf.lo.rp_filter=0 1>/dev/null
sysctl -w net.ipv4.ip_forward=1 1>/dev/null
sysctl -w net.ipv4.conf.all.forwarding=1 1>/dev/null
sysctl -w net.ipv4.conf.default.forwarding=1 1>/dev/null
sysctl -w net.ipv4.conf.$IFACE.forwarding=1 1>/dev/null
sysctl -w net.ipv4.conf.lo.forwarding=1 1>/dev/null
sysctl -w net.ipv4.conf.$VPNMODE.forwarding=1 1>/dev/null
sysctl -w net.ipv4.tcp_fwmark_accept=1 1>/dev/null
#sysctl -w net.ipv6.conf.all.forwarding=1 1>/dev/null
#sysctl -w net.ipv6.conf.default.forwarding=1 1>/dev/null
#sysctl -w net.ipv6.conf.$IFACE.forwarding=1 1>/dev/null
#sysctl -w net.ipv6.conf.lo.forwarding=1 1>/dev/null
#sysctl -w net.ipv6.conf.tun0.forwarding=1 1>/dev/null

#---CLEAR ALL FIREWALL RULES
iptables -F
iptables -t mangle -F
iptables -t nat -F

#ip route flush default dev $IFACE

#---FLSUH EXISTING TABLE 101 + cache
ip route flush table 101
ip route flush cache

#---DEL IF EXISTS AND ADD RULE
ip rule del fwmark 2 table 101 > /dev/null 2>&1
ip rule add fwmark 2 table 101

for i in "`cat $IPROUTESHOW | sed 's/^/ip route add table 101 /'`"; do bash -c "`echo "$i"`"; done

# SETTING MASQUERADE FOR OUTPUT
#iptables --table nat --append POSTROUTING -o $IFACE -j MASQUERADE

sed -i '/101 vpnbypass/d' /etc/iproute2/rt_tables

! [ "`grep "101 vpnbypass" /etc/iproute2/rt_tables`" ] && \
echo "101 vpnbypass" | /usr/bin/tee -a /etc/iproute2/rt_tables >/dev/null

# OPEN PORTS THROUGH TABLE 101
for i in $TCP_PORTS; do iptables -t mangle -A PREROUTING -p tcp  --dport $i  -j MARK --set-mark 2; done
for i in $UDP_PORTS; do iptables -t mangle -A PREROUTING -p udp  --dport $i  -j MARK --set-mark 2; done

if [ "$ENABLE_BYPASSING" == "1" ]; then
	echo Opened ports for bypassing VPN:
	oports
fi

fi
sudo nano /etc/openvpn/vpn-bypass-stop
#!/bin/sh
# ---CLEAR ALL FIREWALL RULES
iptables -F
iptables -t mangle -F
iptables -t nat -F

# ---FLSUH EXISTING TABLE 101 + cache
ip route flush table 101
ip route flush cache

#--- DEL IF EXISTS AND ADD RULE
ip rule del fwmark 2 table 101 > /dev/null 2>&1

Script to show manually opened ports:

sudo nano /usr/local/bin/oports
#!/bin/bash
sudo /sbin/iptables -t mangle -L | \
 grep MARK | grep 0x2 | awk '{ print $6 " " $7 }' | sed s/dpt://

Extra: A “Whats my IP?” shell script:

sudo nano /usr/local/bin/whatsmyip
#!/bin/bash
MYIP=`wget ipinfo.io/ip -qO -`
INFOS=`curl ipinfo.io/$MYIP 2>/dev/null`
echo -e "$INFOS\n"

Extra: A “Whats My IP?” Shortcut as a notification in Kodi:

  • To add it to the OSMC skins home screen: go to the Skin settings and add a custom shortcut with the command:
    System.Exec(“whatsmyip-kodi”)

  • For other skins use a launcher addon like advanced launcher and just write “whatsmyip-kodi” as command

    sudo nano /usr/local/bin/whatsmyip-kodi

#!/bin/bash
whatsmyip > /tmp/whatsmyip.tmp
IP=`cat /tmp/whatsmyip.tmp | grep \"ip\": | awk '{ print $2 }' | sed 's/"//g; s/,//g'`
COUNTRY=`cat /tmp/whatsmyip.tmp | grep \"country\": | awk '{ print $2 }' | sed 's/"//g; s/,//g'`
ORG=`cat /tmp/whatsmyip.tmp | grep \"org\": | awk '{ print $3" "$4" "$5" "$6 }' |  sed 's/"//g; s/,//g'`
SUM="$(echo $IP - $COUNTRY - $ORG)"
echo $IP
echo $COUNTRY
echo $ORG
echo $SUM
xbmc-send -a "Notification(Whats My IP?,$SUM)"
rm /tmp/whatsmyip.tmp

Set permissions:

sudo chmod +x /usr/local/bin/*
sudo chmod +x /usr/etc/openvpn/vpn-bypass-*
sudo chmod +x /usr/etc/openvpn/update-resolv-conf

2. disable the openvpn service!

sudo service openvpn stop
sudo systemctl disable openvpn
sudo update-rc.d openvpn remove

3. edit the configuration

sudo nano /etc/default/openvpn-reconnect

please read carefully. Some things you can just leave like they are.
You must set the IP addresses to fit your settings like done in step 1 and VPN providers 1st or 2nd DNS IP address (google). See the descriptions in the config.
The test servers for ping you can leave or choose your own.

4. test the script

sudo openvpn-reconnect.sh & 

kill later with “ostop”

Look for any errors. Try to solve them by double checking for mistakes in the configurations. Happened to me a lot.
If no error occurs the script itself runs fine. Now take a look at the logs:

cat /var/log/openvpn-reconnect.log

The optimal sequence looks like this:

2017-04-11 14:48:28 INFO:    Script Started! Starting tests...
2017-04-11 14:48:28 WARNING: Restarting connman...
2017-04-11 14:48:31 NOTE:    Trying to recover the routing table for interface wlan0...
2017-04-11 14:48:38 NOTE:    Recreated /tmp/openvpn-reconnect.tmp with original routing table...
2017-04-11 14:48:38 NOTE:    Internet is reachable at 1st try. Using interface wlan0
2017-04-11 14:48:39 WARNING: OpenVPN Service is not running! Restarting OpenVPN...
2017-04-11 14:49:02 SUCCESS: All fine! VPN is active.

Exit with Ctrl+C

5. If it works for you you will want to have the script running at boot time. Originally there was a nice init.d script but I found it much easier to just add a few lines to rc.local where the script gets started by a helper script which keeps it running:

/etc/rc.local:

    sudo openvpn-reconnect-watchdog.sh > /dev/null 2>&1 &
    exit 0
2 Likes

Hi

I’m a little concerned at some of your systctl and cmdline changes.

But this is what I’m not keenly positioned on the most. It’s not recommended for users to randomly wget binaries in to their system. We don’t know where they’ve been sourced from and as the source isn’t provided, getting this into OSMC is not possible.

You are right, I am aware that making changes to the system can always be dangerous for non-advanced users. But this setup is of course intended for people that have some experience with linux and are used to setup networking and tools like openvpn on their own.
I might add a note to the beginning of the post.

The install script by the way does not change anything in the system but only adds a few files to /usr/local/bin
and 3 files to /etc/openvpn for the up and down options of OpenVPN. Everything else must be changed manually as written above and nothing gets executed automatically.

Oh and the sysctl values seem to rly help for some network lags and freezes that I had (especially in ssh). Of course everything is optional.

It adds a few binaries – why don’t you provide the source code and get them to build it? Or use an APT package from the Debian repository. Why do you need to use your own binary? Do you build it statically or handle dependencies for shared objects properly?

You should really make this clear that it works for you but may not work for others. Did you test on more than one network and more than one device?

OK, I added a few lines to the top.
Actually I don’t see any real threat from these settings since everyone should know that it is optional to add them to their system.

There are no binaries but only simple bash scripts. Just extract and open with editor :slight_smile:

This will cause issues if ConnMan’s dnsproxy is on.

Sam

Relisted after author made changes.