User-Login Absicherung

Aus Physik
Wechseln zu: Navigation, Suche

Problem

Als jeder Seiten editieren konnte wurden Wiki-Seiten durch Linksammlungen ersetzt.

Als Zwischenlösung dürfen nur angemeldete User editieren und das Registrieren neuer User ist derzeit nicht möglich.


Ziel

Auf jeden Fall soll das Lesen weiterhin für alle möglich sein.

Minimal:

Das automatisierte Erstellen von User-Accounts soll unterbunden werden

Optimal:

  • Nur angemeldete User dürfen editieren.
  • User-Authentifizierung mit Kerberos.
  • (Möglichst) Keine Änderung im Wiki-Code

Das bedeutet

  • Wer ein Kerberos-Ticket erhält, darf sich auch im Wiki anmelden
    • => Nur wer ein Computerraum Account hat kann sich anmelden
  • Benutzer brauchen sich kein weiteres Passwort zu merken


Lösung

Grundlegende Funktionalität

Durch den Anmelde-Link im Wiki wird man auf eine durch Kerberos abgesicherte Seite weitergeleitet. Von dieser aus wird nach erfolgter Anmeldung (über den Browser) nur ein Skript ausgeführt, welches einen HTTP-Request an die Anmeldeseite vom Wiki schickt. Die in der Antwort enthaltenen Cookies werden auf dem Client gespeichert und man wird wieder auf die Startseite des Wiki weitergeleitet. Von diesem Skript ist für den User nichts zu sehen.

Für die Authentifizierung wird nur Kerberos verwendet, die Daten in der Wiki-DB sind irrelevant. Danach ist man mit dem Usernamen der Authentifizierung angemeldet. Sollte dieser im Wiki noch nicht bekannt sein, wird ein neuer User mit diesem Namen angelegt.


Infrastruktur

  • Im Wiki
    • wikidir/index.php:
      vor dem Block, der mit # If the user is not logged in, anfängt, eine if-Abfrage einbauen, in der die Weiterleitung an den gesicherten Bereich erfolgt
    • Klasse von AuthPlugin ableiten:
      liegt in wikidir/extensions/Auth_Apache.php, ist zuständig für die eigentliche Anmeldeprozedur
    • wikidir/LocalSettings.php:
      Unter dem Namen $wgAuth muss eine neue Instanz dieser Klasse angelegt werden.
  • Das Skript im abgesicherten Bereich
    /srv/www/secure/wikilogin/KerberosLogin.php
    muss angelegt und über eine URL (derzeit https://itp.tugraz.at/wikilogin/KerberosLogin.php) erreichbar sein. Darin muss auch auf die PEAR-Pakete verwiesen werden.
  • PEAR
    • Das PEAR-Basispaket und die PEAR-Pakete HTTP_Request, NET_URL und NET_Socket müssen installiert sein.
    • Leider kann man sie nicht einfach ohne Änderungen entpacken. Am einfachsten ist es, deren Inhalte ein eine passende Verzeichnisstruktur zu legen. Eine so aufbereitete Umgebung liegt in
      /srv/www/secure/wikilogin/PEAR

Quellen

http://meta.wikimedia.org/wiki/Auto_Login_via_REMOTE_USER


Weitere Lösungsansätze

Formular mit Absicherung gegen automatische Eingaben

Ein Formular für die Registrierung neuer User wird mit irgendeinem Mechanismus vor automatischen Eingaben geschützt. Siehe Anmeldung bei PHPBB!

Vorteile:

  • (vermeindlich) schnelle Lösung
    • Vielleicht Code aus PHPBB verwendbar

Nachteile

  • Nur Absicherung gegen automatische Eingaben


Anbindung ans PHPBB

Hier gibt es eine Mediawiki Extension, mit welcher in der Userdatenbank des Forums nach dem User gesucht wird. Ist ein User, der sich anmelden will, nicht in der Wiki-DB, wird jedoch in der PHPBB-DB gefunden, so wird er auch in die Wiki-DB eingetragen und angemeldet.

Diese Extension ist übrigens eine Child-Klasse von AuthPlugin.

Vorteile:

  • Extension ist bereits programmiert

Nachteile

  • Kopplung ans PHPBB
  • Nicht jeder Computerraum-Nutzer hat auch ein PHPBB-Account


Authentifizierung über gssapi/kerberos

Childklasse von AuthPlugin.php, bei der sich der Benutzer über gssapi od. direkt über kerberos authentifiziert.

Als Ausgangspunkt kann die PHPBB-Extension verwendet werden.

Vorteile

  • Am einfachsten für den Benutzer, gleiche Logindaten wie itp-account
  • Sicherheit über SSL genügt
  • Konsistente Lösung
  • Keine Änderungen am Wiki
  • Keine zweite Benutzerdatenbank
  • Keine Eingriffe in die WikiDB - Auf neue mediawiki-Versionen sollte nicht reagiert werden müssen
  • Beim Einsatz eines "kerberosfähigen"-Browsers (z.B. Firefox, Mozilla) kein Einloggen des Benutzers nötig, wenn die Klasse schön programmiert wird

Nachteile

  • gssapi php Anbindung muss teilweise selber geschrieben werden bzw. aus dem Source der IMAP-php Klassen geholt werden.
  • (Vielleicht) eigenes php-Paket notwendig, dass am Server installiert werden muss, um die Lösung sauber zu halten.


Variante: Ticket anfordern

Das Wunschziel!

Das Problem bei dieser Methode ist, dass noch kein Weg gefunden wurde, wie man aus PHP heraus ein Kerberos-Ticket anfordert.

Vorteile:

  • Authentifizierung direkt über Kerberos
  • PHPBB-Extension kann als Basis verwendet werden

Nachteile

  • keine schnelle, leichte Lösung in Sicht.


Variante: Kontaktaufnahme mit dem Server

Das Wunschziel?

Die Idee ist, das PHP-Modul KADM5 zu verwenden. Dieses stellt Funktionalitäten zur Verwaltung eines Kerberos Servers zur Verfügung. Damit kann u.A. nach Principals gesucht werden:

 kadm5_get_principal  -- Gets the principal's entries from the Kerberos database
 kadm5_get_principals -- Gets all principals from the Kerberos database

Allerdings kann man damit keine Passwortüberprüfung vornehmen.

Mit

 kadm5_init_with_password -- Opens a connection to the KADM5 library and initializes any neccessary state information

könnte man vielleicht tricksen: Man versucht mit Principal und Passwort eine Verbindung zum Kerberos-Server herzustellen, stimmen die Daten nicht, liefert die Funktion FALSE. Allerdings muss erst versucht werden, ob das für alle Kerberos-User geht oder nur für Admins.

Die Verbindung kann dann sofort wieder geschlossen werden.

Vorteile:

  • Kerberos wird verwendet
  • Einfache Programmierung

Nachteile

  • Keine weiteren Userdaten abrufbar
    • User muss Emailadresse und Realname selbst eintragen (kann ja höflich darauf hingewiesen bis dazu gezwungen werden)
  • Sicherheit??

Authentizierung über Kerberos mit kinit

Man kann über ein shell escape kinit auch direkt aufrufen - ein kleines Experiment zeigt, daß der return value als Zeichen eines erfolgreichen Logins verwendet werden kann: ich hab dazu kinit einmal mit einem falschen und einmal mit dem korrekten Passwort aufgerufen:

[ahi@faeppc45 ahi]$ kinit ahi; echo $?
Password for ahi@ITP.TUGRAZ.AT: 
kinit(v5): Password incorrect while getting initial credentials
1
[ahi@faeppc45 ahi]$ kinit ahi; echo $?
Password for ahi@ITP.TUGRAZ.AT: 
0

Wie übergibt man das Passwort? Man kann das Passwort über ein Pipe an kinit weiterreichen, aus verständlichen Gründen gibts dazu kein Beispiel.

  • Vorteile:
    • Es ist kein zusätzliches Service (zB IMAP) involviert.
  • Nachteile:
    • Username und Passwort müssen vor der Übergabe jedenfalls auf die Vermeidung von shell escapes geparst werden. Gibt es ein Äquivalent zu Perls system mit getrennten Parametern in PHP? Kann man in PHP Variablen als tainted markieren?

Bei Benutzernamen: http://www.php-faq.de/q/q-security-variablen.html bei Variablen mit vorgegebenen Werten aus einer Wertemenge, wobei in der Wertemenge alle Benutzernamen des Systems liegen. (z.b. aus /afs/itp.tugraz.at/users) Beim Passwort glaub ich nicht so wichtig, da gepiped, da kann man irgendeine PHP-Funktion nehmen, die die Systemaufrufe rausparst. Zu den Äquivalenten von Perls Funktionen: Irgendwo hab ich Source herumliegen, wo ich so etwas ähnliches schon einmal gemacht habe..


Verwenden der Authentifizierung des Browsers

Das Apache-Modul ist bereits installiert, es bräuchte lediglich die Umgebungsvariable REMOTE_USER überprüft werden. Zwei Varianten:

 $username = getenv("REMOTE_USER");
 $username = $_SERVER['REMOTE_USER'];

Übrigens sollte, wenn PHP als Modul eingebunden ist, phpinfo() alle Umgebungsvariablen aufzählen.

Vorteile:

  • Kerberos wird verwendet
  • Einfache Programmierung

Nachteile

  • Diverse Browser verhalten sich nicht optimal

Fragen

  • Kann man die Apache-Konfiguration so ändern, dass nur bei einem einzelnen File die Kerberos-Authentifizierung verlangt wird, od. lauft das Verzeichnisweise?
  • Wenn nur für das Anmeldeformular die Kerberos-Authentifizierung abläuft, wie gibt man die Authentifizierung weiter?
    • ANTW: Wenn der User sich authentifiziert hat, dann ist er ja im Wiki angemeldet => d.h. das Wiki weiß eh ganz automatisch Bescheid
  • Wie erreicht man, dass man beim Aufruf des Wikis (Hauptseite) schon automatisch angemeldet wird (Firefox) od. nach Passwort gefragt wird (Mozilla) und dass man, wenn jemand das ohne gültigen Account aufruft, er/sie trotzdem die Seiten lesen kann? Umsetzung desselben siehe z.B. https://itp.tugraz.at/test/snoop.jsp


Externes Formular auf Kerberos-geschützter Seite

Formular für die Registrierung neuer Benutzer auf einer externen Seite, auf welcher man sich über Kerberos authentifizieren muss.

Der erste, schnelle Versuch; beinahe ausprogrammiert.

Die Technologie zur Absicherung einer Seite gibt es bereits, das Formular wurde so programmiert, dass jene Klassen, die im Wiki verwendet werden, auch hier benutzt werden. Mit dem Formular ist es möglich einen neuen User in die DB einzutragen, allerdings gibt es ein Problem mit dem eingegebenen Passwort, so dass sich der neue User damit nicht anmelden kann. Jedoch kann er sich bei der Wiki-Anmeldeseite ein neues Passwort zusenden lassen, mit dem die Anmeldung dann möglich ist.

Mögliche Fehlerursache: Variable für die Codierung des Passwortes nicht korrekt, da das Wiki ja nicht wirklich läuft?

Ein Verzicht auf die Wiki-Klassen dürfte recht umständlich werden. Der direkte Zugriff auf die DB funktioniert zwar, (wurde getestet) jedoch müsste trotzdem eine Variable aus dem Wiki geholt werden um das Passwort korrekt zu verschlüsseln. Außerdem dürfte es recht kompliziert werden z.B. die User-Einstellungen richtig einzutragen, da diese in einem Blob stecken, welcher erst richtig zusammengebaut werden müsste.

Vorteile:

  • (vermeindlich) schnelle Lösung
  • keine Änderung im Wiki

Nachteile

  • Passwort in die DB eintragen funktioniert nicht so ganz => etwas umständlichere Handhabung für den User
    • dies wäre aber auch ein zusätzlicher Sicherheitsaspekt, der aber unnötig sein sollte, da die Seite bereits über Kerberos abgesichert ist
  • Zugriff auf die Wiki-DB von außen
  • Im Formular musste das Wiki als aktiv deklariert werden, obwohl eigenlich nicht das ganze Wiki läuft => Hackalarm!
  • User hat nach wie vor extra Registrierungsdaten für das Wiki


Externes Formular auf Kerberos-geschützter Seite mit Childklasse von AuthPlugin.php

Man kann eine Childklasse von AuthPlugin.php auch extern verwenden, siehe diese Anleitung

Eine einfachere Variante: http://meta.wikimedia.org/wiki/Auto_Login_via_REMOTE_USER

Dies wäre im Prinzip wie die oben geschilderte Variante, nur eleganter und die Sache mit dem Passwort dürfte funktionieren.


Java Applet mit Authentifizierung über gssapi/kerberos -> JAAS

JAAS ist eine Sammlung von APIs welche auch Kerberos unterstützt, wobei auch die Verwendung in einem Applet möglich ist.

Vorteile:

  • Kerberos
  • kein allzu großer Programmieraufwand

Nachteile

  • zusätzliches Applet in der Seite


Authentifizierung über IMAP (AuthPlugin)

Childklasse von AuthPlugin.php, bei der sich der Benutzer über IMAP authentifiziert.

Vorteile

  • siehe oben, nur muss man sich immer authentifizieren, auch wenn mann schon ein Ticket hat
  • sehr einfach zu schreiben, da php schon alles mitbringt (Ein 10-Zeiler)
    • außerdem kann die PHPBB-Extension als Basis benutzt werden

Nachteile

  • wechselseitige Abhängigkeiten ;-)


Stand der Dinge

Externes Formular auf Kerberos-geschützter Seite ist teilweise implementiert. Das Formular liegt noch nicht auf einer geschützten Seite, außerdem funktioniert das Speichern des Passwortes nicht.

Die schnellste Möglichkeit dies fertigzustellen wäre, die Passworteingabe aus dem Formular zu nehmen und den User zu bitten sich ein neues Passwort schicken zu lassen.

Ein wenig aufwändiger wäre es, dem User ein zufällig generiertes Passwort automatisch zu schicken.


Authentizierung über Kerberos mit kinit ist programmiert und wurde teilweise getestet. Die Authentifizierung eines Benutzers, welcher ein ITP- und Wiki-Account besitzt, funktioniert. Ein Test mit einem Benutzer ohne Wiki-Account steht derzeit noch aus.
Diese Authentifizierung kann in den letzten Zeilen der LocalSettings.php (de-)aktiviert werden. Derzeit ist sie nicht aktiv.


Externes Formular auf Kerberos-geschützter Seite mit Childklasse von AuthPlugin.php LÄUFT!!! und ist in Betrieb.
Meldet sich ein User an, welcher zuvor noch kein Wiki-Account hatte, so werden seine Emailadresse auf "<username>@itp.tugraz.at" und sein Realname auf "I have to fill in my realname" gesetzt.


Allgemeines / offene Fragen

Wiki-User-DB erhalten?

Die User-Tabelle in der Wiki-DB soll erhalten bleiben und alle User beinhalten (weil das Wiki darauf zugreift, außerdem werden benutzerspezifische Einstellungen gespeichert).