VPN mit IPSec #

IPSec ist ein Protokoll zum Aufbau eines VirtualPrivateNetwork. Es dürfte im Moment die beste Wahl sein, wenn man ein VPN neu aufbaut, da es Teil des kommenden IPV6-Standards sein wird.

Free S/WAN #

Die am besten gepflegte Linux-Implementation von IPSec ist Free S/WAN. Dieses wird auch z.B. von Suse Linux benutzt und es gibt entsprechende Debian-Pakete. Aufgrund der Exportbeschränkungen der USA für Verschlüsselungstechnologien ist Free S/WAN nicht im Linux-Kernel und im normalen Debian-Baum integriert, sondern erfordert die Einbindung des non-us-Debian-Zweiges sowie eine Kernel-Kompilierung.

Installation #

Zur Zeit sind die dazu benötigten Debian-Pakete nur in der unstable-Distribution zu finden. Ich habe folgende Files einfach mit wget heruntergeladen und dann mit dpkg -i ... installiert:

Danach muss wie bei DebianKernelKompilieren beschrieben ein neuer Kernel gebaut werden. Wenn der mit Free S/WAN läuft, erkennt man das an entsprechenden Meldungen beim hochfahren.

Außerdem muss in der Datei /etc/network/options die Option "spoofprotect" auf "no" gesetzt werden. Sonst beschwert sich ipsec beim hochfahren, dass seine KLIPS-Komponente nicht mit Devices arbeitet, die "route filtering" eingeschaltet haben. (Da spoof protect an sich kein schlechter Gedanke ist, sollte man dieser Frage später nochmal nachgehen.)

Konfiguration #

Zuerstmal sollte hier gesagt werden, dass die Dokumentation auf der Webseite sehr ausführlich und umfangreich ist und eigentlich alles erklärt, wenn man nur weiss wo. Gerade weil sie so umfangreich ist, habe ich aber doch lange gebraucht, bis meine Konfiguration so stand, wie sie sollte.

Damit es nicht langweilig wird, habe ich hier einen Fall als Beispiel genommen, den es laut der offiziellen Dokumentation gar nicht gibt. :-)

  • Eine Verbindung zwischen zwei Rechnern mit fester IP-Adresse ist relativ schnell eingerichtet, wenn man das Grundprinzip verstanden hat. Wichtig im Vergleich zu anderen VPN-Systemen ist die Tatsache, daß nicht eine neue virtuelle Verbindung erzeugt wird, die an beiden Enden jeweils ein neues Interface hat, sondern das neue Interface ipsec0 hat die gleiche IP-Adresse wie das darunterliegende (z.B. ppp0). Die Entscheidung, was wodurch geroutet wird, fällt in der Routingtabelle bzw. im Kernel-Routingcode (den wir ja oben gepatcht haben).
  • Eine Verbindung, bei der ein Partner eine dynamische IP besitzt, nennt man "Road Warrior". Auch dieses Thema ist recht ausführlich behandelt. Dieser Fall wird in der Konfiguration daran erkannt, dass anstelle der IP-Adresse der Gegenstelle im Server "%any" steht.
  • Für uns arme T-Online-Flatrate-Kunden stellt sich jedoch noch eine ganz andere Frage: Was ist, wenn beide Partner dynamische Adressen haben? Wenn ich zwei Flatrate-Netze verbinden will oder wenn ich mit dem Laptop von unterwegs in meinen heimischen DSL-Rechner will?

Dieser letzte Fall wurde nirgendwo in den Dokus erwähnt. Trotzdem habe ich lange herumgespielt. Natürlich sollten beide Rechner erstmal per DynamischesDNS erreichbar sein. Innteressanterweise sind es gerade die Sicherheitsmerkmale der Authentifizierung, die zuerstmal die Definition einer einfachen Verbindung, die alle Widrigkeiten wie Verbindungsabbruch durch den Provider übersteht, unmöglich machen. Eine Authentifizierung, die sich auf eine vorhandene Verbindung bezieht, aber auf einmal von einer anderen IP-Adresse kommt, wird geflissentlich ignoriert. :-( Dann habe ich es doch geschafft: Man konfiguriert einfach zwei spiegelbildliche Road-Warrior-Verbindungen. Interessanterweise gibt es kein Problem, weil ja nun zwei Tunnel die gleichen Adressbereiche routen wollen. Es funktioniert!

Schlüssel erzeugen #

Grundsätzlich gibt es verschiedene Verfahren der Verschlüsselung, die benutzt werden können. Die Verwendung eines gemeinsamen Schlüssels ist nicht zu empfehlen, da dieser immer gleich bleibt und dadurch ein Angreifer, der ihn irgendwie erbeutet, den gesamten Datenverkehr der Zukunft und auch der Vergangenheit (wenn er ihn protokolliert hat) entschlüsseln kann. Besser ist da das autokeying-Verfahren. Hier wird der Partner mit einem RSA-Schlüssel (RSA arbeitet mit einem öffentlichen und einem privaten Schlüssel) authentifiziert. Der eigentliche Schlüssel für den Datenstrom wird jedoch regelmässig automatisch ausgetauscht. Als dritte Variante gibt es als Patch noch die Verwendung von X.509-Zertifikaten, die die Bildung einer Trust-Organisation erlauben (letztlich werden auch RSA-Schlüssel benutzt). Da dies für meine Anwendung mit Kanonen auf Spatzen geschossen schien, habe ich mich für RSA-Authentifizierung entschieden.

Bei der Installation des Debian-Paketes fragt das Installationsskript, ob ich X.509- oder RSA-Schlüssel erzeugen möchte. Hier wähle ich RSA-Schlüssel. Damit ist schon der erste Schritt getan. Der Schlüssel meines Rechners wird nun in der Datei /etc/ipsec.secrets erzeugt. Mit dem Befehl ipsec showhostkey --left >hostkey.txt (oder right) extrahiere ich ihn in eine Datei. Dabei sollte man auf einem Rechner der Verbindung left und auf dem anderen right angeben. Dadurch wird eine Zeile erzeugt, die direkt in die ipsec.conf eingefügt wird.

Konfigurationsdatei /etc/ipsec.conf #

Diese Datei enthält alle Angaben, um IPSec zu konfigurieren. Sie ist in Sektionen eingeteilt. Die erste Sektion config setup enthält globale Einstellungen. Sie sieht bei mir so aus:

   config setup
        # THIS SETTING MUST BE CORRECT or almost nothing will work;
        # %defaultroute is okay for most simple cases.
        interfaces=%defaultroute
        # Debug-logging controls:  "none" for (almost) none, "all" for lots.
        klipsdebug=none
        plutodebug=none
        # Use auto= parameters in conn descriptions to control startup actions.
        plutoload=%search
        plutostart=%search
        # Close down old connection when new one using same ID shows up.
        uniqueids=yes

Diese Einstellungen sollten eigentlich für alle normalen Anwendungen reichen. Falls der Tunnel nicht auf dem Interface liegen soll, das das Default-Gateway (zum Internet) ist, kann die Zeile interfaces="ipsec0=eth0" oder ähnlich verändert werden.

Jede Verbindung hat nun eine eigene Connect-Sektion. Enthält diese einen Eintrag auto=add oder auto=start, so wird diese Verbindung beim hochfahren automatisch für den Empfang konfiguriert bzw. sogar aufgebaut. Durch das Schlüsselwort also=<sektionsname> kann eine andere Sektion "eingebunden" werden. Dies nutze ich in meinem Beispiel aus. In der Datei ist immer von "left" und "right" die Rede. Damit bezieht man sich auf die beiden Enden der Verbindung. Ob der Rechner left oder right ist, stellt freeswan selber anhand der Daten fest.

"linker" Rechner

  conn rw-pommes
        # Parameter, wenn der lug-Router die Verbindung initiiert
        also=lug-pommes
        left=%defaultroute
        right=lug2.dyndns.org
        keyingtries=0
        auto=start
  conn lug-rw
        # Parameter, wenn Pommes die Verbindung initiiert
        also=lug-pommes
        left=%defaultroute
        right=%any
        keyingtries=1
        auto=add
  conn lug-pommes
        # Parameter, die fuer beide Verbindungen auf beiden Rechnern gleich sind:
        leftsubnet=192.168.1.0/24
        leftid=@lugwall.lug.loc
        # RSA 1024 bits   lugwall   Sun Apr 14 19:36:19 2002
        leftrsasigkey=0sA...........
        rightsubnet=192.168.2.0/24
        rightid=@router.pommes.loc
        # RSA 1024 bits   router   Tue Apr  9 13:51:41 2002
        rightrsasigkey=0sA...........

Nun die Unterschiede für den "rechten" Rechner:

  conn rw-pommes
        left=%any
        right=%defaultroute
        keyingtries=1
        auto=add
  conn lug-rw
        left=lug1.dyndns.org
        right=%defaultroute
        keyingtries=0
        auto=start

Damit findet jeder der beiden Rechner jeweils den anderen und baut eine Verbindung auf. Die angegebene ID wird dabei als "Username" benutzt und der Schlüssel, den wir oben erzeugt haben, als Passwort. Wenn start durch add ersetzt wird, baut sich die Verbindung nicht immer automatisch auf. Dann kann z.B. mit ipsec auto --up rw-pommes die Verbindung hochgefahren werden. Fertig!

Falls der Tunnel automatisch hochgefahren werden soll, sollte man dann allerdings noch folgendes nach /etc/ppp/ip-up.d/5ipsec schreiben:

  #!/bin/bash
  /etc/init.d/ipsec start

Besonderheiten #

Zu sagen ist noch, daß nur das Routing zwischen den beiden lokalen Netzen verschlüsselt wird. Pakete, die von einem der beiden Gateway-Rechner kommen, werden nicht geroutet, da sie als Absendeadresse Ihre dynamische IP benutzen (und nicht Ihre IP im lokalen Netz). Zugriff auf das Gateway vom jeweils anderen Netz ist jedoch möglich, da dafür dann das Interface im lokalen Netz benutzt werden kann, ansonsten muss man die IP-Adresse des öffentlichen Interfaces nehmen (also den Namen für DynamischesDNS). Wie das z.B. mit einem Laptop geht, der kein lokales Netz hat, bleibt noch zu erforschen...

Shorewall-Konfiguration #

In der ShoreWall-Firewall habe ich folgende Änderungen vorgenommen. Dabei habe ich dafür gesorgt, daß das entfernte Netz nicht Teil meiner lokalen Zone wird, sondern eine eigene Zone bekommt. Dadurch hat der eingewählte Rechner nicht Zugang zu meinem ganzen Netz. Selbst wenn ich meinem Partner traue: Schliesslich weiss ich nicht, was für Viren sich derjenige eingefangen hat.

/etc/shorewall/zones

 dmz DMZ    Demilitarisierte Zone/VPN-Netz 

/etc/shorewall/interfaces

 dmz ipsec0  192.168.5.255  dropunclean

/etc/shorewall/policy

 dmz all DROP info
 all dmz DROP info

/etc/shorewall/rules

 ACCEPT loc dmz tcp www,ssh
 #...ggf weitere Dienste freigeben

(Auf der anderen Seite natürlich mit entsprechenden Netzwerkadressen) Damit sollte die Firewall dann laufen und nur noch das durchlassen, was wir wollen. Schliesslich soll unsere Tunnel-Gegenstation ja nicht kompletten Zugang in unser Netz haben.

-- ThomasBayen

Tags:  VPN, Netzwerk

Add new attachment

Only authorized users are allowed to upload new attachments.
« This page (revision-4) was last changed on 25-Jan-2008 08:52 by ThomasBayen