-
-
Save rduplain/d0fb0ecaf444eb5b64cef06ec6a0dd16 to your computer and use it in GitHub Desktop.
#!/bin/sh | |
# PROVIDE: vpn | |
# REQUIRE: LOGIN | |
# KEYWORD: shutdown | |
# | |
# vpn: connect to VPN, start another service once VPN is connected. | |
# | |
# Uses OpenVPN and assumes the configuration does not need any authentication | |
# beyond the given .conf file. Consider an approach using `expect` if needed: | |
# | |
# github.com/amussey/FreeNAS-Transmission-OpenVPN/blob/master/run.sh.template | |
# | |
# Install as an executable at /usr/local/etc/rc.d/vpn, install OpenVPN .conf | |
# at the path specified by openvpn_conf below, and install packages with: | |
# | |
# pkg install -y openvpn | |
# | |
# Add the following configuration to /etc/rc.conf.local or /etc/rc.conf | |
# to enable this service: | |
# | |
# vpn_enable (bool): Set to NO by default; enable with YES. | |
# vpn_service (string): Set to service to start/stop with VPN. | |
# | |
# For the service specified in vpn_service, set its _enable to NO. | |
# | |
# When using vpn up/down precmd/postcmd, be sure to thoroughly test. | |
# OpenVPN might exit on an error without cleaning up the service. | |
. /etc/rc.subr | |
name=vpn | |
rcvar=${name}_enable | |
load_rc_config ${name} | |
: ${vpn_enable:=NO} | |
: ${vpn_pidfile:="/var/run/$service/vpn.pid"} | |
: ${vpn_conf:="/usr/local/etc/openvpn/client.conf"} | |
: ${vpn_log:="/var/log/openvpn.log"} | |
: ${vpn_up_postcmd:="/bin/echo"} | |
: ${vpn_up_precmd:="/bin/echo"} | |
: ${vpn_down_precmd:="/bin/echo"} | |
: ${vpn_down_postcmd:="/bin/echo"} | |
if [ -z "$vpn_service" ]; then | |
err 3 'Set vpn_service=SERVICE in rc.conf to control SERVICE.' | |
fi | |
pidfile=${vpn_pidfile} | |
command=/usr/local/sbin/openvpn | |
service=/usr/sbin/service | |
vpn_flags="--config $vpn_conf --writepid $pidfile --daemon vpn --log $vpn_log" | |
vpn_flags="$vpn_flags --script-security 2" | |
vpn_flags="$vpn_flags --up '$service $name up' --up-delay" | |
vpn_flags="$vpn_flags --up-delay --down '$service $name down' --down-pre" | |
on_up() { | |
$vpn_up_precmd "$@" | |
$service $vpn_service onerestart | |
$vpn_up_postcmd "$@" & | |
} | |
on_down() { | |
$vpn_down_precmd "$@" | |
$service $vpn_service onestop | |
$vpn_down_postcmd "$@" & | |
} | |
if [ "$1" = "up" ]; then | |
shift | |
on_up "$@" | |
elif [ "$1" = "down" ]; then | |
shift | |
on_down "$@" | |
else | |
run_rc_command "$1" | |
fi |
The purpose of this vpn
service is to connect to a VPN via openvpn
at boot and start/stop a service when the VPN client process starts/stops. The script is documented; to summarize, install at:
/usr/local/etc/rc.d/vpn
Edit /etc/rc.conf to add:
vpn_enable="YES"
vpn_service="SERVICE"
... where SERVICE is the name of the service to control on VPN start/stop. Load OpenVPN configuration at:
/usr/local/etc/openvpn/client.conf
Install OpenVPN:
pkg install -y openvpn
Start:
service vpn start
Tested on FreeBSD 11.
Check your IP address:
pkg install -y dns/bind-tools
dig +short myip.opendns.com @resolver1.opendns.com
I recently ran into DNS resolution issues. While workarounds are best avoided, I wanted a workaround without using the many heavy-handed "fix resolv.conf" solutions out there.
In /usr/local/bin/vpn-fix-resolvconf:
#!/bin/sh
# Rewrite resolv.conf using presumed OpenVPN gateway,
# if DNS queries resolve using the presume gateway IP,
# which assumes the gateway server may provide a DNS server.
#
# Call via vpn_up_postcmd in rc.conf.
# tun1 1500 1555 10.8.0.6 10.8.0.5 init
ip=$4
ns="${ip%.*}.1"
if /usr/local/bin/dig +time=2 +tries=3 @$ns; then
echo "Overwriting /etc/resolv.conf from $0" >&2
echo "# Generated by $0" > /etc/resolv.conf
echo "nameserver $ns" >> /etc/resolv.conf
else
echo "No DNS server found at $ns" >&2
fi
In rc.conf:
vpn_up_postcmd="/usr/local/bin/vpn-fix-resolvconf"
Sorry but what is "... where SERVICE is the name of the service to control on VPN start/stop. " supposed to mean?
This rc.d script is for a VPN client on BSD that controls another service alongside the OpenVPN connection. I updated the title of the gist to clarify that up front:
OpenVPN rc.d script for VPN client on BSD (i.e. jail): connect to VPN, start another service once VPN is connected.
The idea is to have a FreeBSD jail that starts some service (SERVICE
) -- jails are often about one service -- only after the OpenVPN connection is established. SERVICE is the name of the service to pass to /usr/sbin/service
, i.e. some other rc.d service by name.
If you are are looking to just start/stop the OpenVPN connection, most of this rc.d script is unnecessary.
Looking back, I did use this rc.d script successfully, but ultimately abandoned the idea. I found it much simpler to move the service up to the VPN-originating network, then just sync the data down (rsync, sftp, https, ...), bypassing any need for OpenVPN and its maintenance.
Note that GitHub does not send notifications for comments on gists, so I probably will not see any comments here.