Skip to content

Instantly share code, notes, and snippets.

@akomakom
Last active November 11, 2019 15:16
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 akomakom/fd0c712e95e58a2c4a7cec9c90c38b05 to your computer and use it in GitHub Desktop.
Save akomakom/fd0c712e95e58a2c4a7cec9c90c38b05 to your computer and use it in GitHub Desktop.
barracudavpn <-> systemd-resolve compatibilty script

barracudavpn <-> systemd-resolve compatibilty script

Problem

My corporate Ubuntu laptop is set up with barracudavpn that doesn't understand systemd-resolve.
In its default configuration it simply overwrites /etc/resolv.conf, completely screwing up DNS on my local LAN (and non-work DNS).

Purpose

I'd like to have completely flexible DNS configuration that is cleanly segmented by interface.

Solution

In order to do that, I'm willing to:

  • Configure barracudavpn client to never touch /etc/resolv.conf
  • Maintain my own config file with corporate DNS settings
  • Connect barracudavpn with a script (the one in this gist) instead of by directly running it (this way I can pass cmd-line args)
  • Have the script run systemd-resolve -i tun0 --set-dns=X --set-domain=Y type command after connecting.
  • Periodically check that the above is still in effect (if the network connection dies, it is cleared).

Installation

  1. Disable resolve.conf overwriting in barracudavpn options (Configure DNS=NO)

  2. Also remove any hardcoded DNS your IT department may have placed into your /etc/systemd/resolved.conf

  3. Ensure that your /etc/nsswitch.conf has resolve early in the hosts entry, eg:

    hosts: files resolve mdns4_minimal dns [NOTFOUND=return] myhostname

  4. Ensure that you can run sudo systemd-resolve -i tun0 --set-dns=XXXX and similar. Passwordless or not is up to you.

  5. Place vpn script anywhere in your $PATH, eg /usr/local/bin, make executable.

  6. Create aliasing symlinks as mentioned in the top of the script.

  7. Copy vpn.properties to /etc/default/vpn and edit to your needs

  8. Test by running (as your user, not root) vpn-up, vpn-down and vpn-status. You should have correct per-interface DNS settings after it runs.

  9. Add a cronjob to run vpn-status --fix periodically so that it can fix DNS settings after your network disconnects. Personally, I use XFCE's Generic Monitor applet to run this and display the output, so I get two for the price of one.

Done.

Troubleshooting

Run any of the scripts with tracing, eg: bash -x /usr/local/bin/vpn-up

#!/bin/bash
# Compatibility script between systemd and barracudavpn
# Intended to be used via symlinks:
# ln -s vpn vpn-up
# ln -s vpn vpn-down
# ln -s vpn vpn-status
#
# Requires sudoers entry to allow "systemd-resolve *"
#
# Usage:
#
# * vpn-up
# * vpn-down
# * vpn-status
# (sets exit code and prints out status, useful for indicators like xfce generic monitor)
# * vpn-status --fix
# (same but also corrects systemd-resolve settings that may be lost if network connection was lost)
#
# "vpn-status --fix" can be run on cron. It will only perform fix actions if the connection is up.
name=$(basename $0)
source /etc/default/vpn
status() {
STATUS=$(barracudavpn --status | grep -E '^Status:|^STATE:' | awk '{print $2}')
[ "$STATUS" == "CONNECTED" ]
}
# If the connection dropped (eg wifi, not VPN),
# our additions to systemd-resolve disappear.
set_resolve() {
# Check that the settings are already in place:
local FIRST_DNS ARGS
FIRST_DNS=$(echo $DNS | grep -o "^[0-9\.]*\b")
if ! systemd-resolve -i $DEVICE --status | grep -E "DNS.*:.*$FIRST_DNS" > /dev/null ; then
ARGS="-i $DEVICE"
for SERVER in $DNS; do
ARGS="$ARGS --set-dns=$SERVER"
done
for DOMAIN in $DOMAINS; do
ARGS="$ARGS --set-domain=$DOMAIN"
done
sudo systemd-resolve $ARGS
fi
}
case $name in
vpn-up)
if status ; then
echo "Already connected"
else
barracudavpn $BARRACUDA_ARGS
fi
set_resolve
;;
vpn-down)
barracudavpn --stop
;;
vpn-status)
status
EXIT=$?
if [ $EXIT -eq 0 ] && [ "$1" == "--fix" ] ; then
set_resolve
fi
echo $STATUS
exit $EXIT
;;
*)
echo "Please use the symlinks"
exit 1
esac
# Config file for barracuda<->systemd compatibility script
# that sets DNS options after connecting
# Place into /etc/default/vpn
# Device to modify DNS settings for
DEVICE="tun0"
# Can be a space-delimited list:
DNS="1.2.3.4"
# Search domains, can be a space-delimited list:
DOMAINS="search.domain.1 search.domain.2"
# Barracuda args for connecting:
BARRACUDA_ARGS="--start --keypwd XXX --login YYYY --serverpwd ZZZZ"
# ZZZZ can be a command, eg $(ZZZZZ)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment