Siebdruck
IPsec verstehen und nutzen
Um IPsec verstehen zu können, solltest Du wenigstens Grundkenntnisse über Verschlüsselungsverfahren und über Netzwerke und das ISO/OSI Schichtenmodell haben. Falls Du die nicht drauf hast, lies am besten mal folgende Artikel:
IPsec bietet Möglichkeiten Netzwerktraffic auf IP Ebene (Layer 3) zu verschlüsseln und zu authentifizieren. D.h. alle Transport- bzw. Applicationlayerprotokolle höherer Ebene wie z.B. TCP/UDP (für die Transportschicht) oder FTP, SMTP usw. (für die Anwendungsschicht) können mit IPsec abgesichert werden.
Das bietet mehr Sicherheit als z.B. ein unsicheres Plain Protokoll der Anwendungsschicht (SMTP) mit einem sicheren Protokoll der gleichen Schicht (SSH) zu tunneln, weil im Falle von IPsec auch garantiert wird, dass die Header der Transport- und Vermittlungsschicht nicht manippalawanert wurden (Beispiel: IP Spoofing, Man-in-the-middle Attack). Bei IPsec handelt es sich keineswegs um ein einzelnes Protokoll, sondern um eine ganze Protokollsammlung. Und es ersetzt auch nicht das IPv4 Protokoll, sondern ergänzt es!
Zur Authentifizierung und Verschlüsselung kann IPsec zwei unterschiedliche Protokolle verwenden: AH (Authentication Header) oder ESP (Encapsulating Security Payload).
Bei der Verwendung von AH wird nur sicher gestellt, dass an den Headern der höheren Schichten nichts manippalawanert wurde. Verschlüsselung des Payloads kommt erst bei der Verwendung von ESP ins Spiel! Wahlweise kann man ESP auch ohne Authentifizierung bzw. Verschlüsselung verwenden, aber erst beide Features zusammen garantieren einem maximale Sicherheit!
AH und ESP werden bei FreeS/WAN durch KLIPS (Kernel IPsec) direkt in den Kernel implementiert.
Dann kommt bei IPsec noch ein weiteres Protokoll zum tragen: IKE (Internet Key Exchange). Wie der Name schon sagt wird dieses Protokoll für den automatischen Austausch von Schlüsseln und anderen Verschlüsselungsoptionen wie z.B. der Frage wird AH oder ESP verwendet oder welcher Verschlüsselungs- typ bzw. -algorythmus wird mit welcher Schluessellänge verwendet, wie lang ist die Lebensdauer der Schlüssel usw.
Das IKE Protokoll wird bei FreeS/WAN durch den PLUTO Daemon implementiert. Diese ganzen Verschlüsselungsoptionen werden von IPsec separat fuer jede Verbindung als sogenannte SA (Security Association) in einer SAD (Security Association Database) gespeichert. Das heisst auf gut Deutsch: Man kann für jede Verbindung zwischen zwei oder mehr Rechnern / Netzen verschiedene Verschlüsselungsoptionen verwenden.
Dann kann es noch sein, dass man im Zusammenhang mit IPsec oder IKE etwas von dem Protokoll ISAKMP (Internet Security Association Key Management Protocol) liest. Hier sei nur kurz erwähnt, dass dieses Protokoll für das Management der SAs zuständig ist und vom IKE Protokoll verwendet wird. Für mehr Informationen über den Aufbau von IPsec lies am besten folgendes:
In den meisten Fällen wird IPsec dazu verwendet VPNs zu realisieren. Ein VPN (Virtual Private Network) ist ein sicherer (verschlüsselter und authentifizierter) Zusammenschluss von mehreren Rechnern / Netzen über ein als unsicher klassifiziertes Netz (z.B. das Internet). Oder auf gut Deutsch: Du "stöpselst" zwei Kisten / Netze sicher zusammen und benutzt sie als eins... Für mehr Informationen über VPNs lies am besten die VPN FAQ.
Mit IPsec kann man allerdings auch im internen Netz den Traffic absichern, indem jeder Rechner ausschliesslich IPsec zur Kommunikation verwendet. IPsec ist ebenfalls eine gute Wahl, wenn man dem unsicheren WEP nicht zutraut das WLAN zu schützen oder um einem Aussendienstmitarbeiter sicheren Zugangs ins Firmennetz zu gewähren.
So voll geschmissen mit allen möglichen Abkürzungen, Theorie und Definitions- krempel kommt jetzt endlich der praktische Part! Also kurz in die Haende spucken, nen Bier oder ne Jolt holen und los geht's! Lade Dir die Sourcen von freeswan.org und entpacke sie.
Danach führst Du den Befehl make menugo aus, um die Userspace Tools zu installieren und die Kernel Sourcen zu patchen und neu zu compilieren. Wenn Du die Fehlermeldung "Cannot find gmp.h" oder so bekommst, dann musst Du noch die GMP Library installieren. Die Library bekommst Du hier Nach der Installation und dem Reboot mit dem neuen Kernel kann man folgendermaßen testen ob IPsec im Kernel funktioniert: ipsec verify. Du solltest jetzt auch ein paar IPsec Informationen des Kernels unter /proc/net finden...
Für FreeS/WAN gibt es zwei Configfiles: ipsec.conf und ipsec.secrets. In ipsec.secrets befindet sich nach der Installation ein frisch generiertes RSA Schlüsselpaar, das für die Authentifikation verwendet wird. In ipsec.conf konfiguriert man alle FreeS/WAN Einstellungen sowie die gewünschten Verbindungen.
Eine Beispiel Konfiguration, um einen internen Rechner via IPsec mit dem Gateway zu verbinden, sieht so aus:
# basic configuration
config setup
interfaces="ipsec0=eth0"
plutodebug=none
klipsdebug=none
syslog=NOTICE
plutoload=example
plutostart=example
plutowait=no
# Example Connection
conn example
auto=start
type=tunnel
authby=rsasig
left=192.168.3.34
leftsubnet=192.168.3.34/32
leftrsasigkey=left-rsa-key
leftid=192.168.3.34
right=192.168.3.32
rightsubnet=0.0.0.0/0
rightrsasigkey=right-rsa-key
rightid=192.168.3.32
keyexchange=ike
keylife=900s
ikelifetime=1200s
keyingtries=5
rekeymargin=150s
In der Sektion setup konfiguriert man generelle Einstellungen. interfaces="ipsec0=eth0" gibt an, dass das erste IPsec Interface eth0 sein soll. Weitere trennt man via Leerzeichen. Oder man verwendet %defaultroute, wenn man die Verbindungen über das Device, über das die Defaultroute geht, benutzen möchte.
plutodebug=none, klipsdebug=none, syslog=NOTICE
dient dem Logging.
Wenn man statt none all einträgt, dann findet man unter /var/log/messages
jede Menge Debugmeldungen des Plutodaemon und der Kernel Ipsec Architektur.
plutoload=example, plutostart=example, plutowait=no
gibt an, dass der Pluto
Daemon die Verbindung example sofort laden und starten soll ohne zu warten.
Verwendet man das Schlüsselwort %search, dann startet der Pluto Daemon
automatisch alle Verbindugen, die auto=start
(siehe weiter unten) definiert
haben.
Mit dem Parameter conn configuriert man eine Verbindung. Wird als
Verbindungsname %default
angegeben, gelten die nachfolgenden Einstellungen
für alle Verbindungen. Der Verbindungsname ist ansonsten frei wählbar.
Genauso kann man eine Verbindung definieren, deren Einstellungen nur für
mehrere andere Verbindungen gelten soll. Dann muss man diese Einstellungen
in der gewünschten Verbindung mit also=Verbindungsname
laden.
auto=start gibt an, dass die Verbindung automatisch gestartet werden soll.
Falls einer der Kommunikationspartner nicht immer am Netz sein sollte, kann
man die Verbindung nicht automatisch aufbauen lassen. In diesem Fall benutzt
man auf dem VPN Gateway, das immer online ist das Schlüsselwort add, welches
angibt, dass die Gegenseite die Verbindung aufbaut. Eine Verbindung wird
über den Befehl ipsec auto --add Verbindungsname
geladen und über
ipsec auto --up Verbindungsname
initiiert (über den Parameter --down wird
die Verbindung dann wieder geschlossen).
type=tunnel
gibt den Typ der Verbindung an. Man verwendet den Verbindungstyp
Tunnel, wenn die Verbindung zwischen zwei Gateways aufgebaut werden soll, die
den Traffic an das jeweilige Subnet weiter leiten sollen (Host to subnet
oder Subnet to subnet Verbindungen). Bei Host to Host Verbindungen verwendet
man den Typ Transport.
authby=rsasig
signalisiert, dass die Authentifikation über RSA geschehen soll.
Falls man für die Authentifikation Preshared Keys verwenden möchte, wählt
man statt rsasig secret. Mehr dazu im Abschnitt Keying weiter unten.
left=192.168.3.34, leftsubnet=192.168.3.34/32
definiert den lokalen Rechner
und das dahinter liegende Subnet. In diesem Fall gibt es kein dahinter
liegendes Subnet, weil der lokale Rechner kein Router ist!
leftrsasigkey=left-rsa-key, leftid=192.168.3.34
konfiguriert den lokalen
RSA Key und ID. Dazu gleich mehr...
Das selbe wird jetzt noch für die remote Seite mit right statt left
eingestellt. Die Remote Seite ist in diesem Beispiel ein Gateway. Das sieht
man an dem Parameter rightsubnet=0.0.0.0/0
. Also das "Subnet" was hinter
diesem Gateway liegt, ist das komplette Internet.
Man kann statt IP Adressen auch Hostnamen eintragen, allerdings muss DNS
dann natürlich einwandfrei zwischen den Verbindungspartner funktionieren
und das auflösen mindert auch ein wenig die Geschwindigkeit...
Sollte die IP und das Subnet eines Verbindungspartners egal sein oder kennt
man es schlicht weg nicht, weil es sich um eine dynamische IP handelt, dann
verwendet man das Schlüsselwort %any.
Die Einstellungen ab keyexchange=ike konfigurieren wie die Schlüssel für die Verschlüsselung und Authentifikation der Verbindung generiert und ausgetauscht werden sollen und wie oft neue Schlüsselpaare generiert werden.
Mit der Konfiguration wie oben beschrieben gibt es allerdings noch ein kleines
Problem...
Die Remote (right) Seite, also der VPN Gateway, ist eine Firewall, die auch
NAT verwendet. Mit der obigen Konfiguration funktioniert zwar das Weiterleiten
der Pakete in die weite Welt, wenn man allerdings versucht auf den Gateway
selbst zu zu greifen z.B. für DNS, dann wird das fehlschlagen!
Dazu gibt es aber auch noch einen Parameter: left bzw rightfirewall=yes
je
nachdem welche Seite eine Firewall ist.
NAT darf übrigens nicht nach dem VPN Gateway statt finden, weil sonst die
Authentifikation der Datenpakete auf der Gegenseite fehl schlagen wird, weil
irgendwelche Adressen umgeschrieben wurden!
Natürlich muss die Firewall den für IPsec nötigen Traffic auch durch lassen.
Für die hier vorgestellte Konfiguration muss man folgende IPtables Regeln
implementieren:
# IKE
iptables -A INPUT -p udp --dport 500 -j ACCEPT
iptables -A OUTPUT -p udp --sport 500 -j ACCEPT
# ESP
iptables -A INPUT -p 50 -j ACCEPT
iptables -A OUTPUT -p 50 -j ACCEPT
Die erforderlichen IPtables Regeln können auch automatisch vor dem
Verbindungsaufbau geladen und nach dem Verbindungabbau wieder entfernt
werden. Dazu verwendest Du die beiden Befehle prepluto und postpluto
und schreibt die Regeln in ein kleines Bashscript.
prepluto=ipsec_rules.sh
Wenn IPtables Regelsätze nur für eine bestimmte Verbindung automatisch
geladen werden sollen, dann verwendet man in der conn Sektion die
Parameter leftupdown bzw. rightupdown=script
.
Die kann man allerdings nicht mit dem Parameter left- bzw. rightfirewall
kombinieren!
Last but not least: Optional kann man auch noch den gesamten Datenverkehr
komprimieren. Dies geschieht ganz einfach ueber den Parameter compress=yes
.
Wie kommt man nun an die Einträge für leftrsasigkey
und rightrsasigkey
?
RSA basiert auf dem Public Key Verfahren, d.h. man hat einen geheimen und
einen öffentlichen Schlüssel. Das VPN Gateway muss ein Schlüsselpaar
generieren und den public Key sicher an seine Clients verteilen. Jeder
Client muss auch wiederum ein RSA Schlüsselpaar generieren und den Public
Key dem VPN Gateway bekannt geben.
Sollte man auf dem Client oder VPN Gateway noch kein Schlüsselpaar unter
/etc/ipsec.secrets
finden, kann man mit ipsec newhostkey --output /etc/ipsec.secrets
einen generieren.
Dies erzeugt ein 2192 Bit RSA Schlüsselpaar. Mit dem Parameter --bits kann
man das natürlich auch anpassen. Und mit dem Parameter --hostname kann man
auch noch angeben für welchen Rechner das Schlüsselpaar generiert werden
soll.
Über ipsec showhostkey --left > public.key
extrahiert man den öffentlich Key in die
Datei public.key. Dieser Key wird direkt in dem richtigen Format als leftrsasigkey
für die ipsec.conf
raus gespuckt.
Mit ipsec showhostkey --right > public.key
bekommt man den Public Key im
rightrsasigkey
Format.
Diesen Key trägt man lokal als leftrsasigkey
ein und überträgt ihn zum anderen
Verbindungspartner, der ihn dann als rightrsasigkey
eintragen muss.
Das hier verwendete Verfahren basiert auf einem automatischen Schlüsselaustausch
Verfahren mit einem asymmetrischen Verschlüsselungsalgorytmus (Public Key Verfahren).
Es gibt auch die Möglichkeit des manuellen Schlüsselaustausches oder
des automatischen mit symmetrischer Verschlüsselung, doch beide andere
Verfahren sind unsicherer als das hier benutze. Wenn die Performance zu
sehr leiden sollte, dann verwendet man am besten automatischen Schlüssel-
austausch mit symmetrischer Verschluesselung (Preshared Keys genannt in der
FreeS/WAN Doku). Von manuellem Schlüsselaustausch ist abzuraten und dient
höchstens dem Debugging oder wenn die Gegenseite keinen automatischen
Schlüsselaustausch unterstützt.
Einen neuen Preshard Key erzeugt man mit dem Befehl ipsec ranbits
und teilt
ihm über den --bytes Parameter die Schlüssellaenge mit. Preshared Keys
werden im Gegensatz zu den Public Keys in der Datei /etc/ipsec.secrets nach
folgendem Schema eingetragen:
left right: PSK "key"
Hier ein Beispiel:
10.0.0.1 11.0.0.1 : PSK "jxTR1lnmSjuj33n4W51uW3kTR55luUmSmnlRUuWnkj"
Der Preshared Key muss genau wie der Public Key beiden Kommunikationspartner
sicher bekannt gemacht werden! Also z.B. über eine mit PGP / GnuPG
verschlüsselte E-Mail oder via scp.
Auf beiden Seiten muss IP Forwarding aktiviert sein! Und es darf kein
Source Validation im Kernel aktiv sein!
Das erreicht man mit folgenden Veränderungen im /proc
Dateisystem:
echo 1 > /proc/sys/net/ipv4/conf/ip_forward
echo 0 > /proc/sys/net/ipv4/conf/eth0/rp_filter
Man kann IP Forwarding auch von IPsec automatisch einstellen lassen, indem
man in der Configdatei /etc/ipsec.conf
in der Setup Sektion den Parameter
forwardcontrol=yes
verwendet. Das ist per Default ausgestellt.
Und /etc/init.d/ipsec start
wird fehlschlagen, wenn man Source Validation
noch aktiviert hat!
Unter Debian wird das normalerweise beim Booten angeschaltet und kann
in der Datei /etc/network/options
abgewürgt werden.
Hier noch ein paar typische Fehlermeldungen auf die man stossen könnte:
route-host command exited with status 7
Dann solltest Du mal Deine Subnetparameter überprüfen.
route-client command exited with status 7
Kann es sein, dass Du einen *nexthop Eintrag vergessen hast? Das kann auf dem ersten Blick für etwas Verwirrung sorgen... Wenn Du z.B. wie ich einen Dialup Host mit einem anderen Rechner, der über ne DSL Flat online ist, zusammen schalten willst, dann connecten sich die beiden Rechner nicht direkt zueinander, sonder immer über den entsprechenden Default Router des Providers! Und den musst Du als leftnexthop eintragen!
[subnet]----[dial-up]--->[router_des_providers]--->{ Internet }--->[dsl-flat]----[subnet]
leftsubnet left leftnexthop right rightsubnet
Wenn Du über eine dynamische IP ans Netz angebunden bist, dann trage als leftnexthop
am besten %defaultroute
ein.
up-client command exited with status 127
Diese Fehlermeldung bedeutet, dass das _updown Script, welches ausgeführt wird,
wenn Du leftfirewall
oder rightfirewall
auf yes gesetzt hast, nicht die entsprechenden
Firewall Regeln eintragen konnte. Das Script funktioniert nur für ipfwadm und ipchains!
Wenn Du z.B. IPtables verwendest, dann kommentiere die entsprechenden Zeilen aus
/usr/local/lib/ipsec/_updown
aus und trage sie selbst in Deine Firewall Regeln ein wie
oben beschrieben!
Mit dem Befehl ipsec look
Verbindung bekommt man einige Informationen über
die Verbindung wie z.B. die Routingtabelle und über ipsec auto --status
minimale Debugmeldungen des Schlüsseldaemons Pluto. Für mehr Debugmeldungen
verwendet man den Befehl ipsec barf
oder stellt die Debugging Meldungen von
KLIPS und dem Pluto Daemon in /etc/ipsec.conf
auf all.
Ein Blick in /var/log/messages
oder ins Proc Dateisystem unter /proc/net
kann auch nicht schaden...
Ansonsten testet man die Verbindung wie jede andere Netzwerkverbindung auch
via ping, traceroute oder Sniffer
usw.