Por que é possível excluir todo o sistema de arquivos?

24

Depois de cometer o infame erro de excluir todo o meu sistema de arquivos sudo rm -rf /*, recuperar-me dos horríveis danos que eu havia causado e lidar com o fato de ter acabado de perder 6 anos da minha vida útil, comecei a me perguntar por que é possível fazer isso, e o que poderia ser feito para impedir que esse erro acontecesse.

Uma solução que me foi sugerida é revogar o acesso root da minha conta, mas isso é inconveniente, porque muitos comandos exigem acesso root e quando você precisa executar algumas dezenas de comandos todos os dias, isso fica irritante.

Fazer backup do seu sistema é o caminho óbvio. Mas restaurar um backup também requer algum tempo de inatividade e, dependendo do sistema, esse tempo de inatividade pode ser de dias ou semanas, o que pode ser inaceitável em alguns casos.

Minha pergunta é: Por que não implementar uma confirmação quando o usuário tenta excluir seu sistema de arquivos? Assim, quando você realmente quer fazer isso, basta pressionar Y ou entrar e, se não fizer, pelo menos, não perderá tudo.

Mister_Fix
fonte
20
"Por que é possível fazer isso?" Por que não deveria ser possível? Existem perfeitamente boas razões para excluir o conteúdo de uma hierarquia de diretórios, e existem muitos subconjuntos /que seriam quase tão ruins para excluir ( /etc/por exemplo). Simplesmente não é o trabalho de rmdecidir quais diretórios podem ou não ser facilmente excluídos.
chepner 12/02
2
O título diz "Por que é possível excluir o sistema?" Considerando que a pergunta em si faz "Minha pergunta é: por que não implementar uma confirmação quando o usuário tenta excluir seu sistema de arquivos?". Portanto, isso torna a pergunta pouco clara. Qual é a sua pergunta real, então pelo menos sabemos o que responder? Por favor, edite sua postagem para esclarecer
Sergiy Kolodyazhnyy
3
Qual é realmente a questão aqui? Eu posso ver três: (1) Por que isso é possível? (2) como evitar fazê-lo? E (3) por que não implementar uma confirmação? - Eles não são a mesma pergunta, o primeiro pede raciocínio, o segundo para ferramentas. (O terceiro está relacionado ao segundo, mas ainda não é o mesmo. Uma confirmação não é a única maneira de evitar algo.)
ilkkachu
10
Se você não está pedindo esclarecimentos ao autor da pergunta, não faça nenhum comentário . Vejo muitos comentários de auto-congratulação aqui, explicando como isso é culpa do OP por não saber o que as bandeiras significam, ou por não ter um backup ou o que seja. Estou muito feliz em saber que muitos de nossos usuários são sábios o suficiente para ter backups e não executar comandos que eles não entendem. Isso é absolutamente bom para eles, mas fundamentalmente inútil para o OP que, presumivelmente, também aprendeu essa lição agora. Então, vamos parar de aproveitar nosso próprio brilho e responder à pergunta.
terdon

Respostas:

16

rmé uma ferramenta de sistema de baixo nível. Essas ferramentas são construídas da maneira mais simples possível e devem estar presentes em qualquer sistema. rmé esperado que tenha um comportamento bem conhecido, especialmente com relação aos prompts de confirmação, para que possam ser usados ​​em scripts.

Adicionar um caso especial a ser solicitado rm /*não seria possível, pois o comando rm não o vê neste formulário. O *curinga é expandido pelo shell antes de ser passado para rm, portanto, o comando real que precisa de um caso especial seria algo como rm /bin /boot /dev /etc /home /initrd.img /lib /lib64 /lost+found /media /mnt /opt /proc /root /run /sbin /srv /sys /tmp /usr /var /vmlinuz. Adicionar o código para verificar esse caso (que provavelmente será diferente em linuxes diferentes) seria um desafio complexo, além de propenso a erros sutis. O linux padrão rmtem uma proteção padrão contra a destruição do sistema, recusando-se a remover /sem a --no-preserve-rootopção.

Por padrão, existem três proteções contra a exclusão do sistema desta maneira:

  1. Permissões - usuários comuns não poderão remover arquivos importantes. Você ignorou isso com sudo
  2. Diretórios - por padrão, o rm não remove os diretórios. Você ignorou isso com o sinalizador -r
  3. Gravar arquivos protegidos - por padrão, o rm solicitará confirmação antes de excluir um arquivo protegido contra gravação (isso não teria interrompido todo o dano, mas pode ter fornecido um aviso antes que o sistema se torne irrecuperável). Você ignorou esta proteção com o sinalizador -f

Para remover todo o conteúdo de uma pasta, em vez de executá-lo rm /path/to/folder/*, faça isso rm -rf /path/to/folder, mkdir /path/to/folderpois isso ativará a --preserve-rootproteção e removerá todos os arquivos de ponto da pasta

Rhellen
fonte
3
"é esperado que o rm tenha um comportamento bem conhecido" e é de fato uma das ferramentas especificadas pelo padrão POSIX. "o curinga * é expandido pelo shell antes de ser passado para a rm" Exatamente, portanto, adicionar verificações para todos os tipos de parâmetros, que podem ser links simbólicos para diretórios e arquivos reais, /exigiria muitas combinações e considerações, por isso não é prático. E voltando à idéia de padrões, adicionar essas verificações quebraria o comportamento consistente
Sergiy Kolodyazhnyy
É exatamente por isso que safe-rmexiste um invólucro rm: dessa forma, ele pode verificar todos os argumentos (em vez de toda a linha de comando aleatória), verificar se não está na lista negra configurável e apenas chamar rmcom os argumentos verificados. Isso não é muito complexo nem propenso a erros.
dessert
59

Conheça safe-rmInstale o safe-rm, o "invólucro do rmcomando para evitar exclusões acidentais":

O safe-rm impede a exclusão acidental de arquivos importantes, substituindo-o rmpor um invólucro que verifica os argumentos fornecidos em relação a uma lista negra configurável de arquivos e diretórios que nunca devem ser removidos.

Os usuários que tentarem excluir um desses arquivos ou diretórios protegidos não poderão fazer isso e receberão uma mensagem de aviso. ( man safe-rm)

Se o link de instalação acima não funcionar, basta usar sudo apt install safe-rm. A configuração padrão já contém os diretórios do sistema, vamos tentar, rm /*por exemplo:

$ rm /*
safe-rm: skipping /bin
safe-rm: skipping /boot
safe-rm: skipping /dev
safe-rm: skipping /etc
safe-rm: skipping /home
safe-rm: skipping /lib
safe-rm: skipping /proc
safe-rm: skipping /root
safe-rm: skipping /sbin
safe-rm: skipping /sys
safe-rm: skipping /usr
safe-rm: skipping /var
…

Como você vê, isso impediria a exclusão /home, onde suponho que seus arquivos pessoais sejam armazenados. No entanto, isso não impede a exclusão ~ou nenhum de seus subdiretórios, se você tentar excluí-los diretamente. Para adicionar o ~/precious_photosdiretório, basta adicionar seu caminho absoluto com o til resolvido para safe-rmo arquivo de configuração /etc/safe-rm.conf, por exemplo:

echo /home/dessert/precious_photos | sudo tee -a /etc/safe-rm.conf

Para os casos em que você executa rmsem sudo1 e o -fsinalizador, é uma boa ideia adicionar umalias para o seu shell que torne rmo -isinalizador padrão. Dessa forma, rmsolicita todos os arquivos antes de excluí-lo:

alias rm='rm -i'

Um sinalizador igualmente útil é o de -Ique apenas alerta "uma vez antes de remover mais de três arquivos ou ao remover recursivamente", que é "menos invasivo do que -i, ao mesmo tempo em que protege contra a maioria dos erros":

alias rm='rm -I'

O perigo geral desses aliases é que você adquire facilmente o hábito de confiar neles para salvá-lo, o que pode sair pela culatra mal ao usar um ambiente diferente.


1: sudoignora aliases , pode-se contornar isso definindo alias sudo='sudo 'embora

sobremesa
fonte
25

A confirmação já está lá, o problema está -fno comando, ou seja --force; Quando o usuário força uma operação, supõe-se que ele saiba o que está fazendo (obviamente, um erro sempre pode ser acrescentado).

Um exemplo:

 rm -r ./*
 rm: remove write-protected regular file './mozilla_mvaschetto0/WEBMASTER-04.DOC'? N
 rm: cannot remove './mozilla_mvaschetto0': Directory not empty
 rm: descend into write-protected directory './pulse-PKdhtXMmr18n'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-bolt.service-rZWMCb'? n
 rm: descend into write-protected directory './systemd-private-     890f5b31987b4910a579d1c49930a591-colord.service-4ZBnUf'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-fwupd.service-vAxdbk'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-minissdpd.service-9G8GrR'? 
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-ModemManager.service-s43zUX'? nn
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-rtkit-daemon.service-cfMePv'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-systemd-timesyncd.service-oXT4pr'? n
 rm: descend into write-protected directory './systemd-private-890f5b31987b4910a579d1c49930a591-upower.service-L0k9rT'? n

É diferente com a --forceopção: Não receberei nenhuma confirmação e os arquivos são excluídos.

O problema é conhecer o comando e seus parâmetros, navegar mais no mancomando (também se o comando for encontrado em um tutorial) para obter exemplos: na primeira vez em que vi o comando tar xzf some.tar.gz, estou me perguntando "o que xzfsignifica? "

Então eu li a página de manual do alcatrão e a descobri.

AtomiX84
fonte
Eu não acho que isso seja relevante aqui. No momento em que a rm solicita pela primeira vez um arquivo protegido contra gravação ou qualquer outro arquivo, ele já pode ter excluído vários arquivos importantes.
Jonas Schäfer
1
Então, pessoalmente, sempre pensei que -fera necessário excluir pastas. Eu até abri um prompt para confirmar e reclamar, mas aprendi que apenas -ré necessário. Suponho que rm -rftenha se tornado a norma, pois é muito útil em um script (você não deseja que o script falhe apenas porque está tentando excluir coisas que não existem), para que você o veja com frequência, mas suponho que precisamos estar vigilante sobre apenas usar rm -rcomo nosso "padrão" quando estiver em um shell (compreensivelmente não deve haver suposições "padrão" que você não entende, especialmente no sudo, mas as pessoas serão pessoas e, pelo menos, isso é mais seguro).
Captain Man
2
Rmdir é a maneira mais segura de excluir uma pasta
AtomiX84
rmnão solicita confirmação por padrão, apenas solicita diretórios e arquivos protegidos contra gravação. Se você executou esse comando em sua máquina, provavelmente excluiu muitos de seus próprios arquivos. Se você precisar rmpedir confirmação, precisará passar o -iparâmetro Por exemplo:rm -ir ./*
Dan
8

Executar sem backups significa que você deve ter muito cuidado para nunca cometer erros. E espero que seu hardware nunca falhe. (Mesmo o RAID não pode salvá-lo da corrupção do sistema de arquivos causada por falha na RAM.) Esse é o seu primeiro problema. (Presumo que você já tenha percebido e fará backups no futuro.)


Mas existem coisas que você pode fazer para reduzir a probabilidade de erros como este:

  • alias rm='rm -I'para avisar se excluir mais de três itens.
  • alias mv e cp para mv -ie cp -i(muitos casos de uso normais para esses não envolvem sobrescrever um arquivo de destino).
  • alias sudo='sudo 'para fazer expansão alias no primeiro argumento parasudo

Eu acho que rm -Ié muito mais útil que rm -i. Normalmente, ele não é solicitado durante o uso normal; portanto, a digitação é solicitada quando você não espera que seja um aviso muito mais perceptível / melhor. Com -i(antes de descobrir -I), me acostumei a digitar \rmpara desativar a expansão de alias, depois de ter certeza de que havia digitado o comando corretamente.

Você não deseja adquirir o hábito de confiar rm -iou usar -Ipseudônimos para salvá-lo . É sua linha de segurança que você espera que nunca seja usada. Se eu realmente quiser selecionar interativamente quais correspondências excluir ou se não tiver certeza se meu glob pode corresponder a alguns arquivos extras, digito manualmente rm -i .../*whatever*. (Também é um bom hábito, caso você esteja em um ambiente sem seus pseudônimos).

Defenda-se contra o dedilhado Enterdigitando ls -d /*foo*primeiro , depois a seta para cima e altere para rm -rdepois que você terminar de digitar. Portanto, a linha de comando nunca contém rm -rf ~/comandos perigosos similares a qualquer momento. Você apenas o "arma", mudando lspara rmcom control-a, alt-d para ir para o início da linha e adicionando o -rou o -fdepois que você terminar de digitar a ~/some/sub/dir/parte do comando.

Dependendo do que você está excluindo, execute o ls -dprimeiro, ou não, se isso não adicionar nada ao que você vê com o preenchimento de guias. Você pode começar com rm(sem -rou -rf), então é apenas control-a / control-right (ou alt + f) / space / -r.

(Acostume-se com as poderosas combinações de teclas de edição do readline para mover-se rapidamente, como setas de controle ou alt + f / b para mover por palavras e matar palavras inteiras com alt + backspace ou alt + d ou control-w. -u para matar o início da linha. E controle- / para desfazer uma edição se você for um passo longe demais. E, é claro, o histórico da seta para cima que você pode pesquisar com control-r / control-s.)

Evite, a -rfmenos que você realmente precise silenciar as solicitações sobre a remoção de arquivos somente leitura.

Reserve um tempo extra para pensar antes de pressionar retornar em um sudocomando. Especialmente se você não tiver backups completos, ou agora seria um momento ruim para restaurá-los.

Peter Cordes
fonte
6

Bem, a resposta curta é não executar esse comando.

A longa história é que isso faz parte da personalização. Essencialmente, existem dois fatores em jogo aqui. Um é o fato de você poder modificar todos os arquivos.

A segunda é que o comando rm oferece o açúcar sintático útil para excluir todos os arquivos em uma pasta.

Efetivamente, isso poderia ser reafirmado como um princípio simples e simples de máquinas Unix. Tudo é um arquivo . Para melhorar as coisas, há controles de acesso, mas eles são substituídos pelo uso de

sudo

Eu acho que você pode adicionar um alias ou uma função para garantir que isso nunca possa ser executado.

HaoZeke
fonte
4

Se o uso do espaço no arquivo do sistema não for imenso (e hoje em dia, 'imenso' significa 'centenas de gigabytes ou mais'), crie algumas instâncias da máquina virtual e sempre trabalhe dentro de uma. A recuperação implicaria apenas o uso de uma instância de backup.

Ou você pode criar uma prisão chroot e trabalhar dentro dela. Você ainda precisaria de alguma recuperação se ela fosse lixeira, mas seria mais fácil trabalhar com um sistema em execução (fechado).

Loren Rosen
fonte
Essa é provavelmente a resposta mais eficaz, pois pode proteger contra danos, mesmo scripts de terceiros. Você só precisa se preocupar com malware real.
PyRulez 12/02
Pensou em outro ângulo. Vale a pena perguntar por que você precisa fazer exclusões recursivas em primeiro lugar. Talvez o que realmente seja necessário são alguns scripts para remover um projeto etc.
Loren Rosen
"Vale a pena perguntar por que você precisa fazer exclusões recursivas em primeiro lugar". Bem, só porque não há comando embutido não significa que você ainda não pode cometer um erro. Scripts de terceiros podem excluir arquivos um por um de algum diretório. E há outras maneiras de usar o sistema que apenas toca em um arquivo. No entanto, substituir rmpor safe-rmajuda, pelo menos.
PyRulez 12/02
Minha noção do script era que ele teria uma noção interna de um 'projeto' ou similar. Talvez você tenha um arquivo vazio na raiz do projeto chamado .project_rootou, se o sistema de arquivos o suportar, um atributo no próprio diretório. Em seguida, o script subia na árvore de arquivos procurando a raiz do projeto e reclamava que o diretório atual não estava em um projeto. Ou, se todos os projetos estiverem no mesmo local, o script poderá exigir que você nomeie um projeto. Você ainda pode excluir o projeto errado, mas não destruir o sistema inteiro.
Loren Rosen
... também, uma variante chrootseria usar algo como o Docker (que eu acho que realmente usa chrootdebaixo das cobertas). Para outros arquivos que você só precisa ler, monte um sistema de arquivos somente leitura.
Loren Rosen
3

rmé um comando Unix muito antigo e provavelmente não foi projetado com a facilidade de uso em mente. Ele tenta fazer exatamente o que é solicitado, quando possui as permissões. Uma armadilha para muitos usuários novos é que eles frequentemente veem o código sudoe não pensam muito em usá-lo. Funções que modificam diretamente arquivos como rm, dd, chroot, etc. exigem extremo cuidado em uso.

Hoje em dia eu gosto de usar trash(sem sudo) do lixo-cli . Funciona como a Lixeira do Windows, na qual você pode recuperar facilmente arquivos excluídos acidentalmente. O Ubuntu já possui uma pasta Lixeira e a funcionalidade mover para o lixo incorporada ao Files.

Mesmo assim, você pode cometer erros, portanto, faça backups de todo o seu sistema de arquivos.

qwr
fonte