¿Cuál es la diferencia entre / tmp y / run?

42

De acuerdo con FHS-3.0 , /tmpes para archivos temporales y /runpara datos variables en tiempo de ejecución. Los datos /rundeben eliminarse en el próximo inicio, lo cual no es necesario /tmp, pero los programas aún no deben suponer que los datos /tmpestarán disponibles en el próximo inicio del programa. Todo esto me parece bastante similar.

Entonces, ¿cuál es la diferencia entre los dos? ¿Con qué criterio debe decidir un programa si se deben incluir /tmpo no datos temporales /run?

De acuerdo con la FHS:

Los programas pueden tener un subdirectorio de /run; Esto se recomienda para los programas que usan más de un archivo de tiempo de ejecución.

Esto indica que la distinción entre "programas del sistema" y "programas ordinarios" no es un criterio, ni tampoco lo es la vida útil del programa (como el proceso de larga duración versus el de corta duración).

Aunque la siguiente justificación no se da en el FHS, /runse introdujo para superar el problema que /varse montó demasiado tarde, de modo que se necesitaban trucos sucios para ponerlos a /var/rundisposición lo suficientemente pronto. Sin embargo, ahora que /runse introdujo, y dada su descripción en el FHS, no parece haber una razón clara para tener ambos /runy /tmp.

Dirk Herrmann
fuente
11
/ tmp es la ubicación estándar * nix para datos temporales. / run es la ubicación estándar de Poettering para datos temporales.
Mark
La compatibilidad con versiones anteriores siempre es una razón ...
Bakuriu

Respuestas:

16

No hay razón para tener tanto / run como / tmp

Creo que tienes razón. /tmpEs esencialmente obsoleto ahora tenemos /run. Si su programa está en condiciones de hacerlo (lo que requiere que se haya instalado como una operación privilegiada), entonces hoy en día usaría un subdirectorio de /run. Esto es por razones de seguridad.

Por ejemplo, el demonio de impresión CUPS no se ejecuta como root, pero generalmente se instala desde un paquete del sistema operativo. El paquete se instala /usr/lib/tmpfiles.d/cups.confy systemd-tmpfilescrea un directorio al que puede acceder. Dado que el directorio está debajo /run, el nombre no puede haber sido reclamado maliciosamente por un usuario sin privilegios, a diferencia de lo /tmpque se puede escribir en el mundo.

"Programas sin privilegios" que no se pueden usar /rundirectamente

La verdadera distinción es si su programa está siendo ejecutado por un usuario arbitrario sin privilegios, bajo su propia identificación de usuario. Pero, en general, aún no desea usarlo /tmp, ya que otros usuarios sin privilegios pueden acceder a él. Prefieres usar $XDG_RUNTIME_DIR. Por lo general, esto se implementa como /run/user/$(id -u), por lo que resulta ser un subdirectorio /runtambién. Sin embargo, la ubicación no está garantizada; Los programas siempre deben usar la variable de entorno.

/tmpsolo sería útil para la cooperación ad-hoc entre diferentes usuarios sin privilegios en el sistema. Dichos sistemas ad-hoc son vulnerables a que un usuario malintencionado se niegue a cooperar y estropee las cosas para todos :). Un ejemplo serían los usuarios no privilegiados que deciden ejecutar una versión del talkdemonio, utilizando un socket Unix.

Información original de Lennart Poettering

Tenga en cuenta que la lista de verificación de Poettering a continuación afirmaba que /tmpsería útil para "archivos pequeños", mientras /runque solo debería usarse para "primitivas de comunicación". Tampoco creo que esta distinción sea cierta. El chico del cartel /runes udev, y estoy bastante seguro de que /run/udevincluye bases de datos internas. Una vez que tenga un /rundirectorio, no creo que nadie quiera seguir la distinción reclamada y crear otro directorio, para desordenar /tmp. Entonces, en la práctica, solo usamos /runhoy en día.

El uso de espacios de nombres compartidos en todo el mundo [like / tmp] para fines de comunicación siempre ha sido problemático, ya que para establecer la comunicación se necesitan nombres estables, pero los nombres estables abren las puertas a los ataques DoS. Esto puede corregirse parcialmente, mediante el establecimiento de directorios protegidos por aplicación para ciertos servicios durante el inicio temprano (como lo hacemos para X11), pero esto solo soluciona el problema parcialmente, ya que esto solo funciona correctamente si cada instalación de paquete es seguida por un reinicio.

...

Otra característica de Fedora (para Fedora 17) cambió la semántica de / tmp para muchos servicios del sistema para hacerlos más seguros, al aislar los espacios de nombres / tmp de los diversos servicios

...

Debido a que / tmp ya no es necesariamente un espacio de nombres compartido, generalmente no es adecuado como ubicación para las primitivas de comunicación.

...

[/ run] se garantiza que es un tmpfs y, por lo tanto, se descarga automáticamente en las botas. No se realiza una limpieza automática más allá de eso.

...

Aquí hay una guía aproximada de cómo le sugerimos (un desarrollador de aplicaciones de Linux) que elija el directorio correcto para usar:

  1. Necesita un lugar para colocar su socket (u otra primitiva de comunicación) y su código se ejecuta con privilegios: use un subdirectorio debajo de / run. (O debajo de / var / run para una compatibilidad adicional).
  2. Necesita un lugar para colocar su socket (u otra primitiva de comunicación) y su código se ejecuta sin privilegios: use un subdirectorio debajo de $ XDG_RUNTIME_DIR.
  3. Necesita un lugar para poner sus descargas y descargas más grandes en progreso y ejecutar sin privilegios: use $ XDG_DOWNLOAD_DIR.
  4. Necesita un lugar para colocar los archivos de caché que deben ser persistentes y ejecutarse sin privilegios: use $ XDG_CACHE_HOME.
  5. No se aplica nada de lo anterior y debe colocar un archivo pequeño que no necesite persistencia: use $ TMPDIR con un respaldo en / tmp. Y use mkstemp () y mkdtemp () y nada de cosecha propia.
  6. De lo contrario, use $ TMPDIR con un respaldo en / var / tmp. También use mkstemp () / mkdtemp ().

Tenga en cuenta que estas reglas anteriores solo son sugeridas por nosotros. Estas reglas tienen en cuenta todo lo que sabemos sobre este tema y evitan problemas con las distribuciones actuales y futuras, por lo que podemos ver. Considere actualizar sus proyectos para seguir estas reglas, y téngalos en cuenta si escribe un código nuevo.

Una cosa que nos gustaría enfatizar es que / tmp y / var / tmp en la mayoría de los casos no son la opción correcta para su caso de uso. Hay usos válidos de estos directorios, pero a menudo otro directorio podría ser el mejor lugar. Por lo tanto, tenga cuidado, considere las otras opciones, pero si elige / tmp o / var / tmp, al menos asegúrese de usar mkstemp () / mkdtemp ().

De alguna manera nos salimos con el /tmpsocket heredado utilizado por el sistema de ventanas X, como se describió anteriormente. Yo leí mal tmpfiles.d/x11.conf. Parece más que depende de la cooperación :). Supongo que el código ha sido auditado, de modo que la denegación de servicio es lo peor que puede suceder.

sourcejedi
fuente
8
Esta respuesta es todo tipo de error.
R ..
@R .., ¿quieres ampliar eso?
Comodín el
Sí, ya lo hice en una respuesta. (Comenzó como un comentario pero me di cuenta de que era más una respuesta.)
R ..
Creo que la principal debilidad en mi respuesta actual, en la que creo que estaba trabajando, es que, aunque técnicamente , se requiere un manejo correcto de XDG_RUNTIME_DIR para ser portátil a cualquier * nix ("recurrir a un directorio de reemplazo con capacidades similares"), Es muy vago lo que esto significa en la práctica. Para los programas de utilidad portátiles, es mejor usar el estándar bien definido para /tmp("las únicas API para usarlo deberían ser mkstemp (), mkdtemp () (y amigos) para que sean completamente seguras").
sourcejedi
La respuesta también es un caso común: /var/runes de todo el sistema (por ejemplo, para comunicarse con la base de datos local), /tmp/ahora se crea por usuario . Históricamente, también la cuota de / tmp se estableció de manera diferente. Y la respuesta omite que una distinción semántica de uso también es importante.
Giacomo Catenazzi
23

Los directorios /tmpy /usr/tmp(más tarde /var/tmp) solían ser el vertedero de todo y de todos. El único mecanismo de protección para los archivos en estos directorios es el bit fijo que restringe la eliminación o el cambio de nombre de los archivos a sus propietarios. Como marcelm señaló en un comentario, en principio no hay nada que impida que alguien cree archivos con nombres que son utilizados por los servicios (como nginx.pido sshd.pid). (Sin embargo, en la práctica, los scripts de inicio podrían eliminar esos archivos falsos primero).

/runse estableció para datos de tiempo de ejecución no persistentes de servicios de larga duración, como bloqueos, sockets, archivos pid y similares. Como no se puede escribir para el público, protege los datos de tiempo de ejecución del servicio del desorden /tmpy los trabajos que limpian allí. De hecho: dos distribuciones que ejecuto (sin juego de palabras) tienen permisos 755 /run, mientras que /tmpy /var/tmp(y /dev/shmpara el caso) tienen permisos 1777.

contramodo
fuente
3
simplemente está ahí para separar los datos de tiempo de ejecución del servicio del desastre/tmp - También para proporcionar un puerto seguro para dichos datos de los diversos trabajos de limpieza que pisotean en todo momento /tmp.
Satō Katsura el
Gracias por la información sobre los permisos. Sin embargo, de acuerdo con FHS "Los programas pueden tener un subdirectorio de / ejecución; esto se recomienda para los programas que usan más de un archivo de tiempo de ejecución". - Esto parece contradecir tanto el criterio de "servicios de larga duración" como la incapacidad de los programas para crear sus subdirectorios debido a los permisos limitados.
Dirk Herrmann el
@DirkHerrmann No, no lo hace. Eche un vistazo /runy eche un vistazo a la estructura de directorios compleja (bueno ...) causada por udev, udisketc. No soy un experto en este tema en particular, pero supongo que los scripts de arranque (que se ejecutan como superusuario) configuran todo.
contramodo
2
"/ run no es técnicamente necesario, simplemente está ahí para separar los datos de tiempo de ejecución del servicio del desastre en / tmp". - También es bueno, por lo que los procesos no privilegiados no pueden utilizar nombres que los servicios del sistema quieren usar. Un poco apesta si nginx quiere usar /tmp/nginx.pidpero ya existe debido a algún programa que se está portando mal. /run/evita esto al requerir privilegios para escribir.
marcelm
18

/tmpes la ubicación para la creación de archivos y directorios temporales. No es utilizable para almacenar "nombres conocidos" (es decir, nombres que otro proceso podría tener en cuenta sin que tenga que transmitir el nombre de alguna manera) porque nadie tiene la propiedad sobre el espacio de nombres; cualquiera puede crear archivos allí. Como tal, generalmente lo usa cuando tiene una utilidad que necesita un archivo (es decir, no una tubería o tal) como entrada o salida, donde cualquier nombre (generado aleatoriamente) funcionará siempre que pase el nombre.

Históricamente, algunas cosas (como X) violaron este principio y pusieron nombres conocidos (como .X11-unix) /tmp. Por supuesto, esto tiene errores y permite a cualquier usuario hacer el servicio que necesita hacerlo simplemente compitiendo para crear un archivo con el nombre deseado primero. Tales cosas pertenecen a /run(o equivalente /var/runsi no se suscribe al revisionismo de Freedesktop.org). Por supuesto, incluso mejor sería arreglarlos para que no usen nombres conocidos en un espacio de nombres global, sino que pasen un nombre de ruta.

R ..
fuente
Gracias por alguna definición más sobre "archivos temporales". Aunque no creo que "pasar un nombre de ruta" explique cómo establecer un punto de coordinación. Es decir, normalmente usarías una variable de entorno. Parece que hay pocos enchufes y tuberías suficientes (en uso general) para que funcione. (En parte porque muchas cosas se ejecutarán en el mismo socket dbus). Sin embargo, parece molesto establecer el entorno si los programas no tienen una ruta predeterminada. Podría agregar una nueva clave a los .socketarchivos de systemd ... pero eso no ayuda para directorios completos, ni para servicios recién instalados
sourcejedi
2
/run/fue adoptado por FHS, no puedo ver cómo tiene algo que ver con fd.o. A menos que lo que realmente quisiéramos quejarnos sean esfuerzos de desarrollo no especificados que hayan contribuido a ambos.
sourcejedi
Creo que la respuesta inicial aquí es la mejor respuesta aquí para la pregunta tal como está escrita. Creo que se mejoraría aún más al considerar: _Cuando el software tiene acceso de escritura a un directorio dedicado, por ejemplo /run, debajo , podría optar por evitar saturar el /tmpdirectorio compartido con aún más archivos.
sourcejedi
¿Qué es "fd.o"?
TRiG
7

De acuerdo con el Estándar de jerarquía del sistema de archivos,

  • /run es para datos variables de tiempo de ejecución, es decir, información sobre el sistema en ejecución desde el reinicio
  • /tmp es un lugar genérico para archivos temporales.

Por lo tanto, cualquier cosa relacionada con el estado del demonio, los usuarios registrados, los dispositivos extraíbles montados, etc. entraría /runmientras entraban los archivos temporales creados por un programa /tmp.

Editar: como señaló @JdeBP en el comentario a continuación,

El FHS permite cosas como la configuración convencional de trabajos cron que purgan regularmente los /tmparchivos "antiguos"; sin tales mecanismos destinados a /run. De ahí el límite draconiano sobre qué programas pueden esperar de la vida útil de cualquier cosa puesta /tmp. Si bien los programas pueden esperar que los archivos vivan más tiempo en /runun sistema en funcionamiento continuo, también se espera que se arreglen más.

dr01
fuente
44
Una cosa que no se señaló en esta o en ninguna otra respuesta, pero que se señaló en el FHS, y con la que le gustaría mejorar su respuesta: El FHS permite cosas como la configuración convencional de trabajos cron que purgan regularmente los /tmparchivos "antiguos"; sin tales mecanismos destinados a /run. De ahí el límite draconiano sobre qué programas pueden esperar de la vida útil de cualquier cosa puesta /tmp. Si bien los programas pueden esperar que los archivos vivan más tiempo en /runun sistema en funcionamiento continuo, también se espera que se arreglen más.
JdeBP
1
Sería bueno tener un directorio por proceso de cosas que desaparecieron (o se permitió que un demonio de basura itinerante lo borrara) tan pronto como el proceso murió.
Omnifarious
1
@Omnifarious ahora puede obtener ese comportamiento para un servicio systemd, utilizando RuntimeDirectory = :-).
sourcejedi