Eigentlich kein Problem, wird auf der Strongswan Seite beschrieben. Zusätzlich muss man aber das Zertifikat auf dem Mac noch freigeben, wie im Apple Forum angedeutet wird. Das Programm heißt auf Englisch Keychain Access und auf Deutsch Schlüsselbundverwaltung und befindet sich in /Programme/Dienstprogramme, hier muss das Zertifikat ausgewählt werden und nach Doppelklick muss hier unter Zugriff /usr/sbin/racoon zur Liste der berechtigten Programme hinzugefügt werden. Falls schon /usr nicht sichtbar ist, CMD-SHIFT-. zeigt versteckte Dateien an.
Der Versuch, ein PKCS12 Zertifikat auf einem Samsung Galaxy von der SD-Karte zu installieren schlug immer wieder fehl, das Passwort wurde immer wieder neu abgefragt, weil es angeblich falsch sei. Die Lösung war einfach, der Weg über Google Drive und ES Dateiexplorer war das Problem, einfach das Zertifikat auf einem Webserver ablegen, mit dem Browser ansteuern, die Passwort-Abfrage kommt und funktioniert.
Nachdem ich mein HTC Desire Z auf Android 4 ICS umgestellt habe, sollte IPSec nun endlich gehen.
Auf dem Telefon (CyanogenMod 9.0.0-RC0 BETA 5):
Ein Zertifikat in pkcs12-Format erstellen, wie findet man an vielen Stellen. Dieses zusammen mit dem ins pcks12-Format umgewandelte CA-Zertifikat auf die SD-Karte überspielen und in Einstellungen->Sicherheit->Von SD-Karte installieren auf das Telefon übertragen. Die Zertifikate werden dabei auf der SD-Karte gelöscht.
In Einstellungen->Mehr…->VPN->VPN hinzufügen. Hier ist der Name nach Wunsch festzulegen, der Typ ist »IPSec Xauth RSA«, das IPSec-Nutzerzertifikat ist das eben eingelesene Zertifikat, IPSec-CA-Zertifikat und IPSec-Serverzertifikat bleiben leer! Sonst kommt es zu einem Fehler, es tauchen Pakete auf Port 4500 auf, die mit tcpdump gesehen werden können, die aber von strongswan nicht verarbeitet werden.
Auf dem Server (Debian Squeeze, Kernel 2.6.39 mit Strongswan 4.5.2 aus den Backports):
Anders als ursprünglich von mir angenommen, ist der Inhalt von /proc/sys/net/ipv4/conf/ppp0/rp_filter anscheinend egal, ich hätte gedacht, er müsse 0 sein. Relevant ist aber natürlich /proc/sys/net/ipv4/ip_forward, was auf 1 stehen muss.
Außerdem muss natürlich port 500 und udp port 4500 von der Firewall durchgelassen werden, ebenso Fragmente, dies ist aber auf Gateways für IPSec meist ohnehin der Fall. Wichtig ist aber, da die normale Android IPSec Implementation keinen geteilten Tunnel erlaubt, sicherzustellen, dass Datenverkehr vom Handy durch das Gateway ins Internet geleitet wird (und zurück), bei mir so gelöst:
iptables -A FORWARD -i eth0 -o ppp0 -m mark --mark 50 -j ACCEPT # Weiterleiten in per IPSec angeschlossene Netze
iptables -A FORWARD -i ppp0 -o eth0 -m mark --mark 50 -j ACCEPT # dito, andere Richtung
iptables -A FORWARD -i ppp0 -d 192.168.99.0/24 -j ACCEPT # Weiterleiten der Antworten aus dem Netz zum Handy
iptables -t mangle -A PREROUTING -i ppp0 -p esp -j MARK --set-mark 50 # Verhindern des doppelten Masqueradings
iptables -t mangle -A PREROUTING -i ppp0 -p udp --dport 4500 -j MARK --set-mark 50 # dito
iptables -t mangle -A PREROUTING -d 192.168.0.0/16 -j MARK --set-mark 50 # dito
iptables -t nat -A POSTROUTING -o ppp0 -s 192.168.199.0/24 -d 192.168.0.0/16 -j ACCEPT # Akzeptieren von Transport in per IPSec angeschlossene Netze
iptables -t nat -A POSTROUTING -s 192.168.99.0/24 -o ppp0 -j MASQUERADE # Masquerading von Paketen vom Handy ins Internet, wegen mark=50 aus PREROUTING
iptables -t nat -A POSTROUTING -o ppp0 -m mark --mark 50 -j ACCEPT # Verhindern des doppelten Masqueradings
iptables -t nat -A POSTROUTING -o ppp0 -j MASQUERADE # Masquerade aller Pakete, die nicht vorher in POSTROUTING behandelt wurden
Die Strongswan Konfiguration benötigt auf jeden Fall die Zeile leftsendcert=always, ohne diese kommt es zu einem Fehler:
packet from 80.186.112.96:59330: Main Mode message is part of an unknown exchange
Die leftid und rightid müssen natürlich entsprechend den eigenen Zertifikaten eingetragen sein. Weiterhin ist dies mit IKEv1, also pluto realisiert, ob dies auch mit charon und IKEv2 geht, weiß ich momentan noch nicht. Auch weiß ich noch nicht, wie ich es mit laufendem charon zum laufen bekomme. Wichtig ist mir aber, dass IPSec mit Zertifikaten auf meinem Handy nun endlich geht.
config setup # klipsdebug=all # plutodebug=control plutostart=yes charonstart=no nat_traversal=yesconn %default keyingtries=2 compress=yes pfs=yes
conn htc-eibo keyexchange=ikev1 type=tunnel pfs=no xauth=server authby=xauthrsasig left=%defaultroute leftrsasigkey=%cert leftid="C=DE, L=Hamburg, O=Eibo Thieme, OU=gateway" leftcert=eibo.pem leftsendcert=always leftsubnet=0.0.0.0/0 right=%any rightrsasigkey=%cert rightid="C=DE, L=Hamburg, O=Eibo Thieme, OU=htc" rightsourceip=192.168.99.1/32 auto=add
Um Zertifikate unter Android 2.2 (auf einem HTC Desire Z) zu installieren kann man diese per OpenSSL in das PKCS12-Format umwandeln und sie im Wurzelverzeichnis auf der per USB-Storage angeschlossenen SD-Karte ablegen, dann ruft man unter Einstellungen->Sicherheit->Zertifikate Importieren auf, hier wird man nach dem Kennwort gefragt. Das Konvertieren geht mit folgendem Aufruf:
openssl pkcs12 -export -in htc.pem -inkey htc.key -out htc.p12 -name "HTC Desire Z"
Das CA-Zertifikat kann dann in das DER-Format umgewandelt, am gleichen Platz abgelegt und auf die gleiche Weise importiert werden, hier entfällt natürlich die Passwort-Abfrage beim Import. Der Aufruf zur Konvertierung:
openssl x509 -outform der -in mycacert.pem -out mycacert.crt
Gefunden habe ich diese Information hier und hier.