Eine große Anzahl Soft- und Hardware-Lösungen wetteifern darum, Firmenstandorte oder Wohngemeinschaften zu “Virtual Private Networks” (VPNs) zusammenzuschließen. Doch wer nur über einen schmalen Geldbeutel verfügt und mit geringem Konfigurationsaufwand und ohne Kernelpatchen über die Runden kommen möchte, muss etwas länger suchen.
Ob Projekt mit überall auf der Welt sitzenden Mitarbeitern, virtuelle Firma oder Pärchen mit getrennten Wohnorten – seit das Internet es möglich macht, von überall her auf gemeinsame Rechner zuzugreifen, liegt die Idee eines virtuellen lokalen Netzwerks nahe: Nicht mehr die räumliche Nähe einer Büro- oder Wohngemeinschaft bestimmt die Grenzen des LANs, sondern die Zugehörigkeit zu einem Team. Doch solche “lokalen” Netze, bei denen das Internet die Aufgabe des Netzwerkkabels übernimmt, müssen abgesichert werden, damit die darüber übertragenen Daten tatsächlich privat bleiben. Das geht mit Hilfe eines Tunnels: Vom Internet aus ist nur die äußere Tunnelhülle sichtbar, die darin fließenden Daten bekommen lediglich die Rechner an den Endpunkten desselben zu Gesicht.
Mit vpn-pppssh von [1] oder der Heft-CD existiert eine skriptbasierte Möglichkeit, ein solches virtuelles privates Netzwerk (VPN) aufzusetzen. Ihr Vorteil: Sie verwendet ausschließlich Software, die ohnehin auf jedem Linux-Rechner vorhanden ist. Eine einzige Befehlszeile im Skript reicht aus, um den VPN-Tunnel aufzubauen. Der restliche Code sorgt für etwas Komfort und das richtige Routing der Datenpakete.
Für die zuverlässige Verschlüsselung der Daten auf dem Weg durch’s Internet sorgt die auf Seite 81 ff. vorgestellte Secure Shell ssh[2]; das “Point-to-Point-Protokoll” PPP sorgt dafür, dass alle möglichen Netzwerk-Basis-Protokolle wie TCP, UDP, ICMP und sogar IPX den VPN-Tunnel passieren können (vgl. Kasten 1).
Kasten 1: Die TCP/IP-Protokollfamilie
Damit sich Rechner untereinander verständigen können, braucht es Regeln, die besagen, wie Daten ausgetauscht werden: Welcher Rechner fragt wie an, ob er Daten abliefern darf, wie antwortet der andere darauf, in welcher Art gehen die Daten von A nach B, und wie erkennt Rechner B, dass Rechner A alles übertragen hat, was er übertragen wollte? Diese Regeln nennt man Protokolle, vergleichbar den Absprachen beim diplomatischen Protokoll.
Sämtliche Kommunikation im Internet basiert auf der TCP/IP-Protokoll-Suite. Das grundlegende “Internet-Protokoll” zeichnet für die Weiterleitung der Daten verantwortlich. Es ermittelt die Route, auf der alle Pakete verschickt werden, und zerlegt große Datenpakete in kleinere Teile. Da sich IP nicht darum kümmert, ob diese den Empfänger auch erreichen, gibt es Erweiterungen, die eine Kontrollstruktur zur Verfügung stellen: Nach dem “Transmission Control Protocol” sendet der Rechner ein Paket so lange, bis eine Bestätigung vom Empfänger eintrifft, die die Übertragung des unversehrten Pakets bestätigt. Diese Sicherheit bezahlt man mit einem nicht immer zu vernachlässigenden Overhead.
UDP (“User Datagram Protocol”) ist ein minimalistisches Protokoll, welches ebenfalls auf IP aufsetzt, aber keine Kontrollstrukturen enthält. Es kommt bei Internet-Diensten zum Einsatz, bei denen es weniger wichtig ist, dass alle Pakete ankommen, dafür aber auf eine schnelle, schlanke Übertragung gewünscht wird, zum Beispiel beim Streaming. Das “Internet Control Message Protocol” ICMP dient zum Austausch von Verwaltungsnachrichten zwischen allen am Datentransport beteiligten Stellen. Dessen bekannteste Anwendung ist das ping-Kommando.
Nichts mit TCP/IP zu tun hat das “Internetwork Packet Exchange”-Protokoll IPX. Es sorgt für die Adressierung und das Routing von Paketen innerhalb und zwischen LANs und wurde inzwischen fast vollständig von Protokollen aus der TCP/IP-Familie verdrängt.
Trotz ihrer Einfachheit beschränkt sich diese Lösung nicht darauf, zwei Standorte miteinander zu verbinden. Mit etwas Zusatzaufwand lassen sich auch zwei oder drei Einzelnetzwerke oder Rechner zu einem großen virtuellen Netz zusammenschließen.
Natürlich hat solch eine Simpelstlösung auch Nachteile. So “repariert” sich die Verbindung nach einem unerwarteten Verbindungsabbruch nicht automatisch. Auch liegt die erreichbare Datenrate unterhalb des bei einer DSL-Verbindung zu erwartenden Werts: Jedes ins andere Teilnetz übertragene Datenpaket wird in ein anderes Datenpaket eingepackt, was den Overhead erhöht. Daher sollte man mit dieser doch sehr einfachen Methode nicht allzuviele Netze verbinden: Mit jedem weiteren Knoten sinkt die Zuverlässigkeit der Verbindung, und ab einer bestimmten Grenze nehmen die Verbindungsabbrüche derart überhand, dass das VPN kaum noch ernsthaft benutzbar bleibt.
Das Szenario
Ob Sie jetzt zwei Wohngemeinschaften mit internem Netzwerk, Windows- und Linux-Rechnern sowie einem DSL-Zugang ins Internet verbinden, das Wort “Wohngemeinschaft” gegen “Firmensitz” oder ähnliches ersetzen, ist dabei in der Praxis egal: Es kommt nur auf die Technik an.
Der leistungsfähigere Gateway-Rechner übernimmt dabei die Aufgabe des Servers am Tunnelende, der leistungsschwächere bekommt die Rolle des Client zugeteilt. In unserem in Abbildung 1 skizzierten Beispiel zweier WGs hat der Rechner in Haus 2 einen besseren Prozessor als die Gegenstelle in Haus 5, womit die Rollenverteilung fest steht: Haus 2 hostet den Server.
vpn-pppssh als Shell-Skript ruft einige Programme auf, die zusätzlich installiert sein müssen. Dazu gehört besagte Secure Shell, die den Datentunnel aufbaut und für die verschlüsselte Übertragung der Pakete durch’s Internet sorgt. Als Transportprogramm kommt der pppd zum Einsatz. Sowohl das SSH-Paket, als auch der PPP-Daemon müssen auf beiden Rechnern am Tunnel installiert sein, damit eine Kommunikation mit dem jeweils anderen Ende des Tunnels zustande kommt.
Um auf dem Server für ein Mindestmaß an Sicherheit gegenüber der angeschlossenen Clients zu sorgen, sollten VPN-Anforderungen von einem eigens dafür zuständigen System-Account ohne besondere Privilegien bearbeitet werden. Doch auch wenn sich das auf dem Client noch abzulegende VPN-Skript auf dem Server nicht als root anmeldet, benötigen einzelne, nach dem Login gestartete Prozesse (namentlich der pppd) doch Superuser-Berechtigungen. Aus dieser Zwickmühle hilft das Programm sudo. Sind ssh und pppd auf beiden Maschinen und auf dem Server, also dem Internet-Gateway-Rechner in Haus 2, zusätzlich noch sudo installiert, geht es an die Konfiguration des VPNs.
Arbeitstier
Den unprivilegierten User vpn, in dessen Namen sich das VPN-Skript auf dem Server einloggt, erzeugt man als root auf dem Server mit folgendem Kommandozeilen-Befehl:
adduser --system --shell /bin/bash --gecos "VPN Account" --disabled-password --group vpn
Damit vpn den pppd im Skript per sudo aufrufen darf, muss der Server-Sysadmin aus Haus 2 dies in der sudo-Konfigurationsdatei /etc/sudoers extra erlauben. Diese Datei editiert er mit dem Befehl visudo. Durch diesen Aufruf startet der in der Umgebungsvariablen EDITOR oder VISUAL festgelegte Texteditor. Sehr wahrscheinlich ist dies der vi. Ihn schaltet man ggf. mit der Taste [i] in den Einfügemodus, schreibt die beiden folgenden Zeilen hinein, und beendet ihn anschließend mit [Esc] :wq:
vpn ALL=NOPASSWD:/usr/sbin/pppd vpn ALL=NOPASSWD:/sbin/route
Die zweite Zeile erlaubt es vpn, mit Hilfe des Programms /sbin/route die Routing-Tabelle zu ändern.
Müsste man bei jedem Verbindungsaufbau zum Server das Login-Passwort für vpn von Hand eingeben, ginge das am Ziel des automatisierten VPN-Aufbaus vollkommen vorbei. Deswegen kommt statt der Passwortabfrage eine alternative Möglichkeit der Authentifizierung zur Anwendung, das Public-Key-Verfahren der Secure Shell. Versucht sich der Client auf dem Server einzuloggen, nimmt der dortige Secure-Shell-Daemonsshd den auf dem Server-Rechner hinterlegten öffentlichen Key des Clients. Damit verschlüsselt er eine kurze Nachricht und schickt sie an den Client zurück. Passt der auf dem Server abgelegte öffentliche Schlüssel zum privaten Key des Clients, ist dieser in der Lage, die “Challenge”-Nachricht (“Herausforderung”) zu dechiffrieren. Er schickt dem Server einen Beleg dafür, worauf dieser einen kontrollierten, aber automatischen Login gestattet.
Liegt auf dem Client bislang kein Schlüsselpaar in den Dateien /root/.ssh/id_dsa und /root/.ssh/id_dsa.pub vor, muss eines mit dem Befehl ssh-keygen erzeugt werden (Listing 1). Der Parameter -t dsa legt die Verschlüsselungsmethode auf DSA fest. Auf die Frage nach der Passphrase antwortet man mit einem beherzten [Enter] nicht – sonst wäre bei jedem Verbindungsaufbau doch wieder ein Passwort fällig.
Listing 1
Generieren eines SSH-Schlüssels
client:~# ssh-keygen -t dsa Generating public/private dsa key pair. Enter file in which to save the key (/root/.ssh/id_dsa): Enter passphrase (empty for no passphrase): [Enter] Enter same passphrase again: [Enter] Your identification has been saved in /root/.ssh/id_dsa. Your public key has been saved in /root/.ssh/id_dsa.pub.
Der öffentliche Schlüssel des gerade auf dem Client erzeugten Schlüsselpaares muss nun in den Schlüsselkatalog des Systemkontos vpn auf dem Server gebracht werden. Anders als zu erwarten, geht das nicht einfach durch Umkopieren der Datei /root/.ssh/id_dsa.pub vom Client nach /home/vpn/.ssh/authorized_keys auf dem Server!
In authorized_keys befinden sich unter Umständen sehr viele öffentliche Schlüssel anderer Rechner, dann nämlich, wenn ein Login per SSH-Public-Key-Verfahren von mehreren Rechnern aus erwünscht ist. Deswegen sollte man die Datei id_dsa.pub mit dem neu aufzunehmenden Schlüssel grundsätzlich zuerst auf den Server übertragen (hier bietet sich scp, ein USB-Stick oder auch eine Diskette an), um ihren Inhalt anschließend mittels cat an die Datei authorized_keys anzufügen:
cat /mnt/usb/id_dsa.pub >> /home/vpn/.ssh/authorized_keys
Trockenschwimmer
Nach diesen Vorbereitungen ist der Zeitpunkt für erste Tests gekommen. Versuchen Sie, sich in der root-Rolle vom Client aus per ssh als User vpn auf dem Server einzuloggen. Mögliche Fragen des ssh-Kommandos, ob Sie dem anderen Rechner vertrauen, beantworten Sie mit yes (Listing 2).
Listing 2
Erste Tests
client:~# ssh server.dyndns.org -l vpn The authenticity of host 'server.dyndns.org (217.81.158.48)' can't be established. DSA key fingerprint is 80:f5:44:74:f4:5e:d0:50:32:12:88:f7:f4:31:75:82. Are you sure you want to continue connecting (yes/no)? yes Warning: Permanently added 'server.dyndns.org' (DSA) to the list of known hosts. Linux server 2.4.16 #6 Mon Apr 20 11:03:22 EST 2003 i686 unknown No mail. vpn@server:~$ vpn@server:~$ sudo /usr/sbin/pppd noauth ~9}#ÀZ}!}!} }9}"}k} }r} }'}%}zt2-*}'}"}
Klappt das passwortlose Einloggen, rufen Sie auf dem Server den pppd auf. Die aus wirren Zeichen bestehende Antwort in Listing 2 ist ganz normal. Sie beweist, dass der pppd auf dem Server-Rechner startete und nun versucht, den pppd der Gegenstelle anzusprechen. Da es den zur Zeit noch nicht gibt, brechen Sie den Prozess mit [Strg-C] ab, um weitere Einstellungen vorzunehmen.
Niemand mag das VPN jedes Mal von Hand starten. Daher gibt man dem Rechner den Auftrag, es beim Booten oder nach dem Aufbau der Internet-Verbindung automatisch herzustellen. Sind die Rechner über eine ordentliche Standleitung mit dem Internet verbunden, reicht es, das vpn-pppssh-Skript auf dem Client-Rechner nach /etc/init.d/ zu kopieren und es nach der Bootlogik der eingesetzten Distribution in die adäquaten Runlevel-Verzeichnisse zu verlinken. Unter Debian geht das wie in Listing 3.
Listing 3
Das VPN-Skript als Init-Skript für den Systemstart bei Debian einrichten
ln -s /etc/init.d/vpn-pppssh /etc/rc0.d/K10vpn-pppssh ln -s /etc/init.d/vpn-pppssh /etc/rc1.d/K10vpn-pppssh ln -s /etc/init.d/vpn-pppssh /etc/rc2.d/S99vpn-pppssh ln -s /etc/init.d/vpn-pppssh /etc/rc3.d/S99vpn-pppssh ln -s /etc/init.d/vpn-pppssh /etc/rc4.d/S99vpn-pppssh ln -s /etc/init.d/vpn-pppssh /etc/rc5.d/S99vpn-pppssh ln -s /etc/init.d/vpn-pppssh /etc/rc6.d/K10vpn-pppssh
Für Rechner mit DSL-Zugang, der meist alle 24 Stunden erneut aufgebaut werden muss, empfiehlt sich der Aufruf des VPN-Skripts nach jeder Einwahl des Clients. Hierfür kopiert man vpn-pppssh nach /usr/local/bin/ und legt in /etc/ppp/ip-up.d/ ein weiteres Skript (Listing 4) ab, das der pppd nach jeder Neueinwahl automatisch aufruft und so für den Aufbau des VPN sorgt.
Listing 4
VPN-Start bei der Internet-Einwahl
#!/bin/sh
if [ "$PPP_IPPARAM" = "vpn" ]; then
# Das VPN soll sich nicht selbst starten
exit 0
fi
/usr/local/bin/vpn-pppssh start
Praktische Details
Damit der Client aus Haus 5 nicht wissen muss, welche IP-Adresse der Server bei der letzten Einwahl zugewiesen bekam, nutzt die WG aus Haus 2 einen dynamischen DNS-Service (siehe Seite 66 f. und [5]), der für die vom Internetprovider dynamisch vergebene IP-Adresse einen festen Hostnamen zur Verfügung stellt.
Im Beispiel trägt der als Server dienende Rechner vom lokalen Netz aus gesehen die interne IP-Adresse 192.168.2.1. Den Gateway-Rechner von Haus 5 konfigurierten dessen Bewohner auf die interne IP-Adresse 192.168.5.1. Sie passen außerdem die Werte der Variablen SERVER_HOSTNAME, SERVER_USERNAME, SERVER_IFIPADDR und CLIENT_IFIPADDR im Skript an die eigenen Gegebenheiten an (Listing 5).
Listing 5
Anpassungen an vpn-pppssh
# Der Hostname bzw. die IP-Adresse des Servers SERVER_HOSTNAME=server.dyndns.org # Benutzername auf dem Server, mit dessen Rechten das VPN aufgebaut wird SERVER_USERNAME=vpn # Die IP-Adresse des VPNs auf dem Server: SERVER_IFIPADDR=192.168.2.254 # Die IP-Adresse des VPNs auf dem Client: CLIENT_IFIPADDR=192.168.5.254 # Der Adressbereich des internen Netzes auf Server-Seite: SERVER_NET="192.168.2.0/24" # Der Adressbereich des internen Netzes auf Client-Seite: CLIENT_NET="192.168.5.0/24"
Um die Routing-Tabelle anpassen zu können, muss bekannt sein, welcher IP-Adressen-Bereich auf der einen wie auf der anderen Seite des Tunnels genutzt wird. Dafür sind die Angaben in SERVER_NET und CLIENT_NET nötig.
Damit alle Pakete ins Server-seitige Netz 192.168.2.0 durch den aufgebauten VPN-Tunnel gehen, muss man am Ende der Startsektion des vpn-pppssh-Skripts einen Befehl einfügen, der die Routing-Tabelle des Clients entsprechend erweitert:
route add -net $SERVER_NET gw $SERVER_IFIPADDR
Ein weiterer Befehl öffnet eine ssh-Verbindung zum Server und setzt dort mit Hilfe von sudo die passende Route zum Client:
ssh -o Batchmode=yes $SERVER_HOSTNAME -l $SERVER_USERNAME sudo /sbin/route add -net $CLIENT_NET gw $CLIENT_IFIPADDR
Dank der im Abschnitt “Trockenschwimmer” erklärten Anpassungen startet der Client das VPN-Skript selbsttätig, sobald er die Verbindung zum Internetprovider aufgebaut hat; die zwei zusätzlichen Befehle im Skript passen das Routing an. Nach spätestens einer Minute sollten die Rechner des anderen Netzes erreichbar sein, was sich z. B. mit ping schnell überprüfen lässt. Webserver oder Drucker im anderen Teilnetz sprechen die Bewohner von Haus 5 nun so an, als ob es sich um lokale Geräte handelt. Umgekehrt gilt für die WG aus Haus 2 dasselbe.
Für Perfektionisten
Nichtsdestotrotz ließen sich an solch einem VPN noch viele Dinge optimieren. Um Rechner des jeweils anderen Teilnetzes mit Hostnamen statt numerischen IP-Adressen anzusprechen, müssen alle Computer beider Teilnetze mit ihren IP-Adressen in der Datei /etc/hosts eines jeden Rechners eingetragen werden. Alternativ käme eine Verbreitung per NIS oder mit Hilfe eines Secondary Nameserver in Frage.
Auch das eingangs beschriebene Problem der Verbindungsabbrüche ließe sich beheben, indem ein Skript in /etc/ppp/ip-down.d/ prüft, ob die Verbindung unplanmäßig unterbrochen wurde.
Selbst wenn statt eines Routers auf Linux-Basis ein Hardwarerouter zum Einsatz kommt, lässt sich vpn-pppssh einsetzen. Hierfür braucht letzterer lediglich den SSH-Port 22 auf einen Linux-Rechner weiterleiten. Dieser muss dann für die Rechner des internen Netzes als Gateway ins andere Teilnetz konfiguriert werden. Damit er ankommende Pakete auch wirklich weiterleitet, erlaubt root mittels
echo 1 > /proc/sys/net/ipv4/ip_forward
das Forwarden.
Wollen jedoch eine größere Anzahl von Einzelnetzen verbunden werden, lohnt sich ein Blick auf aufwändigere VPN-Lösungen wie OpenVPN [3] und FreeS/WAN [4] (pju).
Glossar
-
Routing
-
Eine vom Betriebssystem verwaltete Routing-Tabelle legt den Weg der Datenpakete zwischen den Netzen (die Route) fest.
-
sudo
-
Mit diesem Tool erlaubt der Sysadmin einzelnen Benutzern, bestimmte Programme mit root-Rechten auszuführen. Die Möglichkeiten dieser Methode gehen weit über die des bekannten SUID-Bits [6] hinaus.
-
Public-Key-Verfahren
-
Bei der asymmetrischen Verschlüsselung gibt es immer zwei sich ergänzende Schlüssel: den öffentlichen Public Key sowie einen geheimen Private Key. Beide Schlüssel zusammen bilden ein Schlüsselpaar.
-
Daemon
-
Im Hintergrund wartendes Programm, welches auf Anfragen von außen reagiert. Dessen Programmname setzt sich meist aus dem verwendeten Protokoll mit einem angehängten “d” zusammen, so z. B. pppd oder sshd.
-
DSA
-
“Digital Signature Algorithm”, ein sicherer Algorithmus zum Signieren von Nachrichten.
-
Runlevel
-
Betriebsmodus des Linux-Systems. Die verschiedenen Runlevels unterscheiden sich durch die Dienste, die beim Wechseln in diesen Modus gestartet oder angehalten werden. Welchen das System beim Booten standardmäßig benutzt, bestimmt die Datei /etc/inittab.
-
NIS
-
“Network Information System”. Ein NIS-Server verteilt Konfigurationseinstellungen an angeschlossene Clients, zum Beispiel die User-Daten in Form einer Passwortdatei oder die Konfigurationsdateien für den Automounter, der Netzwerklaufwerke bei Bedarf einhängt. Die Datei /etc/nsswitch.conf legt fest, welche Datenquellen (lokale Dateien, NIS) ein Rechner anzapft.
-
Secondary Nameserver
-
Ein Secondary Nameserver bezieht seine DNS-Informationen vom Primary Nameserver, der die entsprechende Domain verwaltet. Oft holt er sich bereits beim Start eine vollständige Kopie dieser Daten. Dass die DNS-Auskünfte, die ein solcher Nameserver erteilt, zeitweise nicht mit den vom Primary Nameserver verbreiteten Daten übereinstimmt, wird in Kauf genommen.
Infos
[1] vpn-pppssh und Howto: http://www.tldp.org/HOWTO/mini/ppp-ssh/
[2] OpenSSH: http://www.openssh.org/
[3] OpenVPN: http://openvpn.sourceforge.net/
[4] FreeS/WAN: http://www.freeswan.org/
[5] Michael Renner, Hans-Günther Nusseck: “Identitätskrisen meistern”, Linux Magazin 05/2001, S. 93 ff., http://www.linux-magazin.de/Artikel/ausgabe/2001/05/dyndns/dyndns.html
[6] Patricia Jung: “Alles Recht”, LinuxUser 12/2002, S. 31 ff.





