Skip to content

Instantly share code, notes, and snippets.

@marcust
Last active August 3, 2016 06:21
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save marcust/919ef5ad5bea6449fd75 to your computer and use it in GitHub Desktop.
Save marcust/919ef5ad5bea6449fd75 to your computer and use it in GitHub Desktop.
Nameserver setup script for OpenVPN in combination with Ubuntu's NetworkManager and dnsmasq
#!/bin/bash
#
# Parses DHCP options from openvpn to send to dnsmasq via dbus
# To use set as 'up' and 'down' script in your openvpn *.conf:
# up /etc/openvpn/update-dnsmasq
# down /etc/openvpn/update-dnsmasq
#
# 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'
#
DEV_DIR="/etc/openvpn/devices"
[ "$script_type" ] || exit 0
[ "$dev" ] || exit 0
if [ ! -d $DEV_DIR ]; then
mkdir $DEV_DIR;
fi
split_into_parts()
{
part1="$1"
part2="$2"
part3="$3"
}
inet_aton() {
local count=3
local int=0
for num in $(echo $1 | sed -e 's/\./ /g'); do
let "int+=$num*256**$count"
let "count-=1"
done
echo $int
}
update_dnsmasq() {
PARAMS=
for file in $DEV_DIR/*.openvpn; do
ns=$(cat $file | sed -n -e 's/^[[:space:]]*nameserver[[:space:]]\+//p')
PARAMS+="uint32:$(inet_aton $ns) "
domain=$(cat $file | sed -n -e 's/^[[:space:]]*search[[:space:]]\+//p')
PARAMS+="string:$domain "
done
# load default nameservers from network manager
for nameserver in $(nmcli device show | grep DNS | awk '{print $2}' | grep -E '[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}'); do
PARAMS+="uint32:$(inet_aton $nameserver) string: "
done
dbus-send --system --print-reply --dest='org.freedesktop.NetworkManager.dnsmasq' \
/uk/org/thekelleys/dnsmasq uk.org.thekelleys.SetServers $PARAMS
}
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" > "$DEV_DIR/${dev}.openvpn"
update_dnsmasq
;;
down)
rm -fv "$DEV_DIR/${dev}.openvpn"
update_dnsmasq
;;
esac
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment