Qual é a diferença entre / tmp e / run?

42

De acordo com o FHS-3.0 , /tmpé para arquivos temporários e /runpara dados variáveis ​​em tempo de execução. Os dados /rundevem ser excluídos na próxima inicialização, o que não é necessário /tmp, mas os programas ainda não devem assumir que os dados /tmpestarão disponíveis no próximo início do programa. Tudo isso parece muito parecido comigo.

Então qual é a diferença entre os dois? Por qual critério um programa deve decidir se coloca /tmpou não dados temporários /run?

De acordo com a ESF:

Os programas podem ter um subdiretório de /run; isso é recomendado para programas que usam mais de um arquivo de tempo de execução.

Isso indica que a distinção entre "programas do sistema" e "programas comuns" não é um critério, nem a vida útil do programa (como processo de execução longa versus execução curta).

Embora a lógica a seguir não seja dada na ESF, /runfoi introduzida para superar o problema que /varfoi montado tarde demais, de modo que truques sujos eram necessários para /var/rundisponibilizar com antecedência suficiente. No entanto, agora, ao /runser apresentado, e dada sua descrição na ESF, não parece haver uma razão clara para ter ambos /rune /tmp.

Dirk Herrmann
fonte
11
/ tmp é o local padrão * nix para dados temporários. / run é o local padrão de Poettering para dados temporários.
Mark
Compatibilidade para trás é sempre uma razão ...
Bakuriu

Respostas:

16

Não há razão para ter ambos / run e / tmp

Eu acho que você está certo. /tmpestá essencialmente obsoleto agora temos /run. Se o seu programa estiver em condições de fazê-lo (o que exige que ele tenha sido instalado como uma operação privilegiada), hoje em dia você usaria um subdiretório /run. Isto é por razões de segurança.

Por exemplo, o daemon de impressão CUPS não é executado como root, mas geralmente é instalado a partir de um pacote do SO. O pacote instala /usr/lib/tmpfiles.d/cups.confe systemd-tmpfilescria um diretório que ele pode acessar. Como o diretório está sob /run, o nome não pode ter sido reivindicado maliciosamente por um usuário sem privilégios, diferente do /tmpque é gravável no mundo.

"Programas não privilegiados" que não podem ser usados /rundiretamente

A distinção real é se o seu programa estiver sendo executado por um usuário arbitrário e sem privilégios, com seu próprio ID de usuário. Mas você geralmente ainda não deseja usar /tmp, porque pode ser acessado por outros usuários não privilegiados. Você prefere usar $XDG_RUNTIME_DIR. Normalmente, isso é implementado como /run/user/$(id -u)- portanto, também é um subdiretório /run. A localização não é garantida; programas sempre devem usar a variável de ambiente.

/tmpseria útil apenas para cooperação ad-hoc entre diferentes usuários não privilegiados no sistema. Esses sistemas ad-hoc são vulneráveis ​​a um usuário mal-intencionado que se recusa a cooperar e estraga tudo para todos :). Um exemplo seria usuários sem privilégios que decidem executar uma versão do talkdaemon, usando um soquete unix.

Informação original de Lennart Poettering

Observe que a lista de verificação de Poettering abaixo alegou que /tmpseria útil para "arquivos pequenos", enquanto que /rundeveria ser usada apenas para "primitivas de comunicação". Também não acho que essa distinção seja verdadeira. O garoto-propaganda de /runé udev, e tenho certeza que /run/udevinclui bancos de dados internos. Depois de ter um /rundiretório, acho que ninguém quer seguir a distinção reivindicada e criar outro diretório, para desordenar /tmp. Então, na prática, usamos apenas /runhoje em dia.

O uso de namespaces compartilhados graváveis ​​em todo o mundo [como / tmp] para fins de comunicação sempre foi problemático, pois para estabelecer a comunicação você precisa de nomes estáveis, mas os nomes estáveis ​​abrem as portas para ataques de DoS. Isso pode ser corrigido parcialmente, estabelecendo diretórios por aplicativo protegidos para determinados serviços durante a inicialização antecipada (como fazemos no X11), mas isso corrige apenas parcialmente o problema, pois isso funciona corretamente se todas as instalações de pacotes forem seguidas por uma reinicialização.

...

Outro recurso do Fedora (para o Fedora 17) mudou a semântica do / tmp para muitos serviços do sistema para torná-los mais seguros, isolando os namespaces / tmp dos vários serviços

...

Como / tmp não é mais necessariamente um espaço para nome compartilhado, geralmente é inadequado como local para primitivas de comunicação.

...

[/ run] tem a garantia de ser um tmpfs e, portanto, é liberado automaticamente nas botas. Nenhuma limpeza automática é feita além disso.

...

Aqui está um guia aproximado de como sugerimos que você (um desenvolvedor de aplicativos Linux) escolha o diretório certo para usar:

  1. Você precisa de um local para colocar seu soquete (ou outra primitiva de comunicação) e seu código é privilegiado: use um subdiretório abaixo / execute. (Ou abaixo de / var / run para compatibilidade extra.)
  2. Você precisa de um local para colocar seu soquete (ou outra primitiva de comunicação) e seu código é executado sem privilégios: use um subdiretório abaixo de $ XDG_RUNTIME_DIR.
  3. Você precisa de um local para colocar seus downloads e downloads maiores em andamento e executar sem privilégios: use $ XDG_DOWNLOAD_DIR.
  4. Você precisa de um local para colocar arquivos de cache que devem ser persistentes e executados sem privilégios: use $ XDG_CACHE_HOME.
  5. Nada disso se aplica e você precisa colocar um arquivo pequeno que não precise de persistência: use $ TMPDIR com um fallback em / tmp. E use mkstemp () e mkdtemp () e nada caseiro.
  6. Caso contrário, use $ TMPDIR com um fallback em / var / tmp. Use também mkstemp () / mkdtemp ().

Observe que essas regras acima são sugeridas apenas por nós. Essas regras levam em consideração tudo o que sabemos sobre esse tópico e evitam problemas com distribuições atuais e futuras, tanto quanto podemos vê-las. Por favor, considere atualizar seus projetos para seguir essas regras e tenha em mente se você escrever um novo código.

Uma coisa que gostaríamos de enfatizar é que / tmp e / var / tmp com mais frequência do que não são, na verdade, a escolha certa para a sua utilização. Existem usos válidos desses diretórios, mas muitas vezes outro diretório pode realmente ser o melhor lugar. Portanto, tenha cuidado, considere as outras opções, mas se você optar por / tmp ou / var / tmp, certifique-se de usar mkstemp () / mkdtemp ().

Nós meio que escapamos do /tmpsoquete herdado usado pelo sistema X window, como descrito acima. Eu interpretei errado tmpfiles.d/x11.conf. Parece mais com a cooperação :). Presumo que o código foi auditado, de modo que a negação de serviço é a pior coisa que pode acontecer.

sourcejedi
fonte
8
Esta resposta está errada.
R ..
@R .., gostaria de expandir isso?
Curinga
Sim, eu já respondi. (Começou como um comentário, mas eu percebi que era mais uma resposta.)
R. ..
Acho que a principal fraqueza da minha resposta atual, na qual acho que você estava trabalhando, é que, embora tecnicamente , o manuseio correto de XDG_RUNTIME_DIR seja necessário para ser portável para qualquer * nix ("volte para um diretório de substituição com recursos semelhantes"), é muito vago o que isso significa na prática. Para programas utilitários portáteis, é melhor usar o padrão bem definido para /tmp("as únicas APIs para usá-lo devem ser mkstemp (), mkdtemp () (e amigos) para ser totalmente seguro").
sourcejedi
A resposta também está ausente : /var/runé um sistema amplo (por exemplo, para se comunicar com o banco de dados local), /tmp/agora é criado por usuário . Historicamente, também a cota de / tmp foi definida diferente. E a resposta perde que uma distinção semântica de uso também é importante.
Giacomo Catenazzi
23

Os diretórios /tmpe /usr/tmp(mais tarde /var/tmp) costumavam ser o depósito de lixo para tudo e para todos. O único mecanismo de proteção para arquivos nesses diretórios é o bit que restringe a exclusão ou renomeação de arquivos para seus proprietários. Como o marcelm apontou em um comentário, não há, em princípio, nada que impeça alguém de criar arquivos com nomes usados ​​pelos serviços (como nginx.pidou sshd.pid). (Na prática, os scripts de inicialização podem remover esses arquivos falsos primeiro.)

/runfoi estabelecido para dados de tempo de execução não persistentes de serviços de longa duração, como bloqueios, soquetes, arquivos pid e similares. Como não é gravável para o público, protege os dados de tempo de execução do serviço da bagunça /tmpe dos trabalhos que são limpos lá. Na verdade: duas distribuições que eu corro (sem trocadilhos) têm permissões 755 /run, enquanto /tmpe /var/tmp(e, /dev/shmnesse caso) têm permissões 1777.

contra-modo
fonte
3
está simplesmente lá para separar os dados do tempo de execução do serviço da bagunça/tmp - Também para fornecer um porto seguro para os dados mencionados, dos vários trabalhos de limpeza que ocorrem normalmente /tmp.
Satō Katsura
Obrigado pela informação sobre as permissões. No entanto, de acordo com a FHS "Os programas podem ter um subdiretório de / run; isso é recomendado para programas que usam mais de um arquivo em tempo de execução". - isso parece contradizer o critério dos "serviços de longa duração" e a incapacidade dos programas de criar seus subdiretórios devido a permissões limitadas.
Dirk Herrmann
@DirkHerrmann Não, não. Ter um olhar /rune confira o complexo estrutura de diretório (bem ...) causada por udev, udisketc. Eu não sou um especialista sobre esta questão particular, mas eu acho que os scripts de inicialização (que são executados como superusuário) configurar tudo.
Contramodo #
2
"tecnicamente / run não é tecnicamente necessário, existe simplesmente para separar os dados do tempo de execução do serviço da bagunça em / tmp." - Ainda bem, para que processos não privilegiados não possam ocupar nomes que os serviços do sistema desejam usar. É meio ruim se o nginx quiser usar, /tmp/nginx.pidmas ele já existe por causa de algum programa que se comporta mal. /run/evita isso exigindo privilégios nos quais gravar.
marcelm
18

/tmpé o local para criação de arquivos e diretórios temporários. Não é útil armazenar "nomes conhecidos" (ou seja, nomes que outro processo poderia ter conhecimento sem que você tivesse que transmitir o nome de alguma forma) porque ninguém possui propriedade sobre o espaço para nome; qualquer um pode criar arquivos lá. Como tal, você geralmente o utiliza quando possui um utilitário que precisa de um arquivo (por exemplo, não um canal ou outro) como entrada ou saída, onde qualquer nome (gerado aleatoriamente) funcionará desde que você o passe.

Historicamente, algumas coisas (como X) violaram esse princípio e colocaram nomes conhecidos (como .X11-unix) /tmp. Obviamente, isso é um buggy e permite que qualquer usuário faça o serviço de DoS, precisando simplesmente fazê-lo correndo para criar um arquivo com o nome desejado primeiro. Essas coisas pertencem a /run(ou equivalentemente, /var/runse você não assinar o revisionismo do Freedesktop.org). É claro que o melhor seria corrigi-los para não usar nomes conhecidos em um espaço para nome global, mas passar um nome de caminho.

R ..
fonte
Obrigado por mais algumas definições sobre "arquivos temporários". Embora eu não ache que "repassar um nome de caminho" explica como estabelecer um ponto de coordenação. Ou seja, geralmente você usaria uma variável de ambiente. Parece que existem poucos soquetes e tubos suficientes (em uso geral) para permitir que funcione. (Em parte porque muitas coisas serão executadas no mesmo soquete dbus). Parece que seria irritante definir o ambiente, se os programas não tivessem como padrão um caminho codificado. Você pode adicionar uma nova chave para Systemd .socketarquivos ... mas isso não ajuda para diretórios inteiros, nem para os serviços recém-instalados
sourcejedi
2
/run/em si foi adotado pela ESF, não vejo como isso tem a ver com a fd.o. A menos que realmente pretendamos reclamar, há esforços de desenvolvimento não especificados que contribuíram para ambos.
sourcejedi
Eu acho que a resposta inicial aqui é a melhor resposta aqui para a pergunta escrita. Eu acho que seria melhorado ainda mais, considerando: _Quando o software tem acesso de gravação a um diretório dedicado, por exemplo /run, sob , ele pode optar por evitar sobrecarregar o /tmpdiretório compartilhado com mais arquivos.
sourcejedi
O que é "fd.o"?
TRiG 14/10
7

De acordo com o padrão de hierarquia do sistema de arquivos,

  • /run é para dados variáveis ​​de tempo de execução, ou seja, informações sobre o sistema em execução desde a reinicialização
  • /tmp é um local genérico para arquivos temporários.

Portanto, qualquer coisa relacionada ao status do daemon, usuários conectados, dispositivos removíveis montados etc. entraria /runenquanto os arquivos temporários criados por um programa entrariam /tmp.

Edit: como apontado por @JdeBP no comentário abaixo,

O FHS permite coisas como a configuração convencional de tarefas cron que limpam regularmente /tmparquivos "antigos"; sem esses mecanismos destinados /run. Daí o limite draconiano sobre o que os programas podem esperar da vida de qualquer coisa colocada /tmp. Embora os programas possam esperar que os arquivos permaneçam mais tempo em /runum sistema continuamente ativo, também é esperado que eles se arrumam mais lá.

dr01
fonte
4
Uma coisa não apontada nesta ou em qualquer outra resposta, mas observada na ESF, e com a qual você gostaria de melhorar sua resposta: A ESF permite coisas como a configuração convencional de tarefas cron que limpam regularmente /tmparquivos "antigos"; sem esses mecanismos destinados /run. Daí o limite draconiano sobre o que os programas podem esperar da vida de qualquer coisa colocada /tmp. Embora os programas possam esperar que os arquivos permaneçam mais tempo em /runum sistema continuamente ativo, também é esperado que eles se arrumam mais lá.
JdeBP # 13/16
11
Seria bom ter um diretório por processo de coisas que desapareceram (ou foram permitidas a serem excluídas por algum daemon de lixo móvel) assim que o processo morreu.
omniforme
11
@ Oniforme agora você pode obter esse comportamento para um serviço systemd, usando RuntimeDirectory = :-).
sourcejedi 14/07