Quick answer so the question has some closure:
The comment by @user535733 is the best way in my opinion. VPN is disabled at startup and started manually in this system, by systemd disable openvpn.
I have the following added to the vpn-up.sh script which is executed after the VPN starts by systemctl start openvpn:
#!/bin/bash
# Disable ipv6 to prevent leaks
echo 1 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6
# Start services e.g. transmission
service transmission-daemon start
# Heredoc for crontab entry in /etc/cron.d
MINUTE=`date +%M`
tee /etc/cron.d/piaport <<-EOF >/dev/null
# /etc/cron.d/piaport: crontab entries for pia-port script
SHELL=/bin/sh
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
${MINUTE} * * * * root /usr/local/bin/pia-port >> /var/log/piaport.log 2>&1
EOF
The script starts and generates a file piaport in /etc/cron.d which runs a script one hour after its generation, and again every hour afterwards.
The vpn-down.sh script which is run when the VPN service is stopped by systemctl stop openvpn:
#!/bin/sh
# Stop service like Transmission
service transmission-daemon stop
# Prevent DNS leaks
/etc/openvpn/update-resolv-conf
# Reenable ipv6
echo 0 > /proc/sys/net/ipv6/conf/eth0/disable_ipv6
# Remove cronjob / heredoc
rm /etc/cron.d/piaport
For unexpected reboots, the script called by the cronjob checks for the existence of the VPN and deletes the cronjob /etc/cron.d/piaport if it was left over:
part of script:
# Check for tun0
tuncheck=$( { /sbin/ifconfig tun0; } 2>&1 )
tunnotfound="not found"
if [ "${tuncheck/$tunnotfound}" = "$tuncheck" ] ; then
echo "- VPN tunnel appears to be up and connected (Good!)"
else
echo "Error detected! tun0 does not exist."
echo "Please make sure both internet and the VPN is connected!"
echo ""
echo "Then run this script again!"
echo ""
[[ -f /etc/cron.d/piaport ]] && rm -f /etc/cron.d/piaport
exit
In total, the cronjob is only run when necessary, and when the VPN is up.