Die Idee und OpenConnect
Cisco nennt seine Technik AnyConnect. Die Idee dahinter ist eigentlich relativ elegant:
- Stelle eine HTTPs-Verbindung zum VPN-Server her
- Handle ueber diese Verbindung die Authentifikation ab
- Wenn moeglich
- Fuehre den eigentlichen Datenaustausch per UDP durch
- wenn nicht
- dann schiebe saemtliche daten durch die HTTPs-Verbindung
Natuerlich waren die Leute bei Cisco nicht die einzigen, die auf diese Idee gekommen sind, es gibt dazu sogar einen offiziellen Standardisierungsvorschlag -- an dem Cisco um Haaresbreite vorbeiimplementiert. Zufall? Wie dem auch sei, der AnyConnect-Client ist fuer Windows, Mac OS und einige Linuxe verfuegbar. Toll!
Toll nur, dass mir das nichts nuetzt, denn ich moechte die Verbindung ja von meinem kleinen Geode aus aufbauen. Und auf dem laeuft ja ein FreeBSD. Welches ich auch nicht abloesen moechte. Und an der Stelle kommt OpenConnect ins Spiel als freie Implementierung des Verwendeten Protokolls.
OpenConnect und seine Beduerfnisse
Zum Testen habe ich mir eine andere Maschine als meinen Shaper ausgesucht; auf dieser Maschine laeuft ein FreeBSD, dass sich wie folgt charakterisieren laesst:
FreeBSD box 7.2-RELEASE-p3 FreeBSD 7.2-RELEASE-p3 #0: Tue Apr 20 22:51:05 CEST 2010 root@box:/usr/obj/usr/src/sys/GENERIC i386Auf der Maschine waren 39 Ports (FreeBSD-Programmpakete) installiert. Dann kam ein leichtsinniges
make install clean in /usr/ports/security/openconnect. Gefolgt von einem mehrstuendigen Compilemarathon. In dessen Verlauf sich meine Nackenhaare aufzustellen begannen. Nachdem eine libX gebaut war, begann gar der Bau von Teilen von GNOME. Man stelle sich das vor -- ein kleines Programm fuer eine lowlevelige Netzwerkaufgabe -- und es bringt ein grafisches System und ein halbes Toolkit dafuer mit!Ganz konkret: Nach der Installation von
openconnect waren auf der Maschine 145 Ports installiert. Zeit zum Luftholen: Klappt es denn wenigstens?Teilweise. Denn zur Laufzeit stellt Openconnect fest, dass die installierte OpenSSl-Version nicht die notwendigen Funktionen anbietet. Wohlgemerkt, an dieser Stelle ist es die OpenSSL-Version, die das Grundsystem mitbringt. Und das ist so etwas:
%openssl version OpenSSL 0.9.8e 23 Feb 2007Die benoetigte aktualisierte OpenSSL-Version gibt es aber gluecklicherweise in den Ports. Also flugs nach
/usr/ports/security/openssl gegangen und den Port installiert. Anschliessend muss OpenConnect nochmals neu kompiliert werden -- und dabei gegen die neuen OpenSSL-Libraries gelinkt werden. Hierzu kann das Flag WITH_OPENSSL_PORT gesetzt werden -- auch wenn WITH_OPENSSL_BASE bei installiertem OpenSSL-Port zu einem Fehler fuehrt.Mit diesen neuen Libs kann OpenConnect dann auch die UDP-und-nicht-HTTPS-Variante, die deutlich performanter ist :)
In Rezeptform
cd /usr/ports/security/openssl && make install cleancd /usr/ports/security/openconnect && make WITH_OPENSSL_PORT install clean- Kaffee holen. Mehrfach, falls auf dem System bisher noch kein X und kein GTK vorhanden...
- Fertig.
Aufraeumen und Laufenlassen
Die gute Nachricht zuerst: Um Openconnect dann endlich zu nutzen, braucht es doch nur ein Executeable und drei Libraries:
%ls -lah total 3362 -r-xr-xr-x 1 ad001 ad001 1.6M Apr 21 20:40 libcrypto.so.7 -r--r--r-- 1 ad001 ad001 340K Apr 21 20:44 libssl.so.7 -rwxr-xr-x 1 ad001 ad001 1.3M Apr 21 20:45 libxml2.so.5 -rwxr-x--x 1 ad001 ad001 58K Apr 21 20:40 openconnectwir haben das Openconnect-Binary, eine ssl- und eine Crypto-Lib. Und dann ist da noch die libxml2. Ich habe die ganzen Dateien auf dem Zielsystem (meinem FreeBSD-Router, den ich unter amd-geode-based-fbsd-router.html bereits beschrieben habe) einfach erstmal in ein Verzeichnis geschmissen (und nicht nach
/usr/local/{lib,bin} verteilt. Das u.a., um nicht mit dem in Konflikt zu geraten, was da bislang schon herumliegt.Allerdings endet der Versuch des Ausfuehrens erst einmal im nichts, weil die Libs nicht gefunden werden. Aber dem kann durch das simple Setzen von
LD_LIBRARY_PATH entgegengewirkt werden:
%./openconnect /libexec/ld-elf.so.1: Shared object "libcrypto.so.7" not found, required by "openconnect" %setenv LD_LIBRARY_PATH /home/ad001/oc/ %./openconnect No server specified Usage: openconnect [options]Jetzt kann der Spass prinzipiell losghehen. Aber da bleibt noch ein Haken. Von openconnect wird zwar ein Tunnel-Device angelegt. Aber leider wird nur eine der Tunnel-IPs gesetzt und auch keine neue Route angelegt. Das sind aber alles echte Kleinigkeiten im Vergleich zum Daten-durch-den-Tunnel-schieben und leicht mit einem kleinen (dreckigen) Skript zu beheben:Open client for Cisco AnyConnect VPN, version v2.01 -b, --background Continue in background after startup -c, --certificate=CERT Use SSL client certificate CERT -k, --sslkey=KEY Use SSL private key file KEY -K, --key-type=TYPE Private key type (PKCS#12 / TPM / PEM) -C, --cookie=COOKIE Use WebVPN cookie COOKIE --cookie-on-stdin Read cookie from standard input -d, --deflate Enable compression (default) -D, --no-deflate Disable compression -g, --usergroup=GROUP Set login usergroup -h, --help Display help text -i, --interface=IFNAME Use IFNAME for tunnel interface -l, --syslog Use syslog for progress messages -U, --setuid=USER Drop privileges after connecting -m, --mtu=MTU Request MTU from server -p, --key-password=PASS Set key passphrase or TPM SRK PIN --key-password-from-fsid Key passphrase is fsid of file system -q, --quiet Less output -Q, --queue-len=LEN Set packet queue limit to LEN pkts -s, --script=SCRIPT Use vpnc-compatible config script -S, --script-tun Pass traffic to 'script' program, not tun -u, --user=NAME Set login username -V, --version Report version number -v, --verbose More output -x, --xmlconfig=CONFIG XML config file --authgroup=GROUP Choose authentication login selection --cookieonly Fetch webvpn cookie only; don't connect --printcookie Print webvpn cookie before connecting --cafile=FILE Cert file for server verification - Disable password/SecurID authentication --passwd-on-stdin Read password from standard input ngerprint
%cat fixtun
route add 139.30.252.228 10.40.104.1 > /dev/null 2>&1
route delete default >/dev/null 2>&1
a=`ifconfig tun0 | grep inet | awk '{print $2 }'` ; ifconfig tun0 $a $a ; route add default $a >/dev/null 2>&1
Und fertig ist die laufende Verbindung.
Und die Erklaerung fuer die 140 Ports
Es laeuft also. Und das sogar mit recht wenig Laufzeitabhaengigkeiten. Also muessen die Unmengen an Ports wohl alle Build-Dependencies sein, also Programme, die zum Kompilieren benoetigt werden (oder Programme, die zum Erstellen von Programmen, die zum Kompilieren notwendig sind, oder ...).
Also schauen wir mal, was wir da so an Abhaengigkeiten finden... hmmmm. OpenSSL. Einigermassen klein und in sich abgeschlossen. Bringt auch die Crypto-Lib mit. Immer noch keine hundert Abhaengigkeiten.
Dann ist da diese ueberaus ominoese XML-Library. Sehr verdaechtig.
Die gehoert naemlich zum GNOME-Universum. Und als solcher wird mehr oder weniger viel fertiges GtK vorausgesetzt. Zwar nicht zum Nutzen der Library, da kann sie ganz gut fuer sich allein stehen. Aberr um die Lib zu bauen denkt sich eintweder das FreeBSD-Ports-System, dass es praktisch waere, grosse Teile von GtK fertig zu haben. Oder es ist tatsaechlich notwendig.
Was ist denn da alles als Abhaendigkeit?
[ad001@glas /usr/ports/security/openconnect]$ make pretty-print-run-depends-list This port requires package(s) "ORBit2-2.14.17 atk-1.28.0 bison-2.4.1,1 bitstream-vera-1.10_4 cairo-1.8.8_1,1 compositeproto-0.4 damageproto-1.1.0_2 dbus-1.2.16_1 dbus-glib-0.84 eggdbus-0.6 encodings-1.0.2,1 expat-2.0.1_1 fixesproto-4.0 font-bh-ttf-1.0.0 font-misc-ethiopic-1.0.0 font-misc-meltho-1.0.0_1 font-util-1.0.1 fontconfig-2.8.0,1 freetype2-2.3.11 gamin-0.1.10_3 gconf2-2.28.0_2 gettext-0.17_1 gio-fam-backend-2.22.4 glib-2.22.4 gnome_subr-1.0 gnomehier-2.3_12 gobject-introspection-0.6.7 gtk-2.18.7_1 hicolor-icon-theme-0.12 inputproto-1.5.0 jasper-1.900.1_9 jbigkit-1.6 jpeg-8_1 kbproto-1.0.3 libIDL-0.8.13 libX11-1.2.1_1,1 libXau-1.0.4 libXcomposite-0.4.0,1 libXcursor-1.1.9_1 libXdamage-1.1.1 libXdmcp-1.0.2_1 libXext-1.0.5,1 libXfixes-4.0.3_1 libXft-2.1.14 libXi-1.2.1,1 libXinerama-1.0.3,1 libXrandr-1.3.0 libXrender-0.9.4_1 libffi-3.0.9 libfontenc-1.0.4 libiconv-1.13.1_1 libpthread-stubs-0.3_3 libxcb-1.5 libxml2-2.7.6_2 m4-1.4.14,1 mkfontdir-1.0.4 mkfontscale-1.0.6 pango-1.26.2_2 pcre-8.02 perl-5.10.1 pixman-0.16.6 pkg-config-0.23_1 png-1.4.1_1 polkit-0.96_1 python26-2.6.4 randrproto-1.3.0 renderproto-0.9.3 shared-mime-info-0.71 tiff-3.9.2_1 xcb-util-0.3.6_1 xextproto-7.0.5 xineramaproto-1.1.2 xorg-fonts-truetype-7.4 xproto-7.0.15" to run.Uff. Und stimmt nicht :)