Meu caso de uso é que tenho um script que remove meu usuário do grupo sudo e então me adiciona novamente em um determinado momento no futuro usando o at
comando.
O problema é que tenho que reiniciar a máquina toda vez para que as alterações tenham efeito: na primeira vez para deixar de ser o usuário sudo e na segunda vez (depois que o script me adicionou novamente ao grupo sudo) para poder ser ele novamente.
Estranhamente meu DE (Cinnamon) e o explorador de arquivos (Nemo) pegam as mudanças imediatamente, o que significa que se eu tentar ir para um fodler e "abrir como root", não posso fazer isso se eu tiver executado o script e for removido do grupo sudo. Mas se eu for no terminal e, por exemplo, eu fizer sudo apt update
isso, funcionará, a menos que eu reinicie.
O objetivo é fazer com que a remoção/adição do meu usuário ao grupo sudo reflita efetivamente sem precisar reinicializar minha máquina. (Eu digo reinicializar e não sair porque, estranhamente, sair aparentemente não vai funcionar).
Pesquisei online e uma solução foi executar:
sudo service sudo restart
Mas o problema é que recebo o erro: Failed to restart sudo.service: Unit sudo.service is masked.
Tentei desmascarar, sudo.service
mas nada mudou.
Info : Estou no Linux Mint 22 com Cinnamon 6.2.9. Kernel Linux: 6.8.0-48-generic
Editar:
Objetivo de todo o script
Estou fazendo um fork de um projeto chamado delayed-admin . O que isso faz é basicamente remover o usuário principal do grupo sudo para que você não possa executar nada que exija sudo
acesso. Existem então apenas duas maneiras de executar um comando que exija sudo
:
- Aguardando as
at
funções agendadas que colocam o usuário de volta no grupo sudo (porque quando você inicia o comando com osudo ./abdicate.sh "now + 3 hours"
comando sudo, você fica bloqueado por 3 horas). - Usando o comando
sudo delayed example-command
dessa forma, o comandoexample-command
será executado mesmo se você não estiver no grupo sudo, mas será executado com um certo atraso escolhido pelo usuário através de um arquivo de configuração.
O que eu quero alcançar: ser capaz de perder/ganhar privilégios sudo quando o script remover/adicionar meu usuário ao grupo sudo, sem reiniciar minha máquina.
Por que você precisa fazer login novamente
Provavelmente
/etc/sudoers
contém uma linha como esta:É essa linha que permite que usuários do
sudo
grupo executem comandos comsudo
. Quando você executasudo
e ele verifica se você está nosudo
grupo, ele não consulta o banco de dados do usuário/grupo, ele verifica se seu próprio processo carrega essa informação . Uma vez que você esteja em um shell (ou qualquer outro) que esteja nosudo
grupo, todos os seus filhos (incluindosudo
você executa) estarão no grupo. Há maneiras de iniciar um novo processo com informações alteradas ou atualizadas sobre grupos, mas isso tem que ser uma ação deliberada (como sair e entrar novamente, ou reinicializar).Isso é por design. Ao alterar o banco de dados de usuários/grupos, você não pode fazer com que processos já em execução alterem suas atribuições a grupos (e, assim, percam ou ganhem
sudo
acesso) imediatamente.Abaixo há uma tentativa de resolver seu problema subjacente.
Outra abordagem
Esta é uma tentativa de construir uma mecânica que permitirá que usuários escolhidos percam temporariamente seu acesso sudo, que de outra forma seria irrestrito. Experimental, mal testado. Use por sua conta e risco.
Crie
abdicate-until
com o seguinte conteúdo:E torná-lo executável (
chmod +x …
).Notas
/full/path/to/delayed
, edite-o adequadamente.date -d
, ele foi testado com GNUdate
. Certifique-se de quedate
você pode executar comsudo
understands-d now
e tal (executesudo date -d now
e veja se dá certo).Presumo que o usuário para o qual você quer essa funcionalidade esteja atualmente no
sudo
grupo e possa executar comandos comsudo
. Conforme o usuário executa:para criar a estrutura de diretório relevante e um arquivo que mais tarde dirá que
sudo
você deseja "abdicar" até agora (então, efetivamente, não de forma alguma, ainda).Invoque
sudo visudo
e adicione esta linha no final :Salve as alterações e saia do editor. Se
visudo
ele disser que há um problema, não deixe que ele realmente altere osudoers
arquivo. Quando solicitado a revisar o arquivo dentro de/etc/abdicate/sudoers.d
, não altere este arquivo. Prossiga para a próxima etapa somente sevisudo
aceitar a alteração.Versões antigas de
sudo
do not recognize@includedir
, para elas use#includedir
em vez disso. (E eu acho que versões ainda mais antigas desudo
do not recognizeNOTBEFORE=
, que é absolutamente crucial em nossa mecânica; se a suasudo
for tão antiga, aborte: do not changesudoers
, remova/etc/abdicate/
eabdicate-until
como elas não vão funcionar, não prossiga com esta resposta.)Remover o usuário do
sudo
grupo . O usuário pode fazer isso sozinho invocando:Como você já sabe, essa mudança requer um novo login ou um ato semelhante. No shell atual, você ainda pode usar
sudo
por causa%sudo ALL=(ALL:ALL) ALL
dosudoers
arquivo. Eu aconselho você a não sair deste shell caso haja algo errado e nossa mecânica não funcione bem para você. A partir deste shell, você poderágpasswd --add "$USER" sudo
. Sair deste shell somente após verificar se a mecânica funciona.Em um shell separado, você precisa fazer login como o usuário novamente. Se esse shell já pertence ao usuário certo, mas
id
( nãoid "$USER"
) mostra que ele ainda está nosudo
grupo, então você pode fazer:para substituir o shell por um novo shell onde
id
deve mostrar que ele não está nosudo
grupo (verifique isso). É aqui que você testará a solução.No novo shell execute:
Você não precisa citar
+2 minutes
. Nosso script passará+2
andminutes
todate -d
como um argumento de qualquer forma:+2 minutes
. Use qualquer sintaxe que vocêdate
espera depois-d
(estritamente:date
disponível em$PATH
imposto porsudo
; pode ou não ser o mesmodate
que em seu$PATH
).Se o comando for bem-sucedido, o usuário não poderá usar
sudo
nos próximos dois minutos, excetosudo delayed …
, ou exceto se houver outras entradas emsudoers
que permitam que o usuário usesudo
. Lembre-sesudo
de usar a última correspondência . Agora seus trabalhos são:sudoers
e certifique-se de que não há linhas que permitam que o usuário execute.sudo …
Ele não poderá executar quando estiver no estado "abdicado".sudo -l
Executar como o usuário pode ser útil./full/path/to/delayed
você mesmo (ou use o que você já tem, talvez). É uma funcionalidade separada. Esta resposta não implementadelayed
, ela apenas configurasudoers
para que o usuário "abdicado" ainda possa executá-lo comsudo
.Depois de verificar se a mecânica funciona para o usuário, agora você pode fechar o shell antigo, sair, reiniciar ou o que for.
A mecânica não usa
at
nada. Recuperar o acesso asudo
funciona graças asudo
si mesmo comparando a data e a hora com o valor armazenado no arquivo dentro de/etc/abdicate/sudoers.d/
. O usuário pode verificar o valor invocandosudo -l
.A mecânica suporta múltiplos usuários. Outro usuário com
sudo
acesso pode começar a usar a mecânica executando:Para reverter (obviamente enquanto não estiver no estado de "abdicação"):
Depois disso, o usuário precisa fazer login novamente para realmente estar no
sudo
grupo. Remover o arquivo tem consequências imediatas. Remover o arquivo sem adicionar novamente o usuário aosudo
grupo primeiro provavelmente bloqueará o usuário dosudo
acesso; a senha do root (se houver), outro sudoer,pkexec
inicialização no modo de usuário único, inicialização de outro SO (por exemplo, Linux ao vivo a partir de USB) ou uso de outro computador e montagem do disco lá serão necessários para corrigir isso.Como funciona
Suponha que um usuário execute algo com
sudo
:Conforme declarado, ao consultar
sudoers
,sudo
usa a última correspondência . Com@includedir /etc/abdicate/sudoers.d
no final dosudoers
arquivo, para um usuário que tem um arquivo na/etc/abdicate/sudoers.d
última linha que tem uma chance de corresponder será a última linha deste arquivo (linhas em outros arquivos no diretório não corresponderão ao nome de usuário de qualquer maneira). A linha será como:Se o tempo não for antes de
<timestamp>
então a linha corresponderá e agirá como%sudo ALL=(ALL:ALL) ALL
atos para um usuário nosudo
grupo. Para o usuário considerado, o poder deALL=(ALL:ALL) ALL
agora é devido a esta última linha, não devido à%sudo …
linha.Mas se o tempo for antes de
<timestamp>
então a última correspondência estará em alguma outra linha ou não haverá correspondência alguma. Removemos o usuário dosudo
grupo para fazer com que a%sudo …
linha não corresponda neste caso. O usuário não obterá o poder deALL=(ALL:ALL) ALL
(a menos que uma linha não relacionada a esta resposta corresponda e forneça o poder; é por isso que você deve revisar seusudoers
).