REST-Schnittstelle von FreeIPA

Einfach eingesteckt

Der Zugriff auf das Identity-Management Framework FreeIPA erfolgt üblicherweise über ein grafisches Webinterface oder ein Kommandozeilen-Tool. Aber FreeIPA lässt sich auch über eine API-Schnittstelle ansprechen. Der Open Source-Tipp in diesem Monat verrät, wie der Zugriff mittels JSON-RPC gelingt.
Die Suche nach Fehlern im Unternehmensnetz ist meist aufwendig und zeitraubend. Mit dem richtigen Ansatz und den passenden Werkzeugen jedoch machen sich Admins ... (mehr)

Wer schon einmal eine Anfrage an das FreeIPA-Framework gestellt hat, der wird wissen, dass die allermeisten Aktionen nur dann erfolgreich sind, wenn vor dem Zugriff eine erfolgreiche Authentifizierung stattgefunden hat. Diese kann entweder mittels Kerberos oder eines Passwortes erfolgen. Hierbei spielt es erst einmal keine Rolle, ob die Authentifizierung über das Webinterface oder mittels des Kommandozeilen-Tools ipa geschieht. Die Javascript-basierte Webapplikation wird beim Zugriff innerhalb des aufrufenden Browsers ausgeführt, und sämtliche Anweisungen für das Framework finden schließlich innerhalb einer gesicherten HTTPS-Verbindung mittels JSON-RPC statt. Das Tool ipa nutzt die Python-API des Frameworks, um den Zugriff zu abstrahieren. Wer diese API verwenden möchte, muss das Paket free-ipa-python (ipa-python) installieren, um in seinen Skripten das Modul ipalib importieren zu können.

Die direkte Abfrage des Frameworks über die JSON-RPC-API ist gerade dann sinnvoll, wenn der Zugriff von einem System erfolgt, das nicht Teil der FreeIPA-Domäne ist. Das ist beispielsweise der Fall, wenn Daten des Servers von einem anderen Webtool ausgelesen oder manipuliert werden sollen. Eine Abfrage besteht immer aus der gewünschten Methode, gefolgt von einem Array aus Argumenten und Optionen. Die Methodennamen der JSON-RPC API sind dabei identisch mit denen der Python-API. So existiert beispielsweise ein FreeIPA-Plug-in "User", das verschiedene Klassen zur Verwaltung von Benutzern zur Verfügung stellt. Die einzelnen Klassen-Namen sind dabei identisch mit den Argumenten, die dem ipa-Tool zu übergeben sind. So lautet die Anweisung zum Anlegen eines neuen Benutzers etwa »ipa user-add« , die entsprechende Klasse in der Python-API heißt daher user_add. Und dies ist eben auch der Name der Methode, die beim Zugriff auf die JSON-RPC Schnittstelle zu verwenden ist.

Seit der FreeIPA-Version 4.2 existiert innerhalb des grafischen Webinterfaces ein API-Browser, der die einzelnen Methoden beschreibt. Ansonsten ist es auch möglich, das Tool ipa im verbose-Mode aufzurufen (Option "-vv"). Die Ausgabe zeigt die verwendete Methode zusammen mit den Parametern entsprechend an (Listing 1).

Listing 1: Aufruf von ipa im verbose Mode



# ipa -vv user-add --first foo --last bar foobar
[...]
ipa: INFO: Forwarding 'user_add' to json server 'https://ipa01.example.com/ipa/session/json'
ipa: INFO: Request: {
      "id": 0,
      "method": "user_add",
      "params": [
             [
                   "foobar"
             ],
             {
                   "all": false,
                   "cn": "foo bar",
                   "displayname": "foo bar",
                   "gecos": "foo bar",
                   "givenname": "foo",
                   "initials": "fb",
                   "krbprincipalname": "foobar@EXAMPLE.COM",
                   "no_members": false,
                   "noprivate": false,
                   "random": false,
                   "raw": false,
                   "sn": "bar",
                   "version": "2.156"
             }
      ]
}
[...]

Zugriff via JSON-RPC

Um den Benutzer mit einem direkten Zugriff auf die JSON-RPC API anlegen zu können, sind die Aufrufe in entsprechende HTTPS-Anfragen umzuwandeln. Beispielhaft kommt in diesem Open

Source-Tipp der Kommandozeilenbrowser curl zum Einsatz. Bevor es an die Entwicklung eines entsprechenden Skripts geht, ist zu bedenken, dass FreeIPA zwei unterschiedliche Einstiegspunkte zur Authentifizierung eines Benutzers zur Verfügung stellt. Somit ist es möglich, einen Benutzer mittels eines Kerberos-Tickets oder eines einfachen Passwortes anzumelden. Die beiden Einstiegspunkte lauten entsprechend "https://$IPAHOSTNAME/ipa/session/login_kerberos" respekti- ve "https://$IPAHOSTNAME/ipa/session/login_password".

Desweiteren ist zu bedenken, dass die Authentifizierung eines Benutzers im Vorfeld stattfindet und der Server ein Session-Cookie zur Verfügung stellt, das während des Aufrufs der gewünschten Methode zum Einsatz kommt. Außerdem verlangt FreeIPA einen HTTP-Referrer, der auf den IPA-Server selbst verweist. Somit wird Cross-site Request Forgery (XCRF/CSRF) Angriffen vorgebeugt.

Damit der Zugriff über einen sicheren HTTPS-Kanal funktioniert, ist das CA-Zertifikat des FreeIPA-Systems bereitzustellen. Desweiteren wird auch eine Kerberos-Konfigurationsdatei benötigt, damit der Client einen Benutzer mittels eines Kerberos-Tickets authentifizieren kann. Im einfachsten Fall wird diese Datei einfach von einem FreeIPA-System kopiert. Um nicht mit einer anderen Kerberos-Konfiguration zu kollidieren, wird ein alternativer Dateiname gewählt, der dem System dann über die Umgebungsvariable KRB5_CONFIG mitgeteilt wird.

Ein API-Browser innerhalb des Webinterfaces beschreibt die einzelnen API-Methoden.

JSON-RPC-Shell-Skript

Das Beispiel-Skript aus Listing 2 setzt all diese Anforderungen um. Das Skript soll einen neuen Benutzer mittels einer direkten Anfrage an die JSON-RPC-API des Identity-Management Frameworks anlegen. Der Benutzer muss sich beim ersten Aufruf authentifizieren. Dies gelingt entweder mittels Kerberos oder eines regulären Benutzer-Passworts. Im ersten Fall wird über kinit ein entsprechendes TGT vom Kerberos-Server des IdM-Systems angefordert, das später dazu dient, ein entsprechendes Service-Ticket für das IPA-System anzufordern. Im letzteren Fall findet eine einfache Formular-basierte Anmeldung statt. Der eingegebene Benutzername und das Passwort werden mittels einer POST-Anweisung auf den Server übertragen. Hat die Anmeldung geklappt, dient ein Cookie beim Aufruf der user_add-Methode zur Autorisierung.

Listing 2: Anlegen eines neuen Benutzers per API



#!/bin/sh
export COOKIEJAR=/tmp/ipa-$$
export IPAHOSTNAME=ipa01.example.com
if [ $# -ne 1 ]; then
      echo -e "Bitte krb oder pass als Argument angeben." && exit 1
fi
# Die Authentifizierung des Benutzers, falls noch kein Cookie existiert.
if [ ! -f $COOKIEJAR ] ; then
      if [ $1 = "krb" ] ; then
           export KRB5_CONFIG=/etc/krb5-ipa.conf
           kinit admin
           curl -v \
           -H referer:https://$IPAHOSTNAME/ipa \
           -c $COOKIEJAR -b $COOKIEJAR \
           --cacert /etc/ipa/ca.crt \
           --negotiate -u : \
           -X POST \
           https://$IPAHOSTNAME/ipa/session/login_kerberos
      else
           read -p "Bitte Benutzernamen eingeben: " username
           read -s -p "Bitte Passwort eingeben: " password
           curl -v \
           -H referer:https://$IPAHOSTNAME/ipa \
           -H "Content-Type:application/ x-www-form-urlencoded" \
           -H "Accept:text/plain"\
           -c $COOKIEJAR -b $COOKIEJAR \
           --cacert /etc/ipa/ca.crt \
           --data
      "user=$username&password=$password" \
           -X POST \
           https://$IPAHOSTNAME/ipa/session/login_password
           fi
fi
# Aufruf der eigentlichen Methode
curl -v \
      -H referer:https://$IPAHOSTNAME/ipa \
           -H "Content-Type:application/json" \
           -H "Accept:applicaton/json" \
           -c $COOKIEJAR -b $COOKIEJAR \
           --cacert /etc/ipa/ca.crt \
           -d '
      {"method":"user_add","params":[["foobar"],{ "cn": "foo bar", "displayname": "foo bar", "gecos": "foo bar", "givenname": "foo", "initials": "fb", "krbprincipalname": "foobar@EXAMPLE.COM",   "no_members": false, "noprivate": false, "random": false, "raw": false, "sn": "bar" }],"id":0}'\
           -X POST \
      https://$IPAHOSTNAME/ipa/session/json

Zur Speicherung der Authentifizierungsinformationen kommen Cookies zum Einsatz, die curl in einer Datei speichert. Hinter dem Schalter "-b" erwartet curl eine Cookie-Datei, die es für einen Request verwendet, hinter "-c" folgt ein File, in das curl die vom Server gelieferten Cookies speichert. Hier wird beide Male die gleiche Datei "/tmp/ipa-$$" verwendet, wobei die Zeichen "$$" im Shellskript für die aktuelle Prozess-ID stehen.

comments powered by Disqus
Einmal pro Woche aktuelle News, kostenlose Artikel und nützliche ADMIN-Tipps.
Ich habe die Datenschutzerklärung gelesen und bin einverstanden.

Konfigurationsmanagement

Ich konfiguriere meine Server

  • von Hand
  • mit eigenen Skripts
  • mit Puppet
  • mit Ansible
  • mit Saltstack
  • mit Chef
  • mit CFengine
  • mit dem Nix-System
  • mit Containern
  • mit anderer Konfigurationsmanagement-Software

Ausgabe /2023