Kerberos KDC replication mit systemd units

Um eine automatische Replikation des primären Kerberos KDC mit dem sekundären zu erzielen, müssen auf beiden Rechner systemd service units eingerichtet werden. Zumindest unter Ubuntu 16.04 LTS sind diese in keinster Weise vorhanden, weswegen hier auf die Einrichtung eingangen wird.

Service Unit auf dem sekundären (slave) KDC

Auf dem slave KDC muss eigentlich lediglich der kpropd service als stand-alone Instanz gestartet werden. Ursprünglich war der kpropd service auf den (x)inetd master-daemon ausgelegt. Da dieser mittlerweile fast obsolet wurde benutzen wir den stand-alone service, der ab Version 1.11 des kpropd automatisch erkannt wird.
Für das automatische Starten während des Boot-Vorgangs benötigt man mittlerweile ein systemd service unit file, das in unserem Fall folgendermaßen aussieht.


[Unit]
Description=Krb5-KDC replication service
Requires=krb5-kdc.service
After=network-online.target
Wants=network-online.target

[Service]
ExecStart=/usr/sbin/kpropd
Type=forking
ReadOnlyDirectories=/
ReadWriteDirectories=/var/tmp /tmp /var/lib/krb5kdc /var/run /run /var/log


[Install]
WantedBy=multi-user.target

Ein Verifikation mit dem systemd hauseigenen Tool sollte keine syntaktischen Fehler ergeben.

systemd-analyze verify kpropd.service

Auf dem Weg zu der hier abgebildeten service unit, gab es zwei große Stolpersteine, welche syntaktisch aber einwandfrei waren, weswegen das verificiation Tool hierbei keine Hilfestellung leisten konnte.
Der erste war die Direktive
Type=forking
Nur damit kann der systemd erkennen, dass es ein typischer geforkter UNIX daemon ist, der nicht sofort als dead (vom Startprozess her) markiert wird. Die Alternative wäre das Setzen des -d (debug) flags, der den Startprozess permanent als ein foreground Prozess behält.
Der zweite, noch größere Stolperstein, kommt von den unterschiedlichen After/Wants Direktiven. In den meisten Tutorials über systemd wird immer auf
After=network.target
verwiesen, was in diesem Fall zu einem gescheiterten Start von kpropd führt, beispielhaft ausgeführt an folgendem syslog Eintrag.


Mar 18 21:57:30 aurora systemd[1]: Started Light Display Manager.
Mar 18 21:57:30 aurora systemd[1]: Started Raise network interfaces.
Mar 18 21:57:30 aurora systemd[1]: Reached target Network.
Mar 18 21:57:30 aurora systemd[1]: Started Unattended Upgrades Shutdown.
Mar 18 21:57:30 aurora systemd[1]: Started Krb5-KDC replication service.
Mar 18 21:57:30 aurora systemd[1]: Started BIND Domain Name Server.
Mar 18 21:57:30 aurora kpropd[1073]: ready
Mar 18 21:57:30 aurora systemd[1]: Reached target Host and Network Name Lookups.
Mar 18 21:57:30 aurora kpropd[1073]: getaddrinfo: Der Name oder der Dienst ist nicht bekannt
Mar 18 21:57:30 aurora systemd[1]: Starting OpenBSD Secure Shell server...
Mar 18 21:57:30 aurora systemd[1]: kpropd.service: Main process exited, code=exited, status=1/FAILURE
Mar 18 21:57:30 aurora systemd[1]: kpropd.service: Unit entered failed state.
Mar 18 21:57:30 aurora systemd[1]: kpropd.service: Failed with result 'exit-code'.

Das Netzwerk ist „irgendwie“ schon vorhanden, aber es scheint der resolver Mechanismus (getaddrinfo) noch nicht richtig zu Arbeiten.
Die Lösung hält dieser systemd Eintrag von freedesktop.org bereit. Entscheidend ist die Änderung in:
After=network-online.target
Pikanterweise gab es unter Ubuntu aber auch hier wohl einige Zeit eine Unstimmigkeit, bzgl. des resolver Mechanismus unter diesem (passiven) Target, wie man hier nachlesen kann.
Erwähnenswert ist noch, dass man den Dienst theoretisch auch ohne root-Rechte starten könnte, wenn man das Capability Feature von Linux nutzt. Dazu setzt man im [Service] Block des unit files folgende Direktive – in diesem Fall handelt es sich im das Portbinding, welches beim kpropd übrigens auf TCP-Port 754 stattfindet.

CapabilityBoundingSet=CAP_NET_BIND_SERVICE

Service Unit auf dem primären (master) KDC

Auf dem primary KDC muss kontinuierlich ein aktueller Dump dem secondary geschickt werden. Das erzeugen des dumps sowie der transmit Befehl sind in folgenden script (kprop.sh) verpackt:

#!/bin/bash

# starts the krb5kdc propagation to the secondary KDC
# location of dumpfile and secondary KDC are taken from the
# following variables

dumpfile=/var/lib/krb5kdc/kdb_repldata
kdcslave=aurora

kdb5_util dump $dumpfile
if [ $? == 0 ]; then
kprop -f $dumpfile $kdcslave
fi


exit $?

Um diese Aktion frequentiert aufzurufen, kann man natürlich die globale crontab bemühen. Es geht aber auch mit kleinen Vorteilen im systemd Ökosystem. Dazu braucht man allerdings dann 2 files.
Wieder ein systemd service file (kprop.service)

[Unit]
Description=kprop KDC propagation


[Service]
Type=simple
ExecStart=/root/bin/kprop.sh

und ein systemd timer file (kprop.timer)…

[Unit]
Description=Run kprop daily

[Timer]
OnCalendar=4:50
Persistent=true


[Install]
WantedBy=timers.target

..welches in unserem File täglich um 04:50 aufgerufen wird.
Beide files landen in /etc/systemd/system. Aber nur das timer file wird via
sudo systemctl enable kprop.timer
aktiviert.
Vorteil dieser Lösung ist, dass man einerseits mit systemctl auch manuell die Synchronisation anstoßen kann, aber auch schnell eine übersichtliche Darstellung der Logeinträge bekommt, welches man mit
journalctl -u kprop
auf dem primary KDC, bzw.
journalctl -u kpropd
auf dem secondary KDC abfrägt.

Schreibe einen Kommentar

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.