Como sempre aplicar a senha do sudo para um comando específico?

12

No outro dia, eu estava fazendo algumas tarefas de manutenção no meu servidor web. Eu estava com pressa e com sono, então fiz tudo usando o sudocomando.

E então, pressionei acidentalmente Ctrl+ V, enviando este comando para o meu servidor web:

sudo rm -rf /*

Para aqueles que se perguntam o que o comando acima faz: Isso excluiu todo o meu servidor web

Felizmente, eu tinha backups e, infelizmente, tive que passar mais duas horas acordado para corrigir esse erro impressionante. Mas desde então, eu tenho me perguntado:

Existe uma maneira de sempre impor a senha do sudo para um comando específico?

Se o servidor me pedisse uma senha, eu me salvaria de muitos problemas. Não foi, porque eu executei cerca de 5 sudocomandos antes desse erro majestoso.

Então, existe uma maneira de fazer isso? Eu só preciso da senha com o rmcomando para sempre ser aplicada. Outros comandos que estou usando são geralmente nanoou cpquais são (até certo ponto) reversíveis.

Pavel Janicek
fonte
2
O @solsTiCe /*é expandido antes de ser passado para o comando rm. Portanto, o comando não vê um único argumento, mas uma lista de argumentos ( /bin /boot /cdrom /dev /etc /home...) #
1111 de Dan
3
Uma lição importante a ser tirada disso é que você não deve executar as coisas com o sudo, a menos que realmente precise. Eu sei que isso não responde ao que você perguntou aqui, mas a questão principal é como (espero) impedir que você exclua seu servidor novamente, e evitar o sudo deve ser sua primeira linha de defesa contra isso.
David Z
2
Possível duplicata de Como posso configurar uma senha para o comando 'rm'?
WinEunuuchs2Unix
2
@ WinEunuuchs2Unix Essa não é uma pergunta duplicada, o op aqui não deseja que o rmcomando tenha uma senha. Eles só querem sudosolicitar um a cada vez que o comando rm é usado. A solução para a pergunta que você vinculou se tornaria um pouco irritante quando seu primeiro comando for sudo rm. Como solicitará duas senhas, uma por sudouma rm.
Dan

Respostas:

17

Você pode definir o timestamp_timeoutque 0para os comandos específicos em /etc/sudoers. Crie um arquivo visudo -f /etc/sudoers.d/pduckcom o seguinte conteúdo:

Cmnd_Alias DANGEROUS = /bin/rm

Defaults!DANGEROUS timestamp_timeout=0

pduck ALL = (ALL:ALL) DANGEROUS

Agora, pducksempre é solicitada uma senha ao usuário durante a execução sudo rm(não importa quais parâmetros adicionais sejam fornecidos), mesmo que o usuário seja membro do sudogrupo e se sudolembre da senha para outros comandos.

A desvantagem é que você não pode adicionar parâmetros facilmente à /bin/rmlinha do arquivo para restringir ainda mais isso. Bem ... você pode, como:

Cmnd_Alias DANGEROUS = /bin/rm -f

mas você será solicitado exatamente sudo rm -fe não (novamente) sudo rm -rf, por exemplo.

PerlDuck
fonte
9

Um método seria usar o safe-rm . Isso abordará APENAS o uso de "rm" e impedirá que versões específicas de "rm" sejam executadas. Isso inclui remover o sistema raiz, mas também pode ser usado para impedir a remoção de diretórios relacionados ao sistema, como "/ usr /" ou "/ var /". No link:

Revendo a exclusão acidental de arquivos importantes

O Safe-rm é uma ferramenta de segurança destinada a impedir a exclusão acidental de arquivos importantes, substituindo-os /bin/rmpor um wrapper, 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:

$ rm -rf /usr   
Skipping /usr

(Os caminhos protegidos podem ser definidos nos níveis do site e do usuário.)

Recuperar arquivos importantes que você excluiu por engano pode ser bastante difícil. Proteja-se hoje, instalando o safe-rm e reduza a probabilidade de que você precise entrar em contato com um serviço de recuperação de dados!

insira a descrição da imagem aqui

Rinzwind
fonte
Votado para a safecow
Michael Fulton
3

sudofornece uma opção -k, --reset-timestamp, consulte man sudo:

Quando usada em conjunto com um comando ou uma opção que pode exigir uma senha, essa opção fará com que o sudo ignore as credenciais em cache do usuário. Como resultado, o sudo solicitará uma senha (se for exigida pela política de segurança) e não atualizará as credenciais em cache do usuário.

Você pode escrever um invólucro simples para sudotestar rm -rf /*e executar

sudo -k rm -rf /*

em vez disso, por exemplo:

sudo ()                                                                                                                                                 
{ 
    [[ "$*" == "rm -rf /*" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

Exemplo de uso

Testando echo aaqui.

$ sudo echo
[sudo] password for dessert: 

$ sudo echo

$ sudo echo a
[sudo] password for dessert: 
a
$ sudo echo a
[sudo] password for dessert: 
a

Se você desejar ser solicitado sempre que executar rmem geral, poderá adaptar a função acima da seguinte maneira:

sudo () 
{ 
    [[ "$1" == "rm" ]] && opt="-k";
    /usr/bin/sudo $opt "$@"
}

Se você deseja combinar chamadas de comando gerais e linhas de comando específicas, recomendo usar case, por exemplo:

sudo () 
{ 
    case "$*" in 
        rm*)            opt="-k" ;;
        "mv /home"*)    opt="-k" ;;
        "ln -s /usr/bin/fish /bin/sh") opt="-k" && echo "Don't you dare!" ;;
        *)              opt="" ;;
    esac;
    /usr/bin/sudo $opt "$@"
}

Note-se que essas abordagens não vai funcionar se você executar sudocom opções - possíveis soluções são [[ "$*" =~ " rm " ]]para verificar se a string “rm” rodeado por espaços ou *" rm "*)com casea pegar qualquer linha de comando contendo “rm”.

sobremesa
fonte
[[ "$1" == "rm" ]] && opt="-k";e quanto /bin/rm?
Rinzwind
@Rinzwind Acho que a função é facilmente adaptável a necessidades específicas, especialmente a caseabordagem.
Dessert
1

Esta resposta não aborda a sudoparte da sua pergunta, mas, por outro lado, trata de uma maneira de atenuar o perigo de rminvocações acidentais para qualquer usuário.

Você pode alternar rmpara o rm -Iqual

  • pede confirmação assim que excluir um diretório ou mais de 3 arquivos
  • contanto que você deixe de fora o-f que substitui as -Iopções anteriores .

--one-file-systemé outra possível salvaguarda contra exclusão não intencional que eu uso no meu rmalias.

Configuração

Para criar um alias, use o comando:

alias rm='rm -I --one-file-system'

Você pode colocá-lo no seu ~/.bashrcou até mesmo /etc/bash.bashrc.

Uso

$ sudo rm -r /etc/apt/sources.list.d /*
rm: remove all arguments?

Para confirmar o tipo yesou sua tradução no seu código de idioma ou na primeira letra de uma das palavras e pressione Enter. Qualquer outra entrada, incluindo nenhuma, interrompe a operação.

David Foerster
fonte