Arme-Leute-Rechteverwaltung mit SSL-Client-Zertifikaten

Für ein Projekt administriere ich einen Server, auf dem verschiedene Webanwendungen laufen. Sicherheitspolicy ist, daß ein Zugriff darauf nur über https und Client-Zertifikaten möglich sein darf - so weit, so einfach.
Eine der Anwendungen ist gitlab, eine github-ähnliche Weboberfläche für git-Repositories. Erfreulicherweise begeisterten sich immer mehr Leute, die nicht direkt zum Projekt gehörten, für git... und dann folgte der Klassiker: Es soll nun Leute geben, die ausschließlich auf gitlab, aber auf keine der anderen Anwendungen zugreifen können. Also mußte zusätzlich zur Authentisierung noch eine Authorisierung her... aber wie? Die Rechtekontrolle sollte auf Basis von URL (bzw. URL-Teil) sowie den Client-Zertifikaten erfolgen und außerdem "abwärtskompatibel" zu den bereits ausgegebenen Zertifikaten sein.
Wer ebenfalls in eine solche Situation kommt - folgende Möglichkeiten sind mir hierzu eingefallen:

Mehrere CAs

Das Zertifikat der CA, von welcher die Client-Zertifikate ausgestellt sein müssen, wird mittels

SSLCACertificateFile /pfad/zum/zertifikat.crt

konfiguriert. Diese Datei kann aber mehrere Zertifikate beinhalten - Apache akzeptiert dann Client-Zertifikate von all diesen CAs. Eine Möglichkeit wäre somit gewesen, eine neue CA für den eingeschränkten Benutzerkreis aufzusetzen; Nachteil wäre jedoch (abgesehen vom zusätzlichen Verwaltungsaufwand), daß die Beschränkung nur pro vhost möglich wäre. Obendrein wird das ganze kompliziert, wenn manche Benutzer mehrere Zertifikate installieren müssen.
Die Möglichkeit mehrerer CAs ist also ein interessantes Faktum, aber keine Lösung für meinen Anwendungsfall.

Zugriffsbeschränkung auf einzelne Zertifikate

Eine weitere Möglichkeit besteht in der Fake Basic Authentication. Hier wird der Distinguished Name des Zertifikats als Username, sowie das Passwort "password" an die Basic Authentication durchgereicht. Man konfiguriert also den Zugriffsschutz für einen bestimmten Pfad mittels

<Location /your/webpath>
  SSLOptions         +FakeBasicAuth
  AuthType           Basic
  AuthBasicProvider  file
  Require            valid-user
  AuthUserFile       /path/to/your/httpd.passwd
</Location>

und generiert eine passende httpd.passwd, z.B.
/O=My fancy company/CN=Hugo Hansel:xxj31ZMTZzkVA
/O=My fancy company/CN=Colonel Panic:xxj31ZMTZzkVA
/O=My fancy company/CN=General Protectionfault:xxj31ZMTZzkVA

In meinem Fall wäre das zwar ein Ansatz gewesen, hätte aber bedeutet, daß ich jeden neuen Nutzer des Dienstes in der Zugriffsdatei hätte nachpflegen müssen - ein Aufwand, den ich mir nicht antun wollte.

Gruppen/Rollen mittels Regular Expression Matching

Nun also der von mir gewählte Ansatz, welcher mir die gewünschte Flexibilität bietet und dennoch den Verwaltungsaufand gering hält: Mit der Direktive SSLRequire besteht die Möglichkeit, auf den Inhalt der Felder des Zertifikats zu prüfen. In meinem Fall sah das folgendermaßen aus:

<Location /my/path>
  SSLRequire %{SSL_CLIENT_S_DN_L} == "" or %{SSL_CLIENT_S_DN_L} =~ m/^.*\+myservice\+.*$/
</Location>

Beim Durchsehen der bestehenden Zertifikate hatte ich festgestellt, daß das Feld Locality Name in keinem der bestehenden Zertifikate benutzt wurde. Daher entstand die obige Regel: Sie erlaubt den Zugriff, wenn das Feld entweder leer ist (Kompatibilität zu den bereits ausgegebenen Zertifikaten) oder aber den String "+myservice+" enthält.
Die Idee hinter "+myservice+": Es ist so möglich, auf verschiedene Dienste zu prüfen. Als Trennzeichen (welches nicht im Name der Dienste vorkommen darf) habe ich mich willkürlich für das Plus entschieden. Somit bekommen Zertifikate, welche im Feld Locality Name eine Angabe wie "+myservice+", "+myservice+myotherservice+" oder "+yetanotherservice+myservice+" beinhalten, Zugriff.
Eine weitere Überlegung, die man bei diesem Ansatz anstellen sollte: Kommt später ein neuer Dienst hinzu, muß man die Zertifikate der Leute, die auch Zugriff erhalten sollen, austauschen. Sinnvoller ist es, sich über ein Rollenkonzept gedanken zu machen und statt Bezeichern von Diensten Rollennamen zu verwenden. Momentan erhalten Zertifikate mit "+student+" nur Zugriff auf gitlab - sollte es in Zukunft einen weiteren Web Service geben, auf den alle Studenten zugreifen sollen, so muß nur die Authorisierungsregel in der Apache-Konfiguration angepaßt werden - die bereits an Studenten ausgegebenen Zertifikate müssen nicht aktualisiert werden.

comments powered by Disqus