Scripts com privilégios
LidoEsta aula aborda a execução de scripts com privilégios elevados no Linux, explicando quando usar sudo, o princípio do menor privilégio, os riscos envolvidos e as boas práticas para evitar vulnerabilidades. O aluno aprenderá a analisar scripts com sudo, reduzir superfícies de ataque e proteger o sistema.
Executar scripts com privilégios elevados é uma necessidade comum em administração de sistemas, mas também é uma das maiores fontes de riscos de segurança. Quando um script roda como root, qualquer falha ou ação maliciosa pode comprometer todo o sistema. Nesta aula, vamos explorar quando e como usar sudo de forma responsável, entender o princípio do menor privilégio e adotar boas práticas para minimizar danos.
Vamos começar discutindo situações em que o uso de sudo é realmente necessário, depois analisaremos os riscos associados e, por fim, veremos como escrever scripts seguros que exigem privilégios.
Quando usar sudo
O comando sudo permite que um usuário execute comandos com os privilégios de outro usuário, geralmente o root. Ele é essencial para tarefas administrativas, como instalar pacotes, gerenciar usuários, alterar arquivos de sistema ou configurar serviços. No entanto, seu uso deve ser criterioso: nem todo script precisa rodar como root, e forçar isso aumenta desnecessariamente a superfície de ataque.
Exemplos de situações em que sudo é necessário:
- Instalar ou remover pacotes (
apt install,dnf install). - Editar arquivos em diretórios protegidos (
/etc). - Gerenciar serviços do sistema (
systemctl start). - Criar ou modificar usuários (
useradd).
Um script deve solicitar sudo apenas se realmente precisar de privilégios elevados. Você pode verificar se o script está sendo executado como root usando id -u (retorna 0 para root) e, se necessário, usar sudo dentro do próprio script para executar comandos específicos, em vez de rodar todo o script com sudo.
#!/bin/bash
# Exemplo: script que usa sudo apenas para um comando
if [ "$(id -u)" -ne 0 ]; then
echo "Este script precisa de privilégios de root."
exit 1
fi
# Comandos que exigem root
apt update
apt install -y nginx
Princípio do menor privilégio
O princípio do menor privilégio (PoLP, do inglês Principle of Least Privilege) estabelece que cada processo ou usuário deve ter apenas os privilégios necessários para realizar sua função, e nada mais. Aplicado a scripts, isso significa que não devemos rodar um script inteiro como root se apenas uma parte dele precisa de privilégios elevados.
Na prática, isso envolve:
- Identificar exatamente quais comandos exigem privilégios e isolá-los.
- Usar
sudopara executar apenas esses comandos, em vez de todo o script. - Se possível, usar ferramentas que já implementam o menor privilégio, como
systemdcom usuários dedicados.
Exemplo: em vez de rodar o script com sudo ./script.sh, podemos usar sudo apenas para o comando que precisa de root:
#!/bin/bash
# Script que roda sem privilégios, mas usa sudo para uma tarefa específica
sudo systemctl restart nginx
# O restante do script roda como usuário normal
echo "Nginx reiniciado."
Isso reduz o risco: se o script for comprometido, o atacante não terá acesso total ao sistema, apenas ao comando que roda com sudo.
Riscos
Executar scripts com privilégios elevados traz vários riscos de segurança:
- Comprometimento total do sistema: se o script for explorado (ex.: injeção de comandos), o atacante terá acesso root.
- Erros de permissão: um script mal escrito pode alterar arquivos ou configurações indevidamente, causando danos.
- Escalada de privilégios: se o script for executado com
sudosem validação, um usuário pode explorar vulnerabilidades para obter acesso root. - Falta de rastreabilidade: scripts que usam
sudopodem gerar logs incompletos, dificultando auditorias.
Um exemplo clássico de risco é o uso de variáveis não sanitizadas em comandos com sudo. Se um script aceita entrada do usuário e a concatena em um comando, um atacante pode injetar comandos arbitrários:
#!/bin/bash
# Script inseguro: usa sudo com entrada não sanitizada
arquivo="$1"
sudo cat "$arquivo" # Se $arquivo for "; rm -rf /; echo", o sistema é comprometido
Outro risco é a execução de scripts a partir de diretórios com permissões inadequadas, permitindo que um atacante modifique o script antes de ser executado com privilégios.
Boas práticas
Para minimizar riscos ao usar privilégios em scripts, siga estas boas práticas:
- Aplique o menor privilégio: use
sudoapenas para os comandos que realmente precisam de root. - Valide todas as entradas: nunca confie em variáveis de ambiente, argumentos ou dados externos sem sanitização.
- Use caminhos absolutos: evite depender do PATH, que pode ser manipulado.
- Defina permissões restritivas no script:
chmod 700 script.shpara que apenas o proprietário possa executá-lo. - Evite usar
sudodentro de scripts com variáveis não confiáveis: se necessário, usesudo -Ecom cuidado ou defina variáveis explicitamente. - Faça logs: registre as ações do script para auditoria.
- Teste em ambiente controlado: antes de executar em produção, teste em uma máquina virtual ou container.
Exemplo de script seguro com validação e uso mínimo de sudo:
#!/bin/bash
set -euo pipefail
# Verifica se o script está sendo executado como root
if [ "$(id -u)" -ne 0 ]; then
echo "Este script deve ser executado como root." >&2
exit 1
fi
# Valida o argumento (nome de usuário)
if [ $# -ne 1 ]; then
echo "Uso: $0 " >&2
exit 1
fi
usuario="$1"
# Usa apenas comandos necessários com privilégios
useradd "$usuario"
echo "Usuário $usuario criado."
Além disso, considere usar sudo com opções como sudo -n (não interativo) para evitar prompts, mas tenha cuidado com a segurança.
Observações finais
Privilégios são uma ferramenta poderosa, mas perigosa. Sempre questione se um script realmente precisa de root e, se precisar, escreva-o com o máximo de cuidado. Lembre-se: a segurança não é apenas sobre o código, mas também sobre o ambiente e as permissões. Revise regularmente scripts com privilégios e mantenha-os atualizados.
Referências
- Manual do sudo (man7.org)
- Como executar sudo dentro de scripts (cyberciti.biz)
- Manual do Bash (GNU)
- Sudo na Arch Wiki
- Guia de sudo da Red Hat
- Injeção de comandos (OWASP)
Exercícios
- Exercício 1: Escreva um script que verifique se está sendo executado como root e, se não estiver, use
sudopara se elevar. O script deve, em seguida, criar um diretório em/optchamadomeuappe definir permissões 755. - Exercício 2: Explique por que é arriscado usar
sudodentro de um script sem validação de entrada. Dê um exemplo de ataque de injeção de comandos. - Exercício 3: Crie um script que aplique o princípio do menor privilégio, executando apenas uma parte com
sudo. O script deve ler um arquivo de configuração em/etc(que requer root) e, em seguida, processar o conteúdo como usuário normal. - Exercício 4: Liste três boas práticas para escrever scripts com privilégios e explique cada uma.
- Validar entradas: sempre verificar e sanitizar variáveis para evitar injeção.
- Usar caminhos absolutos: evita ataques de PATH hijacking.
- Definir permissões restritivas no script: impede que outros usuários modifiquem o script.
- Exercício 5: Escreva um script que verifique se o usuário tem permissão para executar
sudo(usandosudo -n true) e, se não tiver, exiba uma mensagem de erro e saia com código 1.
#!/bin/bash
if [ "$(id -u)" -ne 0 ]; then
echo "Re-executando com sudo..."
exec sudo "$0" "$@"
fi
mkdir -p /opt/meuapp
chmod 755 /opt/meuapp
echo "Diretório criado."
sudo com uma variável não sanitizada, um atacante pode inserir comandos que serão executados como root. Por exemplo, se o script faz sudo cat "$arquivo" e o usuário passa arquivo="; rm -rf /; echo", o comando executado será sudo cat ; rm -rf /; echo, o que apagaria o sistema.#!/bin/bash
# Lê o arquivo com sudo e salva em variável
conteudo=$(sudo cat /etc/meuapp.conf)
# Processa como usuário normal
echo "Conteúdo processado: $conteudo"
#!/bin/bash
if sudo -n true 2>/dev/null; then
echo "Você tem privilégios sudo."
else
echo "Erro: você não tem permissão para usar sudo." >&2
exit 1
fi