Linux VPN-Gateway für iOS

Nachdem ich schon eine Weile darüber nachgedacht habe die VPN-Funktion meines IPod Touch mal zu testen bin ich nun endlich dazu gekommen ein entsprechendes VPN-Gateway auf Basis von Debian Lenny zu basteln. Das Setup ist sicherlich noch nicht produktionsreif, aber es funktioniert stabil. Ich konnte es mit einem IPod Touch Firmware 2.x und 3.x sowie mit einem IPhone und IPhone 3G, ebenfalls mit Firmware 2.x und 3.x, erfolgreich testen. HINWEIS: Es kommen hier keine Filter zum Einsatz. Der Betrieb des GW, wie hier beschrieben, ist nicht sicher.  Siehe auch den Hinweis von Michael Bürkle am Ende des Posts. Ich habe die Filter-Thematik in diesem Artikel bewusst nicht behandelt, um nicht vom 100ten ins 1000ste zu kommen, aber bisher nicht konkret darauf hingewiesen.

System vorbereiten

Als Basis verwende ich, wie für alle meine Setups, ein Debian. In diesem Fall in der aktuellen Version Lenny. Ich habe mich für die l2tp-(over-ipsec)-Version des VPNs entschieden. PPTP ist nicht mehr zeitgemäß und das native IPSec VPN der Apple-Geräte ist nach meinem Gefühl eher für einen sicheren Zugang zur Infrastruktur (z.B. Campus-WLAN) denn für einen Remote-VPN-Zugang gedacht. So ist z.B. die Verwendung von XAUTH zur Authentifizierung zwingend. Es ist mir nicht gelungen unter Verwendung des reinen IPSec-Modus eine stabile und brauchbare Verbindung aufzubauen. Daher meine Entscheidung für l2tp. Folgende Pakete musste ich nach einer Installation des Standard-Systems nachinstallieren.

Openswan ist für den IPSec-Teil der Verbindung notwendig während der xl2tpd den l2tp-Dämon stellt. Das PPP-Paket ist auch noch notwendig wurde aber bei meiner Installation bereits von obigem Kommando als Abhängigkeit angezogen bzw. war schon vorher bei der Standardsystem-Installation installiert.

Konfiguration IPSec

Zuerst wenden wir uns der Konfiguration des ipsec zu. Die Authentisierung des IPSec erfolgt über ein “Shared Secret”. Dieses ist für alle Geräte, die das VPN verwenden gleich. Es dient zum Aufbau des IPSec-Tunnels durch welchen dann später die l2tp-Verbindung getunnelt wird. Da der Remote-Peer hier mit der Adresse 0.0.0.0 (any) konfiguriert wird – da die Gegenstelle ja wegen dynamischer Adressvergabe über UMTS oder DLS nicht bekannt ist – kann keine weitere Verbindung mir einer “Shared Secret”-basiterten Authentisierung konfiguriert werden. Zertifikatsbasierte Verbindungen sind davon nicht betroffen und können auf dem selben Gateway parallel betrieben werden. Es folgen meine Connection-Beschreibung für die Datei /etc/ipsec.conf. Wenn es eine frische IPSec-Installation ist, dann kann die Verbindung direkt unterhalb des Kommentars “# Add connections here” in der ipsec.conf eingetragen werden. Weitere Parameter für die Datei ipsec.conf können der Man-Page entnommen werden. Diese kann auf dem System mit “man ipsec.conf” aufgerufen werden. Oder sie findet sich hier.

Anschliessend muss noch in der Datei /etc/ipsec.secrets folgende Eintrag gesetzt werden. Dabei muss der Platzhalter “gateway.external.ip” durch die externe IP des VPN-Gateways ersetzt werden.

Nach einem Neustart des IPSec Subsystems ist damit die Konfiguration des IPSec-Teils abgeschlossen. Also wenden wir uns dem l2tp-Part des Setups zu.

Konfiguration L2TP

Die Konfiguration des l2tp-Dämons findet in der Datei “/etc/xl2tpd/xl2tpd.conf” statt. Es folgt meine Version dieser Datei. In der Sektion “global” werde allgemeine Parameter beschrieben. Hier muss wiederrum der Platzhalter “gateway.external.ip” durch die externe IP des VPN-Gateways ersetzt werden. Mit dem Port-Parameter kann der Listen-Port definiert werden. Da auf dem IPhone keine abweichende Konfiguration des Ports möglich ist muss hier der Defaul für l2tp beibehalten werden. Weitere Parameter können sind in der Man-Page des xl2tpd beschrieben. Diese kann auf dem System mit “man xl2tpd.conf” aurgerufen werden. Oder sie findet sich hier.

In der folgenden Sektion wird die eigentliche Verbindung beschrieben. Natürlich können die Parameter “ip range” und “local ip” angepasst werden. Wichtig ist hier, dass der Parameter “local ip” aus dem selben Netz-Segment ist, wie die IP-Range. Der Parameter “local ip” beschreibt die Adresse die das PPP-Interface in Richtung Clients auf dem VPN-Gateway haben wird. Der Parameter hat nichts mit der externen IP des Gateways zu tun, die wir weiter oben bereits gesetzt haben. Der Parameter “IP-Range” beschreib den Adress-Bereich aus dem den Clients IP-Adressen zugewiesen werden. Es ist auch möglich bestimmten Usern feste IP-Adressen zuzuweisen, dazu später mehr. Hier die von mir im Test verwendete Konfiguration:

Routing Exkursion

An dieser Stelle möchte ich noch auf eine Problematik eingehen, die im Rahmen der VPN-Nutzung bei den meisten Administratoren entstehen wird. Im Grunde ist das l2tp-Konzept darauf ausgelegt Adressen aus dem selben Adress-Bereich, der auch im internen LAN verwendet wird, zu tunneln. Dazu kommen dann z.B. Techniken wie Proxy-Arp zum Einsatz. In gösseren Installation ist ein solches Konzept unpraktisch und es wäre wünschenswert die Clients bzw. das für die Clients gedachte Subnetz stattdessen über Routing einzubinden. Das ist natürlich auch möglich aber es gibt dabei einiges zu beachten. Da auf dem IPhone/IPod ohne weiteres keine Routen für die l2tp-Verbindung definiert werden können gibt es nur zwei Möglichkeiten ein solches Setup zu realisieren. Zum einen kann auf dem IPod/IPhone bei der Einrichtung des VPN der Schalter “Für alle Daten” zu aktivieren. Dann setzt der Client eine Default-Route durch das VPN wenn dieses aktiv ist. D.h. es werden alle Daten zu VPN-Gateway gesendet. Das hat allerdings den Nebeneffekt, dass bei aktivem VPN auch alle Anfragen zu Webseiten oder z.B. dem I-Tunes Store über das VPN zum Firmennetz geleitet werden. Auch ist es dann notwendig dem Client einen internen DNS-Server mitzugeben, damit noch eine erfolgreichen Namesauflösung erfolgen kann. Dies ist im Rahmen des PPP-Verbindungsaufbau möglich. Mehr dazu später. Generell ist es mit entsprechender Freischaltung in der ggf. existierenden Firewall und einem richtig konfigurierten, internen DNS ohne Probleme möglich mit dem Client auch über die VPN-Verbindung zu surfen oder bei I-Tunes oder im App-Store einzukaufen. Allerdings leidet die Geschwindigkeit der Verbindung etwas darunter. Der Vorteil ist, dass alle Zugriff, auch auf alle privaten Netze nach RFC1918, beim VPN-Gateway ankommen und dort entsprechend geroutet bzw. gefilter oder überwacht werden können.

Ist der Schalter “Für alle Daten” nicht gesetzt sendet das IPhone nur manche Anfragen in den VPN-Tunnel. So gehen z.B. alle Anfragen an öffentliche IP-Adressen am VPN vorbei direkt über die entsprechende Anbindung. Leider werden dann auch nicht alle Anfragen an RFC1918 Netze, sonder nur eine Submenge, über das VPN geroutet. Soweit ich es bisher testen konnte wird jeweils der komplette RFC1918 Netzblock aus dem die Adressen im Parameter “ip range” stammen durch das Tunnel gesendet. Also bei meinem Beispiel der komplette 10.0.0.0/8 Block, nicht aber z.B. der Bereich 192.168.0.0/16 oder 172.16.0.0/12. Kommen im Firmennetz also mehrere RFC1918 Netzbereiche zum Einsatz kann das ein Problem darstellen.

Konfiguration PPP

So, jetzt aber genug der Routing-Exkursion. Um ein lauffähiges Setup zu bekommen muss noch der PPP-Bereich entsprechend konfiguriert werden. Im oben besprochenen Abschnitt der l2tp-Verbindung finden wir einen Verweis auf die folgenden Konfigurationsdatei “/etc/ppp/options.l2tpd”. Diese Datei enthält die notwendigen Parameter für den pppd der sich um den Aufbau der Verbindung, die Authentifizierung und die Zuweisung von IP-Adressen und z.B. DNS oder WINS Server kümmert. Bei mir sieht der Inhalt der Datei wie folgt aus:

Der pppd bietet eine Fülle an Optionen zur Konfiguration. Daher möchte ich nur auf die wichtigstens kurz eingehen. Weitere Optionen sind in der Man-Page des pppd beschriebe. Diese kann auf dem System mit “man pppd” aufgerufen werden. Oder man findet sie hier. Ich möchte auch noch sagen, dass ich wahrlich kein PPP-Spezialist bin und diese Settings auch aus dem Link im Anhang übernommen habe. Mit diesen Einstellungen war in meinen Tests ein stabiler Betrieb möglich. Ob die immer das Gelbe vom Ei sind kann ich allerdings nicht garantieren.

Wichtig waren bei mir die Einstellungen “mtu” und “mru”. Wenn diese nicht bzw. auf einen zu hohen Wert gesetzt sind, dann hatte ich über UMTS Probleme bei der Verbindung. Das äussert sich dahingehend, dass beim Abruf von z.B. Bildern in Webseiten die Verbindung einfach hängen bleibt. Mit den Werten “1410” habe ich sowohl über UMTS als auch über WLAN keine Probleme mehr gehabt. Der “idle”-Parameter beschreibt, nach welcher Zeit eine VPN-Verbindung über die keine Daten übertragen werden getrennt wird. Ich habe mich hier für 1800 Sekunden entschieden. Ohne diese Option hatte ich manchmal Probleme das VPN von einem IPod Touch wieder aufzubauen, nachdem dieser in den Standby-Modus gefallen war. Dieser Parameter kann sicherlich nach eigenen Anforderungen angepasst werden. Spannend ist dann noch der Parameter “ms-dns”. Damit kann dem Client ein DNS-Server zugewiesen werden, der während der aktiven VPN-Verbindung gilt. Die Option kann auch zwei mal gesetzt werden um einen Primären und eine Sekundären DNS-Server zu definieren. Bitte hierbei beachten, dass der DNS-Server auch externe Adressen auflösen muss, da sonst während einer aktiven VPN-Verbindung kein Zugriff auf normale Webseiten oder I-Tunes bzw. App-Store möglich ist. Siehe dazu auch den Abschnitt “Routing Exkursion” weiter oben. Der Vollständigkeit halber sei noch erwähnt, dass es auch den Parameter “ms-wins” gibt, mit dem Wins-Server definiert werden können. Bei IPhone und IPod scheint das keinen Effekt zu haben. Aber wer auf Windows als Client anbinden möchte kann die Option ggf. gut gebrauchen. Der Parameter “auth” legt fest, dass ein User sich zum Aufbau einer L2TP-Verbindung authentifizieren muss. Weiter oben haben wir in der xl2tpd.conf durch die Parameter “require chap = yes” und “refuse pap = yes” bereits definiert, dass eine Authentifizierung via CHAP stattfinden muss. Somit kommen wir auch zum letzten Schritt der Konfiguration indem wir die Username und Passwörter der Accounts sowie die zuzuweisende IP-Adresse festlegen.

Dies geschieht in der Datei “/etc/ppp/chap-secrets”. Hier ein Beispiel mit einigen Accounts, dass ich in meinem Test verwendet habe:

Ich denke Inhalt und Syntax der Datei ist selbsterklärend. Ich habe noch nicht getestet wie es sich auswirkt, wenn dort z.B. auch ein DSL-Account (vie PPPoE) oder andere PPP-Accounts konfiguriert sind. Solange dort nur die Accounts für das VPN eingetragen sind klappt es jedenfalls ohne Probleme. Der Client bekommt die in der letzten Spalte zugewiesene IP-Adresse und kann auch anhand dieser z.B. in einer Firewall gefilter werden.

Konfiguration auf IPhone oder IPod-Touch

Auf dem Client wird das VPN dann wie folgt konfiguriert.

  • Im Hauptmenü “Einstellungen” wählen.
  • Unter “Einstellungen” –> “Allgemein” wählen.
  • Unter “Allgemein” –> “Netzwerk” wählen.
  • Unter “Netzwerk” –> “VPN” wählen
  • Dann auf “VPN hinzufügen” klicken

Dann öffnet sich der folgende Dialog indem einige Parameter zum VPN eingetragen werden müssen:

IPod Touch VPN Dialog
IPod Touch VPN Dialog

Die “Beschreibung” kann frei gewählt werden und sollte das VPN sprechend beschreiben. Bei “Server” wird entweder die numerische IP oder der DNS-Name des VPN-Gateway eingetragen. In unserem Beispiel ist das “gateway.external.ip” wie bereits oben in den Abschnitten “Konfiguration IPSec” und “Konfiguration L2TP” besprochen. In das Feld “Account” wird der Username aus der Datei “chap-secrets” (siehe PPP-Abschnitt) eingetragen. Der Schalter “RSA-SecureID” hat in meinem Setup keine Funktion und muss ausgeschaltet sein. In das Feld “Kennwort” wird das zum Username korrespondierende Kennwort aus der Datei “chap-secrets” eingetragen. Es ist auch möglich das Kennwort bei jeder Verbindung direkt einzugeben und nicht auf dem Gerät zu hinterlegen, was der Sicherheit ohne Frage zuträglich ist. Wenn das gewünscht ist kann das Feld mit dem Default-Wert “Jedes mal Fragen” belassen werden. In das Feld “Shared Secret” muss das gemeinsame Kennwort für die IPSec Verbindung aus der Datei “ipsec.secrets” (siehe Abschnitt Konfiguration IPSec”) eingetragen werden. Dieses Kennwort ist, wie oben schon besprochen, für alle Clients gleich. Ob der Schalter “Für alle Daten” bei in Ihrem Setup gesetzt ist oder nicht müssen Sie selber entscheiden. Informationen zu den Auswirkungen der einen oder anderen Möglichkeit finden Sie im Abschnitt “Routing Exkursion”.

Wenn jetzt alle Paramter entsprechende gesetzt, das Gateway fertig konfiguriert und alle Dienste neu gestartet worden sind können wir den Aufbau des VPNs versuchen. Das geht entweder direkt unter “Einstellungen” -> “VPN” oder aber im VPN-Menü wo wir gerade auch die Verbindung konfiguriert haben. Wenn alles gut geht, dann sieht es wie folgt aus:

Etablierte VPN-Verbindung IPod Touch
Etablierte VPN-Verbindung IPod Touch

Durch ankicken der “Status-Zeile” können noch weitere Details abgerufen werden:

VPN Details IPod Touch
VPN Details IPod Touch

Troubleshooting

Fehlt noch, werde ich die Tage nachreichen

Weitere Infos, Links und Todos

Einen Teil der Informationen und Konfigurationen in diesem Artikel habe ich hier gefunden. Die Seite geht auch wesentlich tiefer ins Detail und deckt eine größere Menge an Clients ab. So z.B. auch Windows-Client, Mac OSX (auf Desktop oder Laptop) und diverse Software VPN-Clients. Es ist in jedem Fall ratsam einen Blick auf die Seite zu werfen. Dennoch musst ich Anpassungen im IPSec-Bereich vornehmen um mit IPod und IPhone als Client zu einer stabilen Verbindung zu kommen.

Wie im Eingang des Artikels schon erwähnt funktioniert das Setup so wie hier beschrieben stabil. Allerdings gibt es schon noch ein paar Dinge die ich selber für Verbesserungswürdig halte. So muss der l2tp-Dämon im Moment auf dem externen Interface des VPN-Gateway für any freigeschaltet sein. Es wäre natürlich schön das nur zu erlauben, wenn der Client bereits erfolgreich eine IPSec-Verbindung aufgebaut hat. Openswan bietet auch die notwendigen Mechanismen das im Zusammenspiel mit iptables zu realisieren. Ich bin nur noch nicht dazu gekommen das entsprechend umzusetzen. Auch sollten die Optionen der ipsec.conf, xl2tp und pppd-Konfig nochmal auf Sinnhaftigkeit und Sicherheit überprüft werden bevor man mit einem solchen Setup in Produktion geht.

Folgender Beitrag von Michael Bürkle, vielen Dank dafür:

Die letzten drei Tage habe ich mich damit beschäftigt ein entsprechendes Setup bei mir vorzunehmen. Dabei bin ich mit der Beschreibung auf deiner Seite gestartet und habe mich dann durch die Anleitung auf http://www.jacco2.dds.nl/networking/freeswan-l2tp.html, die von dir verlinkt wird, durchgearbeitet.

Anschliessend hat zwar der IPSEC Verbindungsaufbau funktioniert, aber der Verbindungsaufbau zum xl2tpd ist jedesmal gescheitert.

Den entscheidenden Hinweis habe ich auf dieser Seite gefunden:

http://rootmanager.com/ubuntu-ipsec-l2tp-windows-domain-auth/setting-up-openswan-xl2tpd-with-native-windows-clients.html

In den iptables Regeln musste noch folgende Regel eingefügt werden:
-A INPUT -m policy –dir in –pol ipsec -p udp –dport 1701 -j ACCEPT

Dadurch werden Pakete am xl2tpd akzeptiert die in ipsec Paketen ankommen.

Warum ich dir das schreibe:
Das Setup, welches von dir beschrieben wird, erlaubt ankommende Pakete an Port 1701 auf dem externen Interface. Davon wird stark abgeraten, denn die Pakete sind nicht verschlüsselt wenn sie tatsächlich über dieses Interface eintreffen. Dieser Port sollte nach aussen hin also geblockt sein.

Vielleicht findest du die Zeit dein ansonsten schön gemachtes Tutorial zu überarbeiten und damit noch besser für zukünftige Hilfe suchende zu machen.

Leave a Reply