www.fabiankeil.de/freebsd/ipsec_vpn/

IPsec-Tunnel legen mit FreeBSD

Wieso?

Manchmal kann man es nicht vermeiden, über Verbindungen zu kommunizieren, deren Sicherheit nicht garantiert ist, oder dessen Unsicherheit gewiß ist. In solchen Fällen bietet es sich an, Protokolle zu verwenden, die den Netzwerkverkehr verschlüsseln. Statt telnet greift der denkende Mensch also zu OpenSSH, vertrauliche Daten gibt er im Web nur dann in Formulare ein, wenn der Versand über https an Stelle von http erfolgt.

Nicht für jedes unsichere Protokoll existiert eine verschlüsselnde Alternative. Das unter Unix und seinen Derivaten beliebte Network File System, mit dem sich Verzeichnisse oder ganze Dateisysteme von entfernten Rechnern aus lokal einbinden lassen, kommt sogar ohne Passwort-Autentifizierung daher – Zutritt bekommen die Rechner mit den passenden IP-Adressen.

Jeder Benutzer kann sich so viele IP-Adressen zuordnen wie er Lust hat. Auch wenn entsprechend konfigurierte Router die unberechtigte Benutzung der Adressen erschweren können, verhindern kann man sie nicht. Zur Not benutzt der Angreifer eben den Router-Port des Rechners dessen Netzwerk-Adresse er verwenden will.

FTP erlaubt zwar, berechtigte Benutzer an Hand von Namen und Passwörtern zu erkennen, die Passwörter werden jedoch ebenso unverschlüsselt über das Kabel – oder gar durch die Luft – geschickt. Eine Einladung für alle Mithörenden.

Es existieren FTP-Varianten, die den Steuerkanal und damit auch Passwort und Benutzername verschlüsseln, der Datenkanal kann jedoch weiterhin von entsprechend positionierten Interessierten mitgelesen werden. Meist wird FTP nur eingesetzt, um die Inhalte öffentlicher Websites zu aktualisieren, in diesem Fall ist die Sicherheit des Datenkanals weniger wichtig. Die meisten Webmaster fühlten sich geschmeichelt, wenn ihre Inhalte für so interessant angesehen würden, dass sie schon während dem Hochladen gelesen werden müssten. Für diese Webmaster ist es ausreichend, wenn der Mitlesende nicht auch zum Mitschreibenden wird.

Sobald die Inhalte der Website nicht für die Öffentlichkeit bestimmt sind, oder aber noch deutlich kritischere Inhalte übertragen werden, beispielsweise Sicherungen von Firmendatenbanken, ist die Verschlüsselung der gesamten Kommunikation nötig.

Kunden könnten ungehalten reagieren, wenn ihnen überraschend das Konto geleert würde, weil ihre Kreditkarten-Daten von freundlichen Menschen, die das Bedürfnis hatten, auf gewisse Sicherheitslücken aufmerksam zu machen, in die Tauschbörsen gestellt wurden.

Möglicherweise wird sich eine entsprechend getroffene Firma damit rausreden wollen, dass der zuständige Mitarbeiter die Daten natürlich hätte verschlüsseln müssen, und das er in dieser Firma kein zweites Mal begehen könnte, den ein oder anderen Kunden – ob betroffen oder nicht – wird ein solches Datenleck dennoch zum Wechsel animieren.

Es lohnt sich also über die Sicherheit nachzudenken, bevor die Kundendaten in den Esel gefallen sind bzw. bevor die über NFS exportierten Privatvideos die Nachbarschaft unterhalten.

Funktionsprinzip eines Virtual Private Networks

Ob man nun den Videofreunden die Kulturgüter vorenthalten oder nur das Vertrauen seiner Kunden erhalten möchte, die Lösung ist die gleiche, sie lautet IPsec-Tunnel auch VPN genannt.

Ein virtuelles privates Netzwerk (VPN) besteht aus mindestens zwei Rechnern, die eine verschlüsselte Verbindung miteinander haben, durch die sie alle Protokolle tunneln. Jedes Paket, egal ob es zu einer telnet- oder einer ssh-Verbindung gehört, wird dabei in ein anderes Paket gesteckt, verschlüsselt und verschickt. Die verwendetet Verschlüsselung muss nicht zwangsläufig IPsec sein, IPsec gehört jedoch zu den am weitesten verbreiteten und ist außerdem standardisiert.

Das VPN kann ruhig durch ein öffentliches unsicheres Netz gelegt werden. Wie der Name schon sagt, bildet es ein eigenes privates Netz, unabhängig von der Route die die einzelnen Pakete durchlaufen. Den Paketen lassen sich lediglich die äußeren Header entnehmen, ein Mithörer erfährt also nur, welche beiden Rechner Anfang und Ende des Tunnels bilden. Was die Pakete enthalten und wer eigentlich mit wem über den Tunnel kommuniziert, bleibt für ihn im Dunkeln. Die beiden Rechner an den Tunnel-Enden könnten ja auch als Gateways betrieben werden, und so ganze Netze miteinander verbinden.

VPN zur Absicherung eines Funknetzwerks

Leider besitze ich keine zwei Netze, die ich miteinander verbinden könnte. Stattdessen habe ich einen Laptop, der über eine Funkverbindung mit dem Internet verbunden ist. Die Funkverbindung ist nur WEP-verschlüsselt, kann also innerhalb von Stunden geknackt werden.

Ein VPN hindert natürlich niemanden daran, die WEP-Verschlüsselung zu brechen – die transportierten Daten schützt es aber sehr wohl. WEP hat keine Auswirkungen auf die Geschwindigkeit, kann also ruhig an bleiben.

Mein Laptop läuft unter FreeBSD, der Access-Point unter einem verkappten Montavista Linux, dessen Konfiguration nur über ein Webinterface möglich ist, welches keine Einstellungen für ein VPN bietet.

Für den Laptop kann der Router daher nicht als Ansprechpartner am Tunnel-Ende dienen, ein weiterer Rechner musste her, oder ein bereits vorhandener mit dieser Zusatzfunktion beauftragt werden.

Hier wird der Tunnel daher zwischen dem Laptop und einem File-Server im Keller gelegt, der zusätzlich die Gateway-Funktion übernimmt, und ins lokale Netzwerk sowie ins Internet routet. Die vom Laptop kommenden Daten gehen auf dem Weg zum Server verschlüsselt durch den Access-Point, auf dem Weg zum Rest vom Netzwerk oder ins Internet passieren sie ihn ein zweites mal, nun aber unverschlüsselt.


                 --------------------- 
  -------       |                     |       ---------------
 |Laptop |--->--- D-Link-Access-Point -->----| FreeBSD-Server|
  -------       |                     |       -----|---------
                |                     |----<--------
                 ---------------------           ---------- 
                           |     |              |          |
                           |     ---------------- Internet |
                     --------------------       |          |
                    |  Rest vom Netzwerk |       ----------
                     -------------------- 
  

Für meine Zwecke ist das ausreichend, das Ziel war lediglich, die Sicherheit der Luftstrecke zu erhöhen.

Umsetzung

Der FreeBSD-Server läuft nicht den ganzen Tag über, für einfaches Surfen im Netz, oder um verschlüsselt Mails abzurufen, kann er aus bleiben. Der Laptop muss also noch die Möglichkeit behalten, mit wenig Aufwand wieder den D-Link-Access-Point als Gateway zu benutzen.

Das geschieht am einfachsten, in dem man der Funknetzwerkkarte zwei IP-Adressen zu ordnet, und dann lediglich die Standard-Route den Bedingungen anpasst. Um Fehler zu vermeiden, wählt man diese beiden Adressen auch aus unterschiedlichen Netzen.

Das unverschlüsselte Netzwerk ist in meinem Fall 192.168.1.0, Netzmaske ist 255.255.255.0. Bei 254 zur Verfügung stehenden Adressen pro Netz gibt es auch keine Streitigkeiten zwischen den sechs angeschlossenen Rechnern. Das zweite Netz hat die gleiche Netzmaske, die Netzadresse ist 192.168.2.0.

Das zweite Netz ist ebenso wenig verschlüsselt wie das erste, es dient lediglich dazu, Tunnelanfang und -ende aufzunehmen. Die eigentliche Verschlüsselung findet im IPsec-Tunnel statt, er beinhaltet ein drittes Netz, das dann von den Programmen der jeweiligen Rechner angesprochen werden kann, wie jedes andere. Das dritte Netz (192.168.3.0) ist das VPN. Pakete die für das VPN bestimmt sind, werden verschlüsselt und über das zweite Netz versandt.

Die Beschreibung macht vielleicht einen komplexen Eindruck, ist aber unter FreeBSD schnell umgesetzt.

Konfiguration des Laptops

Die Funknetzwerkkarte hat bereits die IP-Adresse 192.168.1.49, die zweite bekommt sie mit dem Befehl.

ifconfig ndis0 alias 192.168.2.49 netmask 0xffffff00

Ein virtuelles privates Netzwerk würde den Namen nicht verdienen, wenn man es nicht über ebenso virtuelle Netzwerkkarten laufen ließe. Die virtuelle Netzwerkkarte im Laptop ist anschließend Ansprechpartner für die Programme, die über das VPN kommunizieren wollen. Erzeugt wird sie durch:

ifconfig gif0 create

Sobald die virtuelle Netzwerkkarte angelegt wurde, können die beiden Tunnel-Enden angegeben werden:

ifconfig gif0 tunnel 192.168.2.49 192.168.2.40

192.168.2.49 ist hier die Tunnelseite des Laptops, 192.168.2.40 die Tunnelseite des Servers.

Wenn der Tunnel steht, kann das zu tunnelnde Netz erzeugt werden.

ifconfig gif0 inet 192.168.3.49 192.168.3.40 netmask 0xffffffff

Die Netzmaske besteht nur aus Einsen, das dritte Netzwerk ist also eher eine Linie als ein Werk.

Die Überprüfung der vorgenommen Konfiguration:

root@r51 /home/fk #ifconfig gif0
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        tunnel inet 192.168.2.49 --> 192.168.2.40
        inet6 fe80::211:25ff:fe2f:e89f%gif0 prefixlen 64 scopeid 0x5 
        inet 192.168.3.49 --> 192.168.3.40 netmask 0xffffffff

Sieht gut aus. Das verkleinerte Maximum Transfer Limit MTU, das heißt die Paketgröße die maximal noch durch den Tunnel passt, ergibt sich dadurch, das die Pakete noch weiterverpackt und verschlüsselt werden müssen, also nochmal anwachsen und anschließend dennoch unfragmentiert durch das zweite Netz passen sollen, wo ein MTU von 1500 Bytes existiert. Ob 1280 bereits der optimale Wert ist, habe ich nicht überprüft.

Die eine Tunnelhälfte steht nun, die Hälfte auf der Server-Seite wird nach dem gleichen Prinzip erzeugt, nur die IP-Adressen von Server und Laptop müssen ihre Position wechseln.

Netzwerkkarte mit weiterer IP-Nummer ausstatten:

ifconfig rl0 alias 192.168.2.40 netmask 0xffffff00

Virtuelle NIC erzeugen:

ifconfig gif0 create

Tunnelanfang und -ende angeben:

ifconfig gif0 tunnel 192.168.2.40 192.168.2.49

Die beiden IPs aus dem Netzwerk, das getunnelt werden soll angeben:

ifconfig gif0 inet 192.168.3.40 192.168.3.49 netmask 0xffffffff

Ergebnis:

root@r51 /home/fk #ifconfig gif0
gif0: flags=8051<UP,POINTOPOINT,RUNNING,MULTICAST> mtu 1280
        tunnel inet 192.168.2.49 --> 192.168.2.40
        inet6 fe80::211:25ff:fe2f:e89f%gif0 prefixlen 64 scopeid 0x5 
        inet 192.168.3.49 --> 192.168.3.40 netmask 0xffffffff

Gegenseitiges Anpingen der inneren Tunneladressen – 192.168.3.40 und 192.168.3.49 – zeigt, ob soweit alles geklappt hat und der Tunnel steht. Die getunnelte Kommunikation wird jedoch noch nicht verschlüsselt, ist daher auch nicht nennenswert sicherer geworden.

Für die Verschlüsselung ist der Kernel zuständig, dazu muss er über die beiden Zeilen:

options         IPSEC                   # IP security
options         IPSEC_ESP               # IP security (crypto; define w/ IPSEC)

verfügen. Für den Client, in meinem Fall der Laptop, sind keine weiteren Kerneländerungen von Nöten. Der Gateway-Kernel muss jedoch noch etwas ergänzt werden:

options IPFIREWALL
options IPDIVERT
options IPFIREWALL_DEFAULT_TO_ACCEPT
options IPFIREWALL_VERBOSE

Dadurch werden die Grundbedingungen geschaffen, um später NAT zu aktivieren.

Exkursion zu Sinn und Unsinn von Personal Firewalls

Noch ein paar Sätze zu den Firewall-Optionen: massenkompatible Medien nutzen gerne Viren und Würmer als Begründuing, Personal Firewalls zu hypen. Jeder Depp meint nun, mindestens mehrere davon zu brauchen. Anständig konfigurierte Rechner bleiben jedoch auch ohne Firewall sauber. Selbst Windows bietet, wenn es hinter einem NAT-Gateway steht, für die Außenwelt erstmal keine Angriffsfläche.

Um dies zu ändern ist erst wieder ein Dummbatz nötig, der mit einem zur Fernwartung einladenden Browser durch die Gegend surft, und brav jede Exe-Datei öffnet, die er per Mail bekommen hat. Ob sich dieser Mensch nun für seine Vireninstallation eine Ausnahme-Regel in der persönlichen Firewall festlegen muss oder nicht – solchen Menschen hilft auch eine Personal Firewall nicht weiter, der denkende Teil der Bevölkerung kommt sowieso ohne aus.

Ob man eine echte Firewall braucht, hängt von der Situation ab, mein Gateway kommt ohne aus, daher die obigen Einstellungen.

Die beiden Kernel können nun kompiliert, installiert und geladen werden.

Die Tunnel-Verschlüsselung wird vom Kernel vorgenommen. Die Regeln in /etc/ipsec.conf legen fest was zu verschlüsseln ist. Die gesamte Kommunikation über den Tunnel soll verschlüsselt stattfinden, die Regeln bestehen daher lediglich aus zwei Zeilen.

Die /etc/ipsec.conf des Clients bekommt den Inhalt:

spdadd 192.168.2.49/32 192.168.2.40/32 ipencap -P out ipsec esp/tunnel/192.168.2.49-192.168.2.40/require;
spdadd 192.168.2.40/32 192.168.2.49/32 ipencap -P in ipsec esp/tunnel/192.168.2.40-192.168.2.49/require;

Für die /etc/ipsec.conf des Gateways werden nur die IP-Adressen vertauscht:

spdadd 192.168.2.40/32 192.168.2.49/32 ipencap -P out ipsec esp/tunnel/192.168.2.40-192.168.2.49/require;
spdadd 192.168.2.49/32 192.168.2.40/32 ipencap -P in ipsec esp/tunnel/192.168.2.49-192.168.2.40/require;

setkey -f /etc/ipsec.conf muss auf beiden Rechnern ausgeführt werden, um dem Kernel die Regeln mitzuteilen.

Welche Pakete in kryptographische Behandlung müssen ist nun geklärt, es fehlt jedoch noch der anzuwendende Schlüssel. Hier kommt racoon ins Spiel, auf beiden Rechnern zu installieren aus /usr/ports/security/racoon.

Wenn versucht wird, verschlüsselt über den Tunnel zu kommunizieren, handeln die beiden racoon-Prozesse erst einen passenden Schlüssel aus, und geben ihn an den Kernel weiter. Auch die Verbindung zwischen den racoon-Prozessen muss natürlich verschlüsselt stattfinden, ansonsten wäre der ganze Aufwand umsonst. Dafür wird ein vorher ausgetauschter Schlüssel benötigt, der Pre Shared Key.

Dazu füllt man /usr/local/etc/racoon/psk.txt mit der IP-Adresse von gegenüber und einem passenden Schlüssel.

192.168.2.40			 mein-nun-nicht-mehr-geheimes-passwort

auf dem Client, und

192.168.2.49			 mein-nun-nicht-mehr-geheimes-passwort

auf dem Gateway.

Der Schlüssel darf nur von root lesbar sein, ansonsten wird er von racoon nicht anerkannt. Dafür sorgt:

chown root /usr/local/etc/racoon/psk.txt
chmod 0600 /usr/local/etc/racoon/psk.txt

Anschließend kann racoon auf beiden Rechner gestartet werden. Parameter müssen nicht übergeben werden, racoon reicht. Schreiben von racoon_enable="YES" in /etc/rc.conf auf beiden Rechnern lässt racoon bei jedem Hochfahren mitstarten.

Und wenn die /etc/rc.conf des Gateways noch ein paar weitere Zeilen bekommt, dann klappt's auch mit dem Routen:

gateway_enable="YES"
firewall_enable="YES"
firewall_type="OPEN"
natd_enable="YES"
natd_interface="rl0"
natd_flags=""

Der Laptop hat nun die Möglichkeit unverschlüsselt über den Access-Point oder verschlüsselt über den Server mit der Außenwelt zu kommunizieren. Welchen Weg er wählt, regelt die Default-Route, die je nach Bedarf angepasst werden kann.