to the weblog
back to the front page

DUKATH Web-Interface Cronjob

Wie man die Authentifizierung des DUKATH Web-Interfaces automatisieren kann.
gebastelt am 1. Oktober 2004, dokumentiert am 6. Oktober 2004

Am 24. August 2004 wurden DUKATH-Nutzer, die SSH-Tunnel dem Zugang via VPN-Concentrator vorziehen (oder es zumindestens ganz praktisch fanden, einfach so per SSH zu einer RZSTUD zu kommen), von einer ärgerlichen Mitteilung beim Einloggen in eine der RZSTUDs begrüßt (so sie sich denn überhaupt noch einloggen konnten..):

ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Ab sofort sind keine direkten ssh Verbindungen mehr zu den RZ-Rechnern
aus dem DUKATH- oder dem LAPTOP-Access-Netz mehr erlaubt. Dafuer kann
nach erfolgter Authentifizierung (gleiches Passwort wie beim IP-Sec
Tunnel) auf dem Web Zugangsserver (dukath-www.rz.uni-karlsruhe.de, http
Requests werden automatisch dahin geleitet) eine ssh Verbindung ueberall
hin, insbesondere auch zu den RZ-Rechnern aufgebaut werden.

W. Fries


---
RZ-Meldung vom Tue Aug 24 15:05:35 CES 2004 (rz19@rzaix-43)

ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ

Insbesondere ärgerlich ist es, daß erwähntes Authentifizieren leider per normalem Web-Formular und nicht mit HTTP Authentification nach RFC 2617 realisiert wurde, im letzeren Fall hätte nämlich einfach ein:

wget https://username:password@dukath-www.rz.uni-karlsruhe.de

als Cronjob genügt. Hier findet sich nun eine Lösung, wie man das ganze mit Hilfe des OpenSSL command line tool realisieren kann.


Idee

Die Idee ist eigentlich simpel. Wenn man das Formular abschickt, sendet der Browser ein POST-Request zum Webserver; dieser sieht für das DUKATH Web-Interface so aus:

POST /cgi-bin/login.pl HTTP/1.0
User-Agent: foo/23.5
Accept: text/*
Host: dukath-www.rz.uni-karlsruhe.de:443
Content-type: application/x-www-form-urlencoded
Content-length: 34

login=BENUTZERNAME&pass=PASSWORT&go=anmelden

Statt einen Browser zu verwenden, soll jetzt einfach eine HTTPS-Verbindung zum Webserver aufgebaut und jener POST-Request abgeschickt werden, ohne das vorher das eigentliche Formular geladen wird. Soweit kein Problem; es gibt mehrere Programme, um eine HTTP-Verbindung aufzubauen -- netcat zum Beispiel. Allerdings kann netcat kein SSL1), und somit habe ich eben jenes OpenSSL command line tool aus dem OpenSSL-Paket genommen.

Bis hier ist es ganz einfach, und mit einem Aufruf von:

openssl s_client -connect dukath-www.rz.uni-karlsruhe.de:443 < POST-request-file

wäre alles erledigt. Allerdings sollte auf jeden Fall das Zertifikat des Servers überprüft werden, denn andernfalls könnte sich gerade im DUKATH einfach ein anderer dazwischenmogeln und so das Passwort abfangen. Hier nun das Rezept, um jenes shell tool genau dazu zu bringen.


Anleitung

Schritt 1

Zunächst benötigt man natürlich jenes OpenSSL command line tool; OpenSSL bekommt man auf der OpenSSL-Homepage, bei Debian hat das zugehörige Paket passenderweise den Namen openssl. Ich habe Version "0.9.6c 21 dec 2001" sowie "0.9.7d 17 Mar 2004", es kann sein, daß sich andere Version anders verhalten.

Schritt 2

Man könnte das Skript wohl einfach als root laufen lassen, allerdings will ich mir nicht vorwerfen lassen, andere aufzufordern, komische Programme als root-cronjob einzutragen, und drum sage ich, man solle einen extra Benutzer dafür erstellen; macht es eigentlich auch kaum komplizierter. Also als root bitte

adduser dukath-unlock

eingeben und den User dadurch erstellen, Passwort bitte zunächst merken (oder auch nicht).

Schritt 3

Man wechsele zum neuen Benutzer, beispielsweise mit:

su - dukath-unlock

Schritt 4

Man wähle ein Verzeichnis im Heimatverzeichnis des eben erstellten Benutzers, das das Skript, die Zertifikate etc. enthalten soll; ich nehme /home/dukath-unlock/dukath-ip-unlock. Dort auch noch ein Verzeichnis namens certs erstellen, in das dann die Zertifikate kommen. Also:

mkdir dukath-ip-unlock; cd dukath-ip-unlock; mkdir certs

Schritt 5

Die Datei /home/dukath-unlock/dukath-ip-unlock/dukath-ip-unlock.sh mit folgendem Inhalt erstellen:

#!/bin/sh

DIR=/home/dukath-unlock/dukath-ip-unlock
MESSAGE_FILE=$DIR/message
HTML_ANSWER_FILE=$DIR/last-answer.html
ERROR_FILE=$DIR/last-error-output
CA_PATH=$DIR/certs

openssl s_client -connect dukath-www.rz.uni-karlsruhe.de:443 -quiet \
 -CApath $CA_PATH -verify -1 \
 < $MESSAGE_FILE > $HTML_ANSWER_FILE 2> $ERROR_FILE

Die Datei gibt es auch unten in der Download-Sektion. Beim eventuellen, direkten Kopieren des Skrips aus dem Browser darauf achten, daß nach den Backslashes jeweil kein Zeichen mehr vorkommen darf.

Da diese Datei als Cronjob ausgeführt werden soll, muß sie auch als ausführbar markiert werden:

chmod u+x dukath-ip-unlock.sh

Die manpage zu openssh s_client (man 1 s_client) besagt:

Currently the verify operation continues after errors so all the
problems with a certificate chain can be seen. As a side effect the
connection will never fail due to a server certificate verify failure.

Genau deswegen wird openssh s_client mit dem Parameter -verify -1 aufgerufen.

Schritt 6

Man erstelle die Datei /home/dukath-unlock/dukath-ip-unlock/message mit dem POST-Request als Inhalt, also:

POST /cgi-bin/login.pl HTTP/1.0
User-Agent: foo/23.5
Accept: text/*
Host: dukath-www.rz.uni-karlsruhe.de:443
Content-type: application/x-www-form-urlencoded
Content-length: 34

login=BENUTZERNAME&pass=PASSWORT&go=anmelden

Wobei BENUTZERNAME und PASSWORT entsprechend ersetzt werden müssen, bei dem Passwort handelt es sich um das VPN-/IP-Sec-Passwort.

Da diese Datei eben das DUKATH-Passwort enthält, sollte man die Rechte so ändern, daß sie nur für den Benutzer, unter dem das Skript laufen soll, lesbar ist. Beispielsweise mit dem Befehl

chmod u=rw,og= message 
Eventuelle Überbleibsel vom Editieren der Datei löschen:
rm message~

Schritt 7

Jetzt benötigt man die passenden Zertifikaten. Man findet auf der Webseite Uni-Karlsruhe Certification Authority. Man benötigt jeweils aktuelle Versionen vom DFN Top Level CA-, dem UNIKA-CA-, sowie dem UNIKA-S-Zertifikat. Die Datein kommen in das Verzeichnis /home/dukath-unlock/dukath-ip-unlock/certs und sollten auf .pem endende Namen erhalten, beispielsweise "DFNPCA-02.pem", "UNIKA-02_2002-2005.pem" und "UNIKA-S-04_2004-2005.pem".

Schritt 8

Mit dem Perl-Skript c_rehash, das zum OpenSSL-Paket gehört, werden die notwendigen symbolischen Links für die Zertifikate erstellt:

c_rehash /home/dukath-unlock/dukath-ip-unlock/certs

Man kann dies auch manuell machen, wie das geht steht auf der manpage von openssl verify (man 1 verify), beispielsweise:

ln -s UNIKA-S-04_2004-2005.pem certs/1e162601.0;
ln -s DFNPCA-02.pem certs/58b68fb7.0;
ln -s UNIKA-02_2002-2005.pem certs/58fc36f8.0

Schritt 9

Jetzt sollte man das Skript eigentlich starten können, testweise mit:

./dukath-ip-unlock.sh

last-answer.html enthält danach die zurückgelieferte Webseite (enschließlich des HTTP-Headers), wenn man will sollte man sie trotz des Headers mit einem Browser ansehen können.

last-error-output enthält die Ausgabe, die von openssh s_client an die Standard-Fehlerausgabe geschickt wurde; im Standardfall (bzw. so wie wir openssl s_client aufrufen, nämlich mit dem Parameter -quiet) protokoliert sie die Überprüfung des Server-Zertifikats.

Falls last-answer.html also anschließend keine Webseite mit dem Satz Sie wurden erfolgreich angemeldet! und last-error-output nicht viermal eine Zeile mit dem Inhalt verify return:1 enthält, gab es leider irgendein Problem..

Schritt 10

Jetzt muß nur noch der eigentliche Cronjob eingetragen werden. Dies geschieht durch:

cronjob -e
In diese Datei werden folgende Zeilen eingefügt:

SHELL=/bin/sh
*/3  * * * *    /home/dukath-unlock/dukath-ip-unlock/dukath-ip-unlock.sh

Bitte beachten, daß laut der crontab-manpage (man 5 crontab) die zweite Zeile unbedingt durch einen Zeilenwechsel abgeschlossen werden muß.

*/3 bedeutet, daß das Skript alle 3 Minuten ausgeführt werden soll. Da sich die DUKATH Web-Interface-Seite nach dem Einloggen alle 150 Sekunden neuladen will, soll das wohl okay sein.

Schritt 11

Da man sich nicht direkt als Benutzer dukath-unlock einloggen können muß, kann man das auch gleich verbieten, indem wir im Passwortfeld zu dem User in der Datei /etc/shadow einen ungültigen String -- beispielsweise * oder ! -- eintragen (siehe man 5 shadow). Also die Zeile, die mit dukath-unlock: anfängt, so verändern, daß zwischen dem ersten Doppelpunkt und dem zweiten nur ein einzelnes Ausrufezeichen steht.

Hierbei sollte man aus offensichtlichen Gründen nichts falsch machen. Falls man diesen Weg also lieber nicht wählen möchte, kann man alternativ vielleicht auch das Passwort auf eine komische, lange, nicht erratbare Zeichenfolge ändern mit:

passwd dukath-unlock

So, fertig! (Hoffentlich..)


Nachtrag

Inzwischen habe ich gesehen, daß es durchaus auch eine SSL-fähige Variante von netcat namens nssl gibt. Naja, was soll's.. Da nssl ebenfall die OpenSSL verwendet, kann man die Zertifikate ins Standart-Zertifikatsverzeichnis der Bibliothek werfen (bei Debian /etc/ssl/certs/); danach c_rehash nicht vergessen. Außerdem sollte man darauf achten, daß die Zertifikate auch wirklich überprüft werden.. Ich sehe aber eigentlich keinen Grund, warum man nicht einfach openssl s_client verwenden sollte.


Download



Max-Gerd Retzlaff <m.retzlaff@gmx.net>, <mgr@bl0rg.net>, or <mgr@vantronix.net>
GnuPG- / OpenPGP-Information:
   Type bits/keyID    Date       User ID
   pub  1024/81239F12 2002/03/12 Max-Gerd Retzlaff <mgr@hannover.ccc.de>
             Key fingerprint =  49 CD 21 F2 41 AC 72 C5  D0 D1 27 DC C2 B2 48 AE  81 23 9F 12 
   uid                           Max-Gerd Retzlaff <m.retzlaff@gmx.net>
   sub  4096g/63E36E39 2002-03-12
   local copy of the key

Last modified: Thu Oct 7 00:11:28 CEST 2004