Sudo 1.8.12 - Parte II - Como sudo funciona

Essa é a segunda parte do artigo sobre sudo 1.8.12 no Slackware Current.

[ Hits: 3.694 ]

Por: Perfil removido em 02/09/2015


Conceitos básicos



Execução de comandos

Quando sudo executa um comando, a política de segurança define o ambiente de execução para esse comando. Tipicamente, os IDs real e efetivo de usuário e de grupo são combinados para coincidir com as especificações do usuário-alvo na base de dados de senhas. O vetor de grupos é inicializado com base no banco de dados de grupo (exceto se a opção "-P" for especificada). Os seguintes parâmetros podem ser especificados pela política de segurança ou por opções:
  • O ID real e efetivo de usuário.
  • O ID real e efetivo de grupo.
  • Os IDs suplementares de grupo.
  • Uma lista com variáveis de ambiente.
  • O diretório de trabalho atual (pwd).
  • A máscara de criação de arquivos para o usuário (umask).
  • Regras, funções e tipos definidos em SELinux.
  • As prioridades de agendamento de processo (a.k.a nice).
  • Se o sistema for Solaris: os privilégios e projetos.
  • Se o sistema for um BSD: a classe do usuário (conforme /etc/login.conf).

O modelo de processos

Quando sudo executa um comando, ele chama por fork (2), configura o ambiente de execução, como descrito anteriormente, e chama execve em um processo filho. O processo principal de sudo aguarda até que o comando seja completado, então passa o estado de saída para a política de segurança fechar a função e encerrar (exit). Caso um plug-in de I/O seja configurado ou se a política de segurança requisitar de modo explícito por um novo pseudo-terminal (pty), ele é criado e uma segunda instância de sudo é utilizada para encaminhar o controle do job entre a pty/tty do usuário e o novo terminal.

Esse processo extra torna possível, por exemplo, suspender e reiniciar o processamento de um comando. Sem esse mecanismo, os comandos deveriam ser "em termos POSIX" considerados um grupo de processos órfãos e, deste modo, não poderiam receber sinais de controle. Em um caso especial, se o plug-in de segurança não definir uma função de fechamento e nenhum pty for requerido, sudo executará o comando diretamente em vez de chamar fork (2). A política sudoers somente definirá uma função de fechamento quando o log de I/O estiver ativado, ou quando uma pty for requerida, ou ainda quando as opções pam_session ou pam_setcred estiverem ativadas. Esse é o padrão em sistemas que usam PAM.

Manipulando sinais

Quando um comando é executado como um processo filho do processo sudo, é sudo quem repassa os sinais recebidos para o comando. A menos que o comando seja executado em um novo pty, os sinais SIGHUP (1), SIGINT(2) e SIGQUIT (3) não são repassados. Por outro lado, o comando deve receber SIGINT duas vezes para cada vez que o usuário utilizar Ctrl-C. Sinais como SIGSTOP e SIGKILL não podem ser capturados e por isso não podem ser repassados ao comando. Uma regra é que SIGTSTP (Ctrl-Z ou 18, 20, 24) deve ser utilizado no lugar de SIGSTOP (17, 19, 23) quando precisar suspender um processo iniciado via sudo.

Como um caso especial, sudo não repassa sinais para comandos em execução. Isso previne o comando de acidentalmente matar a si mesmo. Em alguns sistemas, o reboot (8) envia SIGTERM para todos processos que não são de sistema antes de reiniciar realmente o sistema. Isso previne que sudo repasse um SIGTERM de volta para reboot (8) antes de encerrar realmente. Isso evita que o processo fique em estado zumbi. Observe que este mecanismo somente se aplica ao comando executado diretamente por sudo e não protege outros processos que possam ter sido criados pelo comando em si. Assim, executar um script que chame reboot (8) ou shutdown (8) que usam a função exec() ou funções de system() pode fazer o sistema terminar em um estado indefinido. Se nenhum plug-in de I/O for carregado e a política não definir uma função close(), configure um valor de timeout ou exija que o comando execute em um novo pty. Neste caso, sudo pode executar diretamente em vez de usar um processo filho.

Plug-ins

As diretivas plug-in permitem especificar um plug-in via sudo.conf. O plug-in pode ser carregado como um objeto compartilhado dinâmico (em sistemas que suportam esse tipo de objeto - share object ou LIB). O plug-in também pode ser compilado internamente no binário de sudo. Se não houver um sudo.conf presente, ou ele não tiver uma referência ao plug-in, sudo utilizará a política tradicional baseada em sudoers e um log de I/O padrão. Pesquise no manual sudo.conf (5) para mais detalhes sobre como configurar o arquivo /etc/sudo.conf e o manual de plug-in sudo_plugin (8) para mais informações sobre a arquitetura de plug-ins.

Valor de saída

Após a execução de um comando, o estado de saída de sudo será o estado de saída do programa executado por ele. Por outro lado, sudo saí como estado 1 se um problema de configuração ou de permissão impedir sudo de executar o programa chamado. Neste caso, uma mensagem de erro é enviada para a saída padrão de erro. Se sudo não puder fazer stat (2) em uma ou mais entradas presentes no PATH do usuário, uma mensagem de erro é enviada para stderr. O mais comum para a falha na execução de stat (2) é uma chamada para um comando sem permissão, ou em um sistema de arquivos que não pode ser alcançado pelos valores definidos em PATH por não estar montado.

Notas de segurança

sudo se esforça para ser seguro, principalmente quando executa comandos externos. Para prevenir o sudo spoofing, ele checa o diretório corrente (".") por último. Desta forma, todos os caminhos no PATH são checados primeiro.

Observe, entretanto, que o ambiente atual de PATH não é modificado e é passado sem alterações para o programa que sudo executa. Por favor, observe que sudo irá normalmente logar o comando que realmente foi executado. Se um usuário executa um comando como "sudo su" ou "sudo sh", comandos subsequentes executam o comando em questão sem levar em conta TODA a política de segurança de sudo. Isso é pegar um atalho perigoso. O mesmo é verdade para comandos que tem entrada e/ou saídas logadas, mas eles não produzem qualquer log quando executados normalmente. Comandos que oferecem uma porta de saída (backdoor) para executar um shell (por exemplo o editor Vim) são um exemplo destes casos.

É preciso verificar se ao dar privilégios de sudo você na verdade está dando um shell administrativo para seu usuário. Para mais informações consulte a seção em sudoers (5) "prevenindo escapadas para o shell". Além disto, para evitar que informações potencialmente sensíveis possam vazar quando algo dá errado, sudo desativa despejos de memória (core dumps) ao ser executado. Para depurar quebras de programas com sudo é preciso ativar explicitamente o despejo de memória com a opção set disable_coredump false em sudo.conf.

Os principais problemas de segurança com sudo são causados pelo próprio administrador que não configura corretamente e principalmente não testa cada caso antes de liberar sua política de segurança para uso em produção.

Ambiente

Atualmente, a política de segurança tem total controle sobre o conteúdo do ambiente de execução de comandos. Sudo faz uso das seguintes variáveis de ambiente:
  • EDITOR - define o editor padrão para sudoedit. Pode ser definido também em SUDO_EDITOR ou VISUAL.
  • MAIL - no modo "-i" ou quando env_reset é ativado em sudoers, define a caixa de mensagens para o usuário alvo.
  • HOME - define o diretório casa do usuário alvo, se "-i" ou "-H" for especificado ou env_reset ou always_set_home for configurado em sudoers, ou se a opção "-s" for definida e set_home configurado em sudoers.
  • PATH - pode ser sobrescrito pela política de segurança.
  • SHELL - usado para definir o shell onde o comando será executado. Afetado pela opção "-s".
  • SUDO_ASKPASS - define o path para programa auxiliar (normalmente gráfico) capaz de receber a senha quando não é possível usar um terminal. Afetado pela opção "-A".
  • SUDO_COMMAND - configura o comando executado por sudo.
  • SUDO_EDITOR - define o editor padrão para sudoedit ou opção "-e".
  • SUDO_GID - define o ID de grupo padrão para quando sudo é invocado.
  • SUDO_PROMPT - define um prompt padrão para a senha.
  • SUDO_PS1 - se configurado, PS1 será configurado para esse valor para o comando em execução por sudo.
  • SUDO_UID - define o ID de usuário para quando sudo é invocado.
  • SUDO_USER - define o nome de login para o usuário que invocou sudo.
  • USER - define o usuário alvo. Normalmente o alvo é root, a menos que a opção "-u" seja utilizada.
  • VISUAL - define o editor para sudoedit, quando SUDO_EDITOR não é configurado.

Dicas de segurança complementares

Não há um modo fácil de prevenir que um usuário ganhe um shell administrativo se esse usuário pode executar comandos arbitrariamente através de sudo. Existem vários programas que permitem que esse usuário escape para o shell a partir dele, Vim é um exemplo. Ao escapar para o shell através de um destes programas o usuário pode ganhar um shell administrativo de presente. Isso permite que ele escape das checagens de sudo. Todavia, na maioria dos sistemas é possível prever escapadas através de plug-ins com a funcionalidade noexec.

Executar scripts administrativos via sudo pode expor os mesmos bugs do kernel que fazem scripts com setuid inseguros em tempos passados.

Se você não confia ou não pode responsabilizar seu usuário sudo de modo severo simplesmente NÃO DÊ a permissão. Esse é o melhor modo de evitar problemas. Forme um staff em torno de sua administração, treine e delegue. Não entregue tarefas que podem comprometer seu sistema de modo irremediável.

Referências:
   

Páginas do artigo
   1. Conceitos básicos
Outros artigos deste autor

Instalando o Slackware sem sofrimento (parte 2)

Que tal conhecer mais o Linux pondo a mão na massa? Conheça o Woo Hoo, projeto para uma nova distro

Apache 2.2 - Introdução ao módulo mod_rewrite

Introdução ao Conceito de Hardening

Acessando a Internet 3G da Claro no Ubuntu e no Debian de maneira simples

Leitura recomendada

ARP Poisoning: compreenda os princípios e defenda-se

PFSense com Snort

Nmap - Escaneando sua Rede e Mantendo-a Segura

Transportando dados com segurança - encripte seu pendrive em 5 passos

Hardering com Red Hat 5

  
Comentários
[1] Comentário enviado por fabio em 02/09/2015 - 12:49h

Interessante a leitura sobre essa parte de funcionamento do sudo, parabéns pelo trabalho!

[2] Comentário enviado por removido em 03/09/2015 - 00:15h

Essa série sobre o sudo está ótima. Principalmente certos pontos que são obscuros para mim por barreiras linguísticas.
Parabéns.
--
http://s.glbimg.com/po/tt/f/original/2011/10/20/a97264_w8.jpg

Encryption works. Properly implemented strong crypto systems are one of the few things that you can rely on. Unfortunately, endpoint security is so terrifically weak that NSA can frequently find ways around it. — Edward Snowden


Contribuir com comentário