Nils Schneider

VPN mit fastd

fastd ist ein einfacher VPN Daemon. Er wurde ursprünglich für den Einsatz auf Geräten mit geringem Speicher entwickelt, eignet sich jedoch auch sehr gut um normale Computer miteinander zu verbinden.

Es werden sowohl TUN- als auch TAP-Tunnel untertützt. Der TAP-Modus arbeitet auf Layer 2, TUN auf Layer 3.

Installation

Für Debian Distributionen und Arch Linux gibt es Pakete, die die Installation von fastd einfach gestalten.

Debian/Ubuntu

Die Debian Pakete werden für amd64 und i386 bereitgestellt. Um sie zu installieren, wird folgende Zeile in /etc/apt/sources.list eingefügt:

deb https://repo.universe-factory.net/debian/ sid main

Diese Zeile muss auch auf anderen Distributionen als sid nicht angepasst werden. Anschließend wird die Paketdatenbank aktualisiert und fastd installiert:

$ apt-get update
$ apt-get install fastd

Arch Linux

Im AUR befindet sich ein fastd Paket. Dieses kann wie gewohnt installiert werden.

Server-Client Szenario

Im Folgenden wird ein einfaches Server-Client Szenario beschrieben bei dem mehrere Client mit einem Server verbunden werden können. Dabei wird der TAP Modus verwendet. Dies entspricht im wesentlichen auch dem Setup, welches in der Lübecker Freifunk Firmware Anwendung findet.

Konfiguration des Servers

Zunächst erstellen wir ein Verzeichnis für unser VPN und wechseln dorthin:

mkdir -p /etc/fastd/vpn/
cd /etc/fastd/vpn/

Jeder fastd-Peer benötigt ein Secret, einen privaten Schlüssel. Dieser wird mit fastd --generate-key erstellt:

# fastd --generate-key
2013-02-17 23:46:03 +0100 --- Info: Reading 32 bytes from /dev/random...
Secret: 601ae139eeff9581e99a9ea27e1fc3a72daaa05ac11834bd4f86c39fb273936a
Public: 83369beddca777585167520fb54a7fb059102bf4e0a46dd5fb1c633d83db77a2

Hier erstellen wir nun die Datei fastd.conf und tragen das Secret ein:

bind any:1234; # UDP Port 1234 auf allen Interfaces
mode tap;
method "xsalsa20-poly1305"; # Verschlüsselungsalgorithmus festlegen
mtu 1426;
secret "601ae139eeff9581e99a9ea27e1fc3a72daaa05ac11834bd4f86c39fb273936a";

include peers from "peers";

on up "
  ip link set up $INTERFACE
";

Wir werden die öffentlichen Schlüssel in das Verzeichnis peers legen und legen es mit mkdir an:

mkdir peers

Starten des Servers

Jetzt können wir den Server starten:

# fastd -c /etc/fastd/vpn/fastd.conf
2013-02-17 23:54:23 +0100 --- Info: fastd 7 starting
2013-02-17 23:54:23 +0100 --- Info: successfully bound to any
2013-02-17 23:54:23 +0100 --- Verbose: Dropped capabilities.

Konfiguration des Clients

Auf dem Client läuft alles sehr ähnlich ab. Auch hier erstellen wir wieder das Verzeichnis /etc/fastd/vpn/ und darin peers/ und erstellen ein Schlüsselpaar mit fastd --generate-key. Lediglich die Datei fastd.conf sieht nun leicht anders aus, denn die bind Option ist nicht nötig:

mode tap;
method "xsalsa20-poly1305"; # Verschlüsselungsalgorithmus festlegen
mtu 1426;
secret "b00a03a5541d3f74868e45dd38cfdb59aa40d1126c5c64adbab67b68e246fc7a";

include peers from "peers";

on up "
  ip link set up $INTERFACE
";

Im Unterverzeichnis peers/ legen wir nun eine Datei für den Server an. Dazu benötigen wir den öffentlichen Schlüssel des Servers, den fastd aus dem Secret erzeugen kann:

server # fastd --show-key -c /etc/fastd/vpn/fastd.conf
Public: 83369beddca777585167520fb54a7fb059102bf4e0a46dd5fb1c633d83db77a2

Die Datei peers/server erstellen wir also wie folgt:

key "83369beddca777585167520fb54a7fb059102bf4e0a46dd5fb1c633d83db77a2";
remote "server.example.com" port 1234;

Eintragen des Clients auf dem Server

Nun müssen wir dem Server noch den öffentlichen Schlüssel des Clients mitteilen. Dazu verwenden wir wieder fastd --show-key -c /etc/fastd/vpn/fastd.conf und erstellen auf dem Server die Datei /etc/fastd/vpn/peers/client:

key "739ef68045fbc0614e526ecdabdf82e8142762e909e4a101d21d0dbd88d282da";

Um fastd alle Peers neu einlesen zu lassen senden wir ein SIGHUP an den fastd Prozess

# pkill -HUP fastd

und beobachten die Ausgabe von fastd auf dem Server:

2013-02-18 00:06:44 +0100 --- Info: reconfigure triggered
2013-02-18 00:06:44 +0100 --- Verbose: adding peer <client> (group `default')

Starten des Clients

Jetzt ist alles vorbereitet um fastd auf dem Client zu starten:

client # fastd -c /etc/fastd/vpn/fastd.conf
2013-02-18 00:07:52 +0100 --- Info: fastd 7 starting
2013-02-18 00:07:52 +0100 --- Verbose: adding peer <server> (group `default')
2013-02-18 00:07:52 +0100 --- Verbose: Dropped capabilities.
2013-02-18 00:07:52 +0100 --- Verbose: resolving host `server.example.com' for peer <server>...
2013-02-18 00:07:52 +0100 --- Verbose: resolved host `server.example.com' successfully
2013-02-18 00:07:52 +0100 --- Verbose: received handshake response from <server>[[2001:db8:ffff::1]:1234] using fastd 7
2013-02-18 00:07:52 +0100 --- Verbose: [2001:db8:ffff::1]:1234 authorized as <server>
2013-02-18 00:07:52 +0100 --- Info: connection with <server> established.
2013-02-18 00:07:52 +0100 --- Verbose: new session with <server> established using method `xsalsa20-poly1305'.

Auch jetzt beobachten wir wieder die Ausgabe auf dem Server:

2013-02-18 00:07:53 +0100 --- Verbose: received handshake from <client>[[2001:db8:ffff::2]:58583] using fastd 7
2013-02-18 00:07:53 +0100 --- Verbose: [2001:db8:ffff::2]:58583 authorized as <client>
2013-02-18 00:07:53 +0100 --- Info: connection with <client> established.
2013-02-18 00:07:53 +0100 --- Verbose: new session with <client> established using method `xsalsa20-poly1305'.

Der Tunnel wurde erfolgreich aufgebaut.

Pings

Auf beiden Systemen existiert nun ein Interface mit dem Namen tap0:

server # ip address show tap0
4: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1426 qdisc pfifo_fast state UNKNOWN qlen 500
	link/ether 1a:8f:14:59:21:f7 brd ff:ff:ff:ff:ff:ff
	inet6 fe80::188f:14ff:fe59:21f7/64 scope link
	   valid_lft forever preferred_lft forever
	   
client # ip address show tap0
5: tap0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1426 qdisc pfifo_fast state UNKNOWN qlen 500
	link/ether 7a:46:3a:9f:8d:b2 brd ff:ff:ff:ff:ff:ff
	inet6 fe80::7846:3aff:fe9f:8db2/64 scope link 
	   valid_lft forever preferred_lft forever

Über die Link-Local Addresse können wir nun den jeweils anderen Host erreichen:

server # ping6 -c 3 fe80::7846:3aff:fe9f:8db2%tap0
PING fe80::7846:3aff:fe9f:8db2%tap0(fe80::7846:3aff:fe9f:8db2) 56 data bytes
64 bytes from fe80::7846:3aff:fe9f:8db2: icmp_seq=1 ttl=64 time=0.537 ms
64 bytes from fe80::7846:3aff:fe9f:8db2: icmp_seq=2 ttl=64 time=0.934 ms
64 bytes from fe80::7846:3aff:fe9f:8db2: icmp_seq=3 ttl=64 time=0.704 ms

--- fe80::7846:3aff:fe9f:8db2%tap0 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.537/0.725/0.934/0.162 ms

Und vom Client aus:

client # ping6 -c 3 fe80::188f:14ff:fe59:21f7%tap0
PING fe80::188f:14ff:fe59:21f7%tap0(fe80::188f:14ff:fe59:21f7) 56 data bytes
64 bytes from fe80::188f:14ff:fe59:21f7: icmp_seq=1 ttl=64 time=0.754 ms
64 bytes from fe80::188f:14ff:fe59:21f7: icmp_seq=2 ttl=64 time=0.855 ms
64 bytes from fe80::188f:14ff:fe59:21f7: icmp_seq=3 ttl=64 time=0.850 ms

--- fe80::188f:14ff:fe59:21f7%tap0 ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 1998ms
rtt min/avg/max/mdev = 0.754/0.819/0.855/0.057 ms

Interfaces konfigurieren

Um die TAP-Interfaces zu konfigurieren kann das up-Script in der fastd.conf verwendet werden. Hier ein Beispiel um dem Interface eine feste IP zuzuweisen:

up "
  ip link set up $INTERFACE
  ip address add 2001:db8::1/64 dev $INTERFACE
";

Möchte man das Interface für B.A.T.M.A.N. Advanced verwenden, könnte das Skript in etwa so aussehen:

up "
  ip link set up $INTERFACE
  batctl if add $INTERFACE
";

systemd.unit

Läuft auf einem Host systemd, lässt sich ein so konfiguriertes VPN leicht automatisch starten:

# systemd enable fastd@vpn.service

Dabei ist vpn dem Namen des Verzeichnisses in /etc/fastd/ anzupassen.