Systemd: Warum werden Dateien in /tmp oder /run nach wenigen Sekunden gelöscht?

Systemd: Warum werden Dateien in /tmp oder /run nach wenigen Sekunden gelöscht?

Ich verwende systemd, um eine Windows-Freigabe mit Kerberos zu mounten. Damit das funktioniert, führe ich zuerst kiniteine .service-Datei aus, um einen Kerberos-Anmeldeinformationscache (ccache) zu erstellen. Der .service wird als Root ausgeführt, da der ccache root gehören muss ( journalctl -xehat mir dabei geholfen), da mount.cifs root erfordert. .mount (und .automount) verwenden den ccache, um das kerberisierte Mounten durchzuführen. Wenn ich den ccache interaktiv erstelle, funktioniert das gut. Wenn ich ihn jedoch innerhalb der Service-Einheit ausführe, wird der ccache schnell gelöscht und das (automatische) Mounten schlägt fehl. Es spielt keine Rolle, ob ich ihn in /tmp oder /run/user/0 speichere.

  1. Warum werden Dateien in /tmp oder /run automatisch gelöscht?
  2. Was ist der bevorzugte Speicherort für diese Ccache-Dateien? Gibt es PrivateTmpeine bessere Lösung? Wenn ja, wie verweise ich in der Servicedatei auf dieses private temporäre Verzeichnis? Ich habe es versucht %T/krb5cc_root.ccache, aber systemctl generiert einen Fehler. Ist JoinsNamespaceOfes möglich, dasselbe private temporäre Verzeichnis in der Mount-Datei zu verwenden?

Ich verwende systemd 219 unter Linux CentOS 7. Unten ist meine .service-Einheit. Vielen Dank im Voraus!

[Unit]
Description=Kinit keytab for /mnt/windows_staging
After=network.target
Requires=network.target

[Service]
Restart=always
RestartSec=30
PrivateTmp=yes
User=root
Group=users
ExecStartPre=-/bin/mkdir -p /mnt/windows_staging
ExecStartPre=-/bin/mkdir -p /run/user/0
Environment=KRB5_KTNAME=/home/albertjan@domain/myproject/etc/keytabs/albertjan.keytab
Environment=KRB5CCNAME=/run/user/0/krb5cc_root.ccache
ExecStart=/bin/kinit albertjan -kt ${KRB5_KTNAME} -c ${KRB5CCNAME}
ExecStartPost=/bin/sleep 2
ExecStop=-/bin/kdestroy -c ${KRB5CCNAME}

[Install]
WantedBy=multi-user.target

Antwort1

Warum werden Dateien in /tmp oder /run automatisch gelöscht?

Denn Ihr Servicestartet einen "Daemon", der sofort beendet wird, wodurch der Dienst innerhalb weniger Sekunden nach dem Start als „gestoppt“ markiert wird, was zur kdestroyAusführung von ExecStop= führt.

  • Option 2: Ändern Sie die .service-Definition, um systemd mitzuteilen, dass diessoll seineine Aufgabe, die mit diesen Optionen sofort beendet wird:

    [Service]
    Type=oneshot
    RemainAfterExit=yes
    

    Der Type=oneshotModus ist außerdem nützlich, weil systemd wartet, bis ExecStart= vollständig abgeschlossen ist, bevor der Dienst als „aktiv“ markiert wird. Dadurch ist es nicht mehr nötig, das beliebige hinzuzufügen sleep 2. Mit anderen Worten, Sie können es verwenden, After=kinit.serviceohne sich Sorgen machen zu müssen, dass andere Dinge „zu früh“ starten.

  • Option 1: Ersetzen Sie kinit durch den k5startDaemon vonhttps://www.eyrie.org/~eagle/software/kstart/. Dies ist ein echter Daemon – ein lang andauernder Prozess – und wird als solcher verfolgt. Er kümmert sich auch um die regelmäßige Erneuerung.

    Wenn Sie k5start mit der -bOption („Beim Start trennen“) verwenden und den .service- Type=forkingModus entsprechend ändern, erhalten Sie auch dasselbe „Verzögerung bis zum Erfolg“-Verhalten.

(Es gibt auch eine dritte Option, bei der gssproxyalle Tickets bearbeitet werden, aber cifs.upcall in CentOS unterstützt dies noch nicht. Für andere Verwendungszwecke als das Mounten von Dateisystemen KRB5_CLIENT_KTNAMEkönnte das Programm bei Bedarf selbst Tickets aus der Keytab abrufen, aber in diesem Fall funktioniert das nicht.)

Was ist der bevorzugte Speicherort für diese Ccache-Dateien?

Ich persönlich würde bei /tmp/krb5cc_*oder bleiben /run/user/<uid>/krb5cc_*. (Dies sind die einzigen Orte, die NFS rpc.gssd überprüft.)

Für SMB sucht cifs.upcall am Standardspeicherort des Systems nach der UID, die die Einbindung durchführt (also was auch immer in krb5.conf definiert ist), was normalerweise der Fall ist, /tmp/krb5cc_0wenn systemd dies tut. (Obwohl cifs.upcall KRB5CCNAME aus der Umgebung des Aufrufers auslesen kann, hilft das nicht, wenn Automounts beteiligt sind, da cifs.upcall nur systemd oder autofsd als Anrufer sehen würde.)

Ist PrivateTmp eine bessere Lösung?

PrivateTmp hilft nicht, da Ihre Datei nicht von einer externen Aufgabe gelöscht wird, sondern vom Dienst selbst.

verwandte Informationen