Was ist der Unterschied zwischen / tmp und / run?

42

Laut FHS-3.0 , /tmpist für temporäre Dateien und /runist für den variablen Datenlaufzeit. Die Daten in /runmüssen beim nächsten Start gelöscht werden, was jedoch nicht erforderlich /tmpist. Programme dürfen jedoch nicht davon ausgehen, dass die Daten in /tmpbeim nächsten Programmstart verfügbar sind. All das scheint mir ziemlich ähnlich zu sein.

Was ist der Unterschied zwischen den beiden? Nach welchem ​​Kriterium sollte ein Programm entscheiden, ob temporäre Daten abgelegt werden sollen /tmpoder nicht /run?

Laut FHS:

Programme können ein Unterverzeichnis von haben /run; Dies wird für Programme empfohlen, die mehr als eine Laufzeitdatei verwenden.

Dies zeigt an, dass die Unterscheidung zwischen "Systemprogrammen" und "gewöhnlichen Programmen" kein Kriterium ist, ebenso wenig wie die Lebensdauer des Programms (wie langlaufender oder kurzlaufender Prozess).

Obwohl die folgende Begründung in der FHS nicht gegeben ist, /runwurde eingeführt, um das Problem zu überwinden, /vardas zu spät montiert wurde, so dass schmutzige Tricks erforderlich waren, um /var/runfrüh genug verfügbar zu machen . Mit /runder Einführung und der Beschreibung in der FHS scheint es jedoch keinen klaren Grund zu geben, beides /runund zu haben /tmp.

Dirk Herrmann
quelle
11
/ tmp ist der * nix-Standardspeicherort für temporäre Daten. / run ist der Pöttering-Standardspeicherort für temporäre Daten.
Mark
Rückwärtskompatibilität ist immer ein Grund ...
Bakuriu

Antworten:

16

Kein Grund, sowohl / run als auch / tmp zu haben

Ich denke, du hast recht. /tmpist im Wesentlichen veraltet, jetzt haben wir /run. Wenn Ihr Programm dazu in der Lage ist (was erfordert, dass es als privilegierte Operation installiert wurde ), würden Sie heutzutage ein Unterverzeichnis von verwenden /run. Dies ist aus Sicherheitsgründen.

Beispielsweise wird der CUPS-Druckerdämon nicht als Root ausgeführt, sondern in der Regel von einem Betriebssystempaket installiert. Das Paket wird installiert /usr/lib/tmpfiles.d/cups.confund systemd-tmpfileserstellt ein Verzeichnis, auf das es zugreifen kann. Da sich das Verzeichnis unter befindet /run, kann der Name nicht böswillig von einem nicht privilegierten Benutzer behauptet worden sein, im Gegensatz zu /tmpdem, der von der Welt beschreibbar ist.

"Unprivilegierte Programme", die nicht /rundirekt verwendet werden können

Der eigentliche Unterschied besteht darin, ob Ihr Programm von einem beliebigen, nicht privilegierten Benutzer unter seiner eigenen Benutzer-ID ausgeführt wird. Im Allgemeinen möchten Sie es jedoch nicht verwenden /tmp, da andere nicht privilegierte Benutzer darauf zugreifen können. Sie würden es vorziehen, zu verwenden $XDG_RUNTIME_DIR. In der Regel wird dies implementiert als /run/user/$(id -u)- so dass es zufällig auch ein Unterverzeichnis von ist /run. Die Lage ist jedoch nicht garantiert. Programme sollten immer die Umgebungsvariable verwenden.

/tmpwäre nur für die Ad-hoc-Zusammenarbeit zwischen verschiedenen nichtprivilegierten Benutzern auf dem System nützlich. Solche Ad-hoc-Systeme sind anfällig für einen böswilligen Benutzer, der sich weigert, zusammenzuarbeiten, und verwöhnt Dinge für alle :). Ein Beispiel wären nicht privilegierte Benutzer, die sich dafür entscheiden, eine Version des talkDaemons unter Verwendung eines Unix-Sockets auszuführen .

Originalinformationen von Lennart Pöttering

Hinweis: In der nachstehenden Prüfliste von Pöttering wurde angegeben, dass /tmpdies für "kleine Dateien" nützlich ist, wohingegen diese /runnur für "Kommunikationsprimitive" verwendet werden sollten. Ich glaube auch nicht, dass diese Unterscheidung wahr ist. Der Aushängeschild für /runist udev, und ich bin mir ziemlich sicher, /run/udeventhält interne Datenbanken. Wenn Sie ein /runVerzeichnis haben, möchte wohl niemand der behaupteten Unterscheidung folgen und ein anderes Verzeichnis erstellen , um Unordnung zu schaffen /tmp. In der Praxis verwenden wir /runheutzutage nur.

Die Verwendung von weltweit beschreibbaren freigegebenen Namespaces [wie / tmp] für Kommunikationszwecke war immer problematisch, da zum Aufbau der Kommunikation stabile Namen erforderlich sind, stabile Namen jedoch die Türen für DoS-Angriffe öffnen. Dies kann teilweise korrigiert werden, indem für bestimmte Dienste während des frühen Startvorgangs geschützte Verzeichnisse pro App eingerichtet werden (wie dies bei X11 der Fall ist). Dies behebt das Problem jedoch nur teilweise, da dies nur dann ordnungsgemäß funktioniert, wenn auf jede Paketinstallation ein Neustart folgt.

...

Eine andere Fedora-Funktion (für Fedora 17) hat die Semantik von / tmp für viele Systemdienste geändert, um sie sicherer zu machen, indem die / tmp-Namespaces der verschiedenen Dienste isoliert wurden

...

Da / tmp nicht mehr unbedingt ein gemeinsam genutzter Namespace ist, ist es im Allgemeinen nicht als Speicherort für Kommunikationsprimitive geeignet.

...

[/ run] ist garantiert ein tmpfs und wird daher beim Booten automatisch gespült. Darüber hinaus wird keine automatische Bereinigung durchgeführt.

...

Hier ist eine grobe Anleitung, wie wir Ihnen (einem Linux-Anwendungsentwickler) vorschlagen, das richtige Verzeichnis auszuwählen:

  1. Sie benötigen einen Ort, an dem Sie Ihren Socket (oder ein anderes Kommunikationsprimitiv) platzieren können, und Ihr Code wird privilegiert ausgeführt: Verwenden Sie ein Unterverzeichnis unter / run. (Oder unter / var / run für zusätzliche Kompatibilität.)
  2. Sie benötigen einen Speicherort für Ihren Socket (oder ein anderes primitives Kommunikationselement), und Ihr Code wird nicht privilegiert ausgeführt: Verwenden Sie ein Unterverzeichnis unter $ XDG_RUNTIME_DIR.
  3. Sie benötigen einen Ort, an dem Sie größere Downloads und Downloads durchführen und ohne Berechtigungen ausführen können: Verwenden Sie $ XDG_DOWNLOAD_DIR.
  4. Sie benötigen einen Ort, an dem Sie Cachedateien ablegen können, die persistent und nicht privilegiert sein sollten: Verwenden Sie $ XDG_CACHE_HOME.
  5. Nichts von alledem trifft zu und Sie müssen eine kleine Datei platzieren, die keine Persistenz benötigt: Verwenden Sie $ TMPDIR mit einem Fallback auf / tmp. Und benutze mkstemp () und mkdtemp () und nichts Eigenes.
  6. Verwenden Sie andernfalls $ TMPDIR mit einem Fallback auf / var / tmp. Verwenden Sie auch mkstemp () / mkdtemp ().

Beachten Sie, dass diese Regeln nur von uns vorgeschlagen werden. Diese Regeln berücksichtigen alles, was wir über dieses Thema wissen, und vermeiden Probleme mit aktuellen und zukünftigen Distributionen, soweit wir sie sehen können. Bitte denken Sie daran, Ihre Projekte zu aktualisieren, um diese Regeln zu befolgen, und denken Sie daran, wenn Sie neuen Code schreiben.

Eine Sache, die wir hervorheben möchten, ist, dass / tmp und / var / tmp häufig nicht die richtige Wahl für Ihren Anwendungsfall sind. Es gibt gültige Verwendungen dieser Verzeichnisse, aber oft ist ein anderes Verzeichnis tatsächlich der bessere Ort. Denken Sie also über die anderen Optionen nach. Wenn Sie sich jedoch für / tmp oder / var / tmp entscheiden, müssen Sie mindestens mkstemp () / mkdtemp () verwenden.

Wir kommen irgendwie mit dem alten /tmpSockel davon, der vom X-Window-System verwendet wird, wie oben beschrieben. Ich habe falsch verstanden tmpfiles.d/x11.conf. Sieht eher nach Kooperation aus :). Ich gehe davon aus, dass der Code geprüft wurde, sodass Denial-of-Service das Schlimmste ist, was passieren kann.

sourcejedi
quelle
8
Diese Antwort ist falsch.
R ..
@R .., möchten Sie das näher erläutern?
Wildcard
Ja, das habe ich schon in einer Antwort getan. (Begonnen als Kommentar, aber mir wurde klar, dass es eher eine Antwort war.)
R ..
Ich denke, die Hauptschwäche meiner aktuellen Antwort, auf die Sie meiner Meinung nach hingearbeitet haben , ist, dass die korrekte Handhabung von XDG_RUNTIME_DIR technisch auf alle * nix portierbar sein muss ("auf ein Ersatzverzeichnis mit ähnlichen Fähigkeiten zurückgreifen"). Es ist sehr vage, was dies in der Praxis bedeutet. Für tragbare Hilfsprogramme ist es besser, den genau definierten Standard zu verwenden /tmp("die einzigen APIs für die Verwendung sollten mkstemp (), mkdtemp () (und friends) sein, um absolut sicher zu sein").
Sourcejedi
Die Antwort fehlt ebenfalls häufig: Ist /var/runsystemweit (z. B. zur Kommunikation mit der lokalen Datenbank), wird /tmp/jetzt häufig pro Benutzer erstellt . Historisch war auch die Quote von / tmp unterschiedlich eingestellt. Und die Antwort vermisst, dass eine semantische Unterscheidung der Verwendung ebenfalls wichtig ist.
Giacomo Catenazzi
23

Die Verzeichnisse /tmpund /usr/tmp(später /var/tmp) waren der Abladeplatz für alles und jeden. Der einzige Schutzmechanismus für Dateien in diesen Verzeichnissen ist das Sticky-Bit, das das Löschen oder Umbenennen von Dateien auf deren Eigentümer beschränkt. Wie marcelm in einem Kommentar betont hat, hindert grundsätzlich nichts daran, Dateien mit Namen zu erstellen, die von Diensten (wie nginx.pidoder sshd.pid) verwendet werden. (In der Praxis könnten die Startskripte solche gefälschten Dateien jedoch zuerst entfernen.)

/runwurde für nicht persistente Laufzeitdaten von langlebigen Diensten wie Sperren, Sockets, PID-Dateien und dergleichen erstellt. Da es für die Öffentlichkeit nicht beschreibbar ist, schützt es die Laufzeitdaten des Dienstes vor dem Durcheinander /tmpund den Jobs, die dort aufräumen. In der Tat: Zwei von mir ausgeführte Distributionen (ohne Wortspiel) haben Berechtigungen 755 /run, während /tmpund /var/tmp(und /dev/shmin diesem Fall) Berechtigungen 1777 haben.

Gegenmodus
quelle
3
es ist einfach da, um die Laufzeitdaten des Dienstes von den Mess-In-Daten zu trennen/tmp - und um einen sicheren Hafen für diese Daten aus den verschiedenen Bereinigungsaufträgen zu schaffen, die durchgehend in Mitleidenschaft gezogen werden /tmp.
Satō Katsura
Danke für die Infos zu den Berechtigungen. Laut FHS können "Programme ein Unterverzeichnis von / run haben; dies wird für Programme empfohlen, die mehr als eine Laufzeitdatei verwenden." - Dies scheint sowohl dem Kriterium "Langlebige Dienste" als auch der Unfähigkeit von Programmen zu widersprechen, ihre Unterverzeichnisse aufgrund begrenzter Berechtigungen zu erstellen.
Dirk Herrmann
@DirkHerrmann Nein, tut es nicht. Schauen /runSie sich die komplexe (naja ...) Verzeichnisstruktur an, die durch usw. verursacht udevwurde udisk. Ich bin kein Experte für dieses spezielle Problem, aber ich denke, die Boot-Skripte (die als Superuser ausgeführt werden) haben alles eingerichtet.
Gegenmodus
2
"/ run ist technisch nicht notwendig, es dient lediglich dazu, die Laufzeitdaten des Dienstes von den Mess-In / tmp zu trennen." - Gut, dass nichtprivilegierte Prozesse die Namen der Systemdienste, die sie verwenden möchten, nicht in die Knie zwingen können. Irgendwie scheiße, wenn Nginx es benutzen will, /tmp/nginx.pidaber es existiert bereits aufgrund eines fehlerhaften Programms. /run/verhindert dies, indem Berechtigungen zum Schreiben erforderlich sind.
März
18

/tmpist der Speicherort für die Erstellung temporärer Dateien und Verzeichnisse. Es kann nicht zum Speichern von "bekannten Namen" verwendet werden (dh Namen, die einem anderen Prozess bekannt sein könnten, ohne dass Sie den Namen irgendwie mitteilen müssen), da niemand den Besitz über den Namespace hat. jeder kann dort dateien anlegen. Als solches verwenden Sie es im Allgemeinen, wenn Sie ein Dienstprogramm haben, das eine Datei (dh keine Pipe oder ähnliches) als Eingabe oder Ausgabe benötigt, bei der ein beliebiger (zufällig generierter) Name funktioniert, solange Sie den Namen eingeben.

Historisch gesehen haben einige Dinge (wie X) gegen dieses Prinzip verstoßen und bekannte Namen (wie .X11-unix) hinzugefügt /tmp. Dies ist natürlich fehlerhaft und ermöglicht es jedem Benutzer, den Dienst zu tun, der dies erfordert, indem er einfach rennt, um zuerst eine Datei mit dem gewünschten Namen zu erstellen. Solche Dinge gehören unter /run(oder gleichwertig, /var/runwenn Sie Freedesktop.org revisionism nicht abonnieren). Noch besser wäre es natürlich, sie so zu reparieren, dass sie keine bekannten Namen in einem globalen Namespace verwenden, sondern stattdessen einen Pfadnamen weitergeben.

R ..
quelle
Vielen Dank für weitere Definitionen zu "temporären Dateien". Obwohl ich nicht denke, dass "einen Pfadnamen weitergeben" erklärt, wie man einen Koordinationspunkt erstellt. Dh normalerweise würden Sie eine Umgebungsvariable verwenden. Sieht so aus, als gäbe es nur wenige Steckdosen und Rohre (im allgemeinen Gebrauch), damit es funktioniert. (Zum Teil, weil viele Dinge über dieselbe D-Bus-Buchse laufen). Es scheint ärgerlich zu sein, die Umgebung einzustellen, wenn die Programme nicht standardmäßig einen fest codierten Pfad verwenden. Sie könnten systemd- .socketDateien einen neuen Schlüssel hinzufügen ... aber das hilft weder für ganze Verzeichnisse noch für neu installierte Dienste
sourcejedi
2
/run/selbst wurde von FHS adoptiert, ich kann nicht sehen, wie es mit fd.o zu tun hat. Es sei denn, wir wollten uns wirklich über unspezifische Entwicklungsbemühungen beschweren, die zu beiden beigetragen haben.
Sourcejedi
Ich denke, die erste Antwort hier ist die beste Antwort hier auf die Frage, wie sie geschrieben wurde. Ich denke, es könnte durch folgende Überlegungen weiter verbessert werden: _Wenn Software Schreibzugriff auf ein dediziertes Verzeichnis hat, z. B. unter /run, sollte vermieden werden , dass das freigegebene /tmpVerzeichnis mit noch mehr Dateien überladen wird .
Sourcejedi
Was ist "fd.o"?
TRiG
7

Nach dem Dateisystem-Hierarchie-Standard

  • /run ist für die Laufzeit variable Daten, dh Informationen über das laufende System seit dem Neustart
  • /tmp ist ein generischer Ort für temporäre Dateien.

Alles, was den Daemon-Status, angemeldete Benutzer, gemountete Wechseldatenträger usw. betrifft, würde eingehen, /runwährend temporäre Dateien, die von einem Programm erstellt wurden, eingehen /tmp.

Bearbeiten: wie im Kommentar unten von @JdeBP hingewiesen,

Das FHS ermöglicht die konventionelle Einrichtung von Cron-Jobs, bei denen regelmäßig /tmp"alte" Dateien gelöscht werden. ohne solche Mechanismen bestimmt für /run. Daher die drakonische Grenze dessen, was Programme von der Lebensdauer von allem erwarten können, was eingegeben wird /tmp. Während Programme erwarten können, dass Dateien länger /runauf einem ständig aktualisierten System verbleiben, wird auch erwartet, dass sie dort mehr aufräumen.

dr01
quelle
4
Eine Sache, die in dieser oder einer anderen Antwort nicht erwähnt, aber in der FHS vermerkt ist und mit der Sie Ihre Antwort möglicherweise verbessern möchten: Die FHS ermöglicht Dinge wie das herkömmliche Einrichten von Cron-Jobs, die regelmäßig /tmp"alte" Dateien löschen; ohne solche Mechanismen bestimmt für /run. Daher die drakonische Grenze dessen, was Programme von der Lebensdauer von allem erwarten können, was eingegeben wird /tmp. Während Programme erwarten können, dass Dateien länger /runauf einem ständig aktualisierten System verbleiben, wird auch erwartet, dass sie dort mehr aufräumen.
JdeBP
1
Es wäre schön, ein prozessbezogenes Verzeichnis mit Dingen zu haben, die verschwunden sind (oder die von einem umherziehenden Garbage Daemon gelöscht werden durften), sobald der Prozess beendet ist.
Omnifarious
1
@Omnifarious Sie können dieses Verhalten jetzt für einen systemd-Dienst erhalten, indem Sie RuntimeDirectory = :-) verwenden.
Sourcejedi