02 August 2013

[Howto] NetworkManager: VPNs abhängig vom Standort starten

Kategorien: HowTos
Tags: VPN

Wer mit seinem Laptop zwischen Wohnung und Arbeitsplatz pendelt, möglicherweise viel reist und öffentliche Funknetze verwendet, der hat womöglich die Vorzüge von VPNs bereits schätzen gelernt, die es einem erlauben, verschlüsselt mit entfernten privaten Netzen zu kommunizieren, oder auch eine selbstkontrollierte Transportverschlüsselung an vertrauensunwürdigen Zugangspunkten zu realisieren.

Unpraktisch wird es dann, wenn je nachdem an welchem Standort man sich befindet, unterschiedliche VPN-Zugänge benötigt werden, die beim Aufklappen des Laptops manuell ausgewählt werden müssen. Schöner wäre es, wenn der Computer selbst in der Lage wäre zu erkennen, welches VPN gerade die richtige Wahl ist. Wer Debian oder Ubuntu benutzt, konnte schon „immer“ mit einem mapping-script und einiger Konfiguration in /etc/network/interfaces auch ifupdown dazu bekommen, diesen Wunsch zu erfüllen. Dieser Artikel löst diese Aufgabe jedoch für NetworkManager, der inzwischen in Desktop-Installationen große Verbreitung gefunden hat.

NetworkManager (von nun an NM) bietet die Möglichkeit, in dem Verzeichnis /etc/NetworkManager/dispatcher.d/ Programme abzulegen, die von NM ausgeführt werden, wenn sich der Status einer Verbindung ändert. Dies ist die Stelle, an der wir ein Script 50autovpn ablegen, um unsere VPNs zu verwalten.

Zunächst einmal erhalten dispatcher-Programme von NM zwei Parameter, nämlich das Interface dessen Konfiguration sich geändert hat und den aktuellen Status:

#!/bin/sh -e
# Script to dispatch NetworkManager events
#
# Automatically starts VPN services for specific base connections.
# See NetworkManager(8) for further documentation of the dispatcher events.
 
IF=$1
STATUS=$2
 
if [ -z "$IF" ]; then
    echo "$0: called with no interface" 1>&2
    exit 1;
fi

NM unterscheidet zwischen VPN-Verbindungen und Basisverbindungen, also allen Verbindungen, die keine VPN-Verbindung sind. Folgerichtig kann der von NM an das Script übergebene Status up, down, vpn-up oder vpn-down lauten. Zusätzlich existieren die Status hostname, dhcp4-change und dhcp6-change für Änderungen in diesen Komponenten. Sorgen wir also zunächst dafür, dass das Script mit allen Status zurechtkommt:

case "$STATUS" in
    up)
        # actions will go here
        ;;
    down|vpn-up|vpn-down|hostname|dhcp4-change|dhcp6-change)
        # Do nothing
        ;;
    *)
        echo "$0: called with unknown action \`$2'" 1>&2
        exit 1
        ;;
esac

Da NM die VPN-Verbindungen automatisch schließt wenn die Basisverbindung wegbricht, ist der einzige Status an dem wir interessiert sind, der Status up.Situation 1: Am Arbeitsplatz soll ein VPN zum Kunden, an dessen Projekt wir gerade arbeiten, aufgebaut werden:

WORK_NET="192.168.222.0/24"
CUSTOMER_UUID="a5715412-8ad4-4c91-9846-025be8772315"
 
if [ "$IF" = "eth0" ] && [ -n "$(/sbin/ip addr show $IF to $WORK_NET)" ]; then
        /usr/bin/nmcli con up uuid $CUSTOMER_UUID
fi

Wenn also eth0 mit dem Subnetz des Firmennetzwerks konfiguriert ist, soll das VPN mit der UUID a5715412-8ad4-4c91-9846-025be8772315 gestartet werden. Die Kommandozeilenschnittstelle nmcli kann zuvor verwendet werden, um die UUIDs der Verbindungen herauszufinden:

nmcli con list

Situation 2: Im heimischen WLAN soll eine VPN-Verbindung zum Firmennetz hergestellt werden:

HOME_SSID="home"
HOME_UUID="56e09fda-3490-4292-b5e8-7ed86595f3b9"
 
if [ "$IF" = "wlan0" ] && [ "$HOME_SSID" = "$(iwgetid -r)" ]; then
        /usr/bin/nmcli con up uuid $HOME_UUID
fi

Situation 3: In unbekannten WLAN-Netzen soll ein Volltunnel zu einem vertrauenswürdigen VPN-Host gestartet werden:

TRUSTED_SSIDS="home company"
FULL_TUNNEL_UUID="a352d5f1-fcba-4865-ab7e-caa3502c7b27"
 
unknown_wlan () {
    local SSID
    SSID=$(iwgetid -r)
 
    for i in $TRUSTED_SSIDS; do
        if [ "$i" = "$SSID" ]; then
            return 1
        fi
    done
    return 0
}
 
if [ "$IF" = "wlan0" ] && unknown_wlan; then
        /usr/bin/nmcli con up uuid $FULL_TUNNEL_UUID
fi

Zusammenfassung: Diese drei beispielhaften Situationen zeigen, wie mit dispatcher-Scripten Abhängigkeiten zwischen konfigurierten Verbindungen hergestellt werden können. Andere Anforderungen sind natürlich denkbar und auf analoge Art und Weise lösbar. Zu guter Letzt wird noch einmal das vollständige Script /etc/NetworkManager/dispatcher.d/50autovpn aufgeführt:

#!/bin/sh -e
# Script to dispatch NetworkManager events
#
# Automatically starts VPN services for specific base connections.
# See NetworkManager(8) for further documentation of the dispatcher events.
 
IF=$1
STATUS=$2
 
if [ -z "$IF" ]; then
    echo "$0: called with no interface" 1>&2
    exit 1;
fi
 
WORK_NET="192.168.222.0/24"
CUSTOMER_UUID="a5715412-8ad4-4c91-9846-025be8772315"
 
HOME_SSID="home"
HOME_UUID="56e09fda-3490-4292-b5e8-7ed86595f3b9"
 
TRUSTED_SSIDS="home company"
FULL_TUNNEL_UUID="a352d5f1-fcba-4865-ab7e-caa3502c7b27"
 
unknown_wlan () {
    local SSID
    SSID=$(iwgetid -r)
 
    for i in $TRUSTED_SSIDS; do
        if [ "$i" = "$SSID" ]; then
            return 1
        fi
    done
    return 0
}
 
case "$STATUS" in
    up)
        if [ "$IF" = "eth0" ] && [ -n "$(/sbin/ip addr show $IF to $WORK_NET)" ]; then
                /usr/bin/nmcli con up uuid $CUSTOMER_UUID
        fi
 
        if [ "$IF" = "wlan0" ] && [ "$HOME_SSID" = "$(iwgetid -r)" ]; then
                /usr/bin/nmcli con up uuid $HOME_UUID
        fi
 
        if [ "$IF" = "wlan0" ] && unknown_wlan; then
                /usr/bin/nmcli con up uuid $FULL_TUNNEL_UUID
        fi
        ;;
    down|vpn-up|vpn-down|hostname|dhcp4-change|dhcp6-change)
        # Do nothing
        ;;
    *)
        echo "$0: called with unknown action \`$2'" 1>&2
        exit 1
        ;;
esac

 

Dieser Artikel wurde ursprünglich geschrieben von Carsten Wolff.

Kategorien: HowTos
Tags: VPN

SH

über den Autor

Sascha Heuer


Beitrag teilen: