Quelle est la différence entre / tmp et / run?

42

Selon FHS-3.0 , il /tmps’agit de fichiers temporaires et de /rundonnées variables au moment de l’exécution. Les données d' entrée /rundoivent être supprimées au prochain démarrage, ce qui n'est pas obligatoire pour /tmp, mais les programmes ne doivent pas encore supposer que les données d' /tmpentrée seront disponibles au prochain démarrage du programme. Tout cela me semble assez similaire.

Alors, quelle est la différence entre les deux? Par quel critère devrait un programme décider de mettre les données temporaires dans /tmpou en /run?

Selon la FHS:

Les programmes peuvent avoir un sous-répertoire de /run; cela est encouragé pour les programmes qui utilisent plusieurs fichiers d'exécution.

Cela indique que la distinction entre "programmes système" et "programmes ordinaires" n'est pas un critère, pas plus que la durée de vie du programme (comme, processus long ou court).

Bien que le raisonnement suivant ne soit pas expliqué dans la FHS, il a /runété introduit pour résoudre le problème qui a /varété mis en place trop tard, de sorte que des astuces compliquées étaient nécessaires pour être /var/rundisponibles suffisamment tôt. Cependant, maintenant avec /runson introduction, et compte tenu de sa description dans le FHS, il ne semble pas être une raison évidente d'avoir les deux /runet /tmp.

Dirk Herrmann
la source
11
/ tmp est l'emplacement standard * nix pour les données temporaires. / run est l'emplacement standard de Poettering pour les données temporaires.
Marc
La compatibilité en
amont

Réponses:

16

Aucune raison d'avoir les deux / run et / tmp

Je pense que tu as raison. /tmpest essentiellement obsolète maintenant, nous avons /run. Si votre programme est en mesure de le faire (ce qui nécessite qu'il soit installé en tant qu'opération privilégiée), vous utiliserez alors un sous-répertoire de /run. C'est pour des raisons de sécurité.

Par exemple, le démon d'impression CUPS ne s'exécute pas en tant que root mais est généralement installé à partir d'un package de système d'exploitation. Le paquet s'installe /usr/lib/tmpfiles.d/cups.confet systemd-tmpfilescrée un répertoire auquel il peut accéder. Étant donné que le répertoire est en dessous /run, le nom ne peut pas avoir été réclamé de manière malveillante par un utilisateur non privilégié, contrairement à /tmpce qui est en écriture pour le monde entier.

"Programmes non privilégiés" qui ne peuvent pas utiliser /rundirectement

La vraie différence réside dans le fait que votre programme est exécuté par un utilisateur arbitraire non privilégié, sous son propre ID utilisateur. Mais vous ne voulez généralement pas utiliser /tmp, car d’autres utilisateurs non privilégiés peuvent y accéder. Vous préférez utiliser $XDG_RUNTIME_DIR. Généralement, ceci est implémenté comme /run/user/$(id -u)- il se trouve qu’il s’agit également d’un sous-répertoire /run. L'emplacement n'est pas garanti cependant; les programmes doivent toujours utiliser la variable d'environnement.

/tmpne serait utile que pour une coopération ad hoc entre différents utilisateurs non privilégiés du système. De tels systèmes ad-hoc sont vulnérables au refus d'un utilisateur malveillant de coopérer et de gâter tout le monde :). Un exemple serait les utilisateurs non privilégiés qui décideraient d'exécuter une version du talkdémon, en utilisant un socket Unix.

Information originale de Lennart Poettering

Notez que la liste de contrôle de Poettering ci-dessous indique que /tmpcela serait utile pour les "petits fichiers", alors /runqu'il ne devrait être utilisé que pour les "primitives de communication". Je ne pense pas que cette distinction soit vraie non plus. Le posteur pour /runest udev, et je suis à peu près sûr, /run/udevinclut des bases de données internes. Une fois que vous avez un /runrépertoire, je ne pense pas que quiconque veuille suivre la distinction revendiquée et créer un autre répertoire, pour encombrer /tmp. Donc, en pratique, nous utilisons simplement de /runnos jours.

L'utilisation d'espaces de noms partagés en écriture [comme / tmp] à des fins de communication a toujours été problématique, car pour établir une communication, vous avez besoin de noms stables, mais des noms stables ouvrent la porte aux attaques par déni de service. Cela peut être corrigé partiellement en établissant des répertoires protégés par application pour certains services lors du démarrage initial (comme nous le faisons pour X11), mais cela ne résout que partiellement le problème, car cela ne fonctionne correctement que si chaque installation de package est suivie d'un redémarrage.

...

Une autre fonctionnalité de Fedora (pour Fedora 17) a modifié la sémantique de / tmp pour de nombreux services système afin de les rendre plus sécurisés, en isolant les espaces de noms / tmp des différents services.

...

Etant donné que / tmp n'est plus nécessairement un espace de noms partagé, il ne convient généralement pas comme emplacement pour les primitives de communication.

...

[/ run] est garanti d'être un fichier tmpfs et est donc automatiquement vidé lors du démarrage. Aucun nettoyage automatique n'est fait au-delà de cela.

...

Voici un guide approximatif sur la façon dont nous vous suggérons (développeur d'applications Linux) de choisir le bon répertoire à utiliser:

  1. Vous avez besoin d'un emplacement pour placer votre socket (ou une autre primitive de communication) et votre code est privilégié: utilisez un sous-répertoire sous / run. (Ou sous / var / run pour une compatibilité accrue.)
  2. Vous avez besoin d'un emplacement pour placer votre socket (ou une autre primitive de communication) et votre code est exécuté sans privilège: utilisez un sous-répertoire situé sous $ XDG_RUNTIME_DIR.
  3. Vous avez besoin d'un emplacement pour mettre vos téléchargements les plus volumineux et en cours et exécuter sans privilèges: utilisez $ XDG_DOWNLOAD_DIR.
  4. Vous avez besoin d'un emplacement pour placer les fichiers de cache qui doivent être persistants et s'exécuter sans privilège: utilisez $ XDG_CACHE_HOME.
  5. Rien de ce qui précède ne s'applique et vous devez placer un petit fichier qui ne nécessite aucune persistance: utilisez $ TMPDIR avec un repli sur / tmp. Et utilisez mkstemp (), et mkdtemp () et rien chez vous.
  6. Sinon, utilisez $ TMPDIR avec un repli sur / var / tmp. Utilisez également mkstemp () / mkdtemp ().

Notez que ces règles ci-dessus ne sont suggérées que par nous. Ces règles prennent en compte tout ce que nous savons sur ce sujet et évitent les problèmes liés aux distributions actuelles et futures, dans la mesure où nous pouvons les voir. Pensez à mettre à jour vos projets pour suivre ces règles, et gardez-les à l'esprit si vous écrivez un nouveau code.

Une chose sur laquelle nous voudrions insister est que / tmp et / var / tmp ne sont pas le plus souvent le bon choix pour votre cas d'utilisation. Il existe des utilisations valables de ces répertoires, mais très souvent, un autre répertoire peut en fait être le meilleur endroit. Donc, soyez prudent, considérez les autres options, mais si vous choisissez / tmp ou / var / tmp, assurez-vous au moins d’utiliser mkstemp () / mkdtemp ().

Nous nous débrouillons un peu avec le /tmpsocket hérité utilisé par le système X Window, comme décrit ci-dessus. J'ai mal lu tmpfiles.d/x11.conf. On dirait plus que ça dépend de la coopération :). Je suppose que le code a été vérifié, de sorte que le déni de service est le pire qui puisse arriver.

sourcejedi
la source
8
Cette réponse est erronée.
R ..
@R .., veux-tu développer?
Wildcard
Oui, je l'ai déjà fait dans une réponse. (Commencé comme un commentaire mais j'ai réalisé que c'était plus une réponse.)
R ..
Je pense que la principale faiblesse de ma réponse actuelle, à laquelle je pense que vous travailliez, est que, bien que techniquement , le traitement correct de XDG_RUNTIME_DIR soit portable sur n'importe quel * nix ("retournez à un répertoire de remplacement doté de capacités similaires"), c'est très vague ce que cela signifie en pratique. Pour les programmes utilitaires portables, il est préférable d'utiliser le standard bien défini pour /tmp("les seules API à utiliser doivent être mkstemp (), mkdtemp () (et amis) pour être totalement sûr").
sourcejedi
La réponse manque également le cas commun: est globale au /var/runsystème (par exemple pour communiquer avec la base de données locale), /tmp/est maintenant créée par utilisateur . Historiquement, le quota de / tmp était également différent. Et la réponse manque qu'une distinction sémantique d'utilisation est également importante.
Giacomo Catenazzi
23

Les annuaires /tmpet /usr/tmp(plus tard /var/tmp) étaient le dépotoir pour tout et pour tout le monde. Le seul mécanisme de protection des fichiers de ces répertoires est le "sticky bit" qui limite la suppression ou le changement de nom des fichiers à leurs propriétaires. Comme l'a souligné marcelm dans un commentaire, rien n'empêche en principe de créer des fichiers avec des noms utilisés par des services (tels que nginx.pidou sshd.pid). (Cependant, dans la pratique, les scripts de démarrage peuvent supprimer d’abord ces faux fichiers.)

/runa été établi pour les données d'exécution non persistantes de services de longue durée tels que les verrous, les sockets, les fichiers pid, etc. Comme il n’est pas accessible en écriture pour le public, il protège les données d’exécution du service du désordre /tmpet les tâches qui y sont nettoyées. En effet: deux distributions que je lance (sans jeu de mots) ont des autorisations 755 sur /run, tandis que /tmpet /var/tmp(et /dev/shmd'ailleurs) ont des autorisations 1777.

contre mode
la source
3
il s'agit simplement de séparer les données d'exécution du service du gâchis/tmp , ainsi que de fournir un abri sûr pour ces données à partir des divers travaux de nettoyage qui piétinent /tmp.
Satō Katsura
Merci pour l'info sur les permissions. Toutefois, selon FHS, "Les programmes peuvent avoir un sous-répertoire / run; ceci est encouragé pour les programmes qui utilisent plusieurs fichiers d'exécution". - cela semble contredire à la fois le critère "services de longue durée" et l'incapacité des programmes de créer leurs sous-répertoires en raison d'autorisations limitées.
Dirk Herrmann
@ DirkHerrmann Non, ce n'est pas le cas. Jetez un coup d'œil à /runla structure complexe (bien ...) des répertoires causée par udev, udisketc.
Contre-mode
2
"/ run n’est techniquement pas nécessaire, c’est simplement là pour séparer les données d’exécution du service du désordre dans / tmp." - Bonne chose aussi, si bien que les processus non privilégiés ne peuvent pas utiliser les noms de système que les services système veulent utiliser. Kinda craint si nginx veut utiliser /tmp/nginx.pidmais il existe déjà à cause d'un programme qui se comporte mal. /run/empêche cela en exigeant des privilèges pour écrire dans.
marcelm
18

/tmpest l'emplacement de création des fichiers temporaires et des répertoires. Il n'est pas utilisable pour stocker des "noms connus" (c'est-à-dire des noms dont un autre processus peut avoir connaissance sans que vous ayez à lui transmettre le nom) parce que personne n'est propriétaire de l'espace de noms; n'importe qui peut y créer des fichiers. En tant que tel, vous l'utilisez généralement lorsque vous avez un utilitaire nécessitant un fichier (c.-à-d. Pas un tuyau) comme entrée ou sortie, où tout nom (généré aléatoirement) fonctionnera aussi longtemps que vous le passerez.

Historiquement, certaines choses (comme X) ont violé ce principe et ont mis des noms connus (comme .X11-unix) dans /tmp. Ceci est bien sûr bogué et permet à tout utilisateur de créer un fichier avec le nom souhaité en premier. De telles choses appartiennent à /run(ou équivalent /var/runsi vous ne vous abonnez pas au révisionnisme Freedesktop.org). Bien sûr, il serait même préférable de les empêcher de ne pas utiliser de noms connus dans un espace de noms global, mais plutôt de les contourner.

R ..
la source
Merci pour plus de définition sur les "fichiers temporaires". Bien que je ne pense pas que "passer un chemin" explique comment établir un point de coordination. En règle générale, vous utiliseriez une variable d’environnement. On dirait qu'il y a assez peu de douilles et de tuyaux (généralement utilisés) pour le laisser fonctionner. (En partie parce que beaucoup de choses fonctionneront sur le même socket dbus). On dirait qu'il serait ennuyeux de définir l'environnement si les programmes ne sont pas configurés par défaut sur un chemin codé en dur. Vous pouvez ajouter une nouvelle clé aux .socketfichiers systemd ... mais cela n’aide en rien les répertoires entiers, ni les services nouvellement installés
sourcejedi
2
/run/elle-même a été adoptée par FHS, je ne vois pas en quoi cela aurait un rapport avec fd.o. À moins que nous ne voulions vraiment nous plaindre, ce sont des efforts de développement non spécifiés qui ont contribué à la fois.
sourcejedi
Je pense que la réponse initiale ici est la meilleure réponse ici pour la question telle que formulée. Je pense qu’il serait encore amélioré si: _Lorsque le logiciel a un accès en écriture à un répertoire dédié, par exemple /run, il peut être préférable d’éviter d’encombrer le /tmprépertoire partagé avec encore plus de fichiers.
sourcejedi
Qu'est-ce que "fd.o"?
TRiG
7

Selon la norme de hiérarchie du système de fichiers,

  • /run est pour les données variables d'exécution c.-à-d. des informations sur le système en cours depuis le redémarrage
  • /tmp est un endroit générique pour les fichiers temporaires.

Ainsi, tout ce qui concerne l'état du démon, les utilisateurs connectés, les périphériques amovibles montés, etc. serait inséré pendant /runque les fichiers temporaires créés par un programme y seraient insérés /tmp.

Edit: comme l'a souligné @JdeBP dans le commentaire ci-dessous,

La FHS permet, par exemple, la configuration classique de tâches cron qui purgent régulièrement les /tmp"anciens" fichiers; sans de tels mécanismes destinés à /run. D'où la limite draconienne à ce que les programmes peuvent attendre de la durée de vie de tout ce qui est mis en place /tmp. Alors que les programmes peuvent s’attendre à ce que les fichiers durent plus longtemps /runsur un système continuellement en place, ils sont également censés s’organiser davantage après eux-mêmes.

dr01
la source
4
Une chose non mentionnée dans cette réponse ou dans une autre, mais notée dans la FHS, et que vous aimeriez peut-être améliorer: - La FHS permet, par exemple, la configuration classique de tâches cron qui purgent régulièrement les /tmp"anciens" fichiers; sans de tels mécanismes destinés à /run. D'où la limite draconienne à ce que les programmes peuvent attendre de la durée de vie de tout ce qui est mis en place /tmp. Alors que les programmes peuvent s’attendre à ce que les fichiers durent plus longtemps /runsur un système continuellement en place, ils sont également censés s’organiser davantage après eux-mêmes.
JdeBP
1
Ce serait bien d'avoir un répertoire de processus qui contient des éléments qui ont disparu (ou ont été autorisés à être supprimés par un démon errant) dès la fin du processus.
Omnifarious
1
@Omnifarious vous pouvez maintenant obtenir ce comportement pour un service systemd, en utilisant RuntimeDirectory = :-).
sourcejedi le