← Voltar para o Blog

Usuários, grupos e sudo: quem pode o quê no seu servidor

Todo servidor com mais de seis meses tem uma conta que ninguém sabe explicar. Este é o modelo mental de usuários e grupos no Linux, e como dar acesso sem entregar a máquina.

Equipe EasyOps Cloud · · 7 min de leitura

Todo servidor com mais de seis meses tem pelo menos uma conta que ninguém sabe explicar. Foi criada para um estagiário, para uma integração que não existe mais ou para "resolver rapidinho" — e continua lá, com shell válido e chave autorizada.

Isso acontece porque conta é fácil de criar e difícil de lembrar. E o custo não é teórico: cada conta esquecida é uma porta que ninguém está vigiando, e cada acesso concedido de forma ampla é um incidente que vai ser mais difícil de investigar.

O modelo do Linux para isso é simples e não mudou em décadas. Vale entendê-lo uma vez.

Conta de pessoa e conta de serviço

A primeira distinção que organiza o resto. São duas categorias com propósitos opostos:

Conta de pessoa existe para alguém entrar e trabalhar. Tem shell, tem diretório pessoal, tem chave SSH. Deve ser nominal — mariana, não dev nem acesso.

Conta de serviço existe para um processo rodar sem privilégio excessivo. Não deve ter shell nem senha, e ninguém deve entrar com ela.

# Conta de pessoa
sudo adduser mariana

# Conta de serviço: sem login, sem home, sem senha
sudo useradd --system --no-create-home \
  --shell /usr/sbin/nologin meuapp

O --system cria com UID abaixo de 1000, faixa reservada por convenção para serviços. Isso ajuda ferramentas e pessoas a distinguirem os dois grupos de imediato.

Rodar aplicação como root é o atalho que cobra caro depois: uma falha na aplicação vira comprometimento total da máquina em vez de comprometimento de um serviço. Cada serviço com o próprio usuário é a diferença entre um incidente contido e um incidente completo.

Grupos são a unidade de gestão

O erro mais comum em servidor pequeno é conceder permissão direto ao usuário. Isso funciona com duas pessoas e vira caos com cinco, porque não há nenhum lugar onde esteja escrito quem pode o quê.

Grupos resolvem isso: a permissão vai para o grupo, e a gestão de pessoas vira entrar e sair dele.

sudo groupadd deploy
sudo usermod -aG deploy mariana

# Conferir
groups mariana
id mariana

O -a de usermod -aG é obrigatório e é a pegadinha clássica. Sem ele, o comando substitui todos os grupos secundários do usuário em vez de acrescentar — e a pessoa perde acessos que tinha, sem nenhum aviso.

Alguns grupos já vêm com significado no sistema, e vale saber o que cada um concede:

  • sudo (Debian/Ubuntu) ou wheel (RHEL e derivados) — permite escalar a root. É a decisão mais importante da lista.
  • docker — acesso ao socket do Docker. Isso é equivalente a root, porque quem pode criar container pode montar o disco inteiro. Trate como se fosse sudo.
  • adm — leitura dos logs em /var/log. Útil para quem precisa diagnosticar sem poder alterar nada.
  • www-data — usuário do servidor web em Debian e Ubuntu. Colocar pessoas nesse grupo é quase sempre sinal de permissão mal resolvida em arquivo.

Uma mudança de grupo só vale na próxima sessão. Se a pessoa continuar sem o acesso, peça para sair e entrar de novo antes de investigar qualquer outra coisa — é a explicação na maioria esmagadora dos casos.

Sudo sem entregar a máquina

Colocar alguém no grupo sudo dá acesso irrestrito a root. Para boa parte dos casos, isso é mais do que a pessoa precisa.

O sudoers permite recortar. E ele nunca deve ser editado direto: um erro de sintaxe pode tirar o sudo de todo mundo, inclusive de você.

sudo visudo -f /etc/sudoers.d/deploy

O visudo valida antes de salvar. Usar um arquivo separado em sudoers.d/ mantém a configuração organizada e sobrevive a atualização de pacote.

Um recorte útil, permitindo apenas o necessário para implantar:

# /etc/sudoers.d/deploy
%deploy ALL=(root) NOPASSWD: /bin/systemctl restart meuapp, \
                             /bin/systemctl status meuapp, \
                             /usr/bin/journalctl -u meuapp *

O % indica grupo. O NOPASSWD é apropriado aqui porque a lista é restrita e precisa rodar em automação.

Há uma armadilha importante nessa técnica. Autorizar um comando que aceita argumento arbitrário equivale a autorizar tudo:

# NUNCA faça isto — vim executa shell, e o shell é root
%deploy ALL=(root) NOPASSWD: /usr/bin/vim

# Nem isto — o find executa qualquer comando
%deploy ALL=(root) NOPASSWD: /usr/bin/find

Editor de texto, find, awk, tar com opção de compressão e qualquer coisa que chame outro programa são caminhos diretos para root. A regra: autorize verbos específicos, não ferramentas genéricas.

Teste sempre o resultado sem sair da sessão:

sudo -l -U mariana

Auditar o que já existe

Servidor herdado exige inventário. Estes comandos respondem às perguntas certas:

# Pessoas com shell utilizável
awk -F: '$3 >= 1000 && $7 !~ /nologin|false/ {print $1, $3, $7}' /etc/passwd

# Quem pode virar root
getent group sudo wheel docker 2>/dev/null

# Contas sem senha definida — não deveria haver nenhuma
sudo awk -F: '$2 == "" {print $1}' /etc/shadow

# Regras de sudo espalhadas
sudo ls -la /etc/sudoers.d/

Cruze com quem realmente usa a máquina:

last -F | head -30
sudo journalctl _COMM=sudo --since '30 days ago' | tail -40

Conta que aparece em /etc/passwd e não aparece em last nos últimos meses é candidata natural a desativação.

Desativar em vez de apagar

Ao remover acesso, prefira bloquear primeiro. Apagar a conta pode deixar arquivos órfãos, quebrar tarefas agendadas e dificultar auditoria posterior:

# Bloqueia login, preserva tudo
sudo usermod -L -e 1 -s /usr/sbin/nologin mariana

# Encerra sessões abertas
sudo pkill -u mariana

# Remove das listas de acesso
sudo gpasswd -d mariana sudo
sudo gpasswd -d mariana docker

Lembre da chave SSH, que é independente da senha:

sudo mv ~mariana/.ssh/authorized_keys ~mariana/.ssh/authorized_keys.revogado

Só apague a conta depois de um período de carência, quando estiver claro que nada dependia dela:

sudo deluser --remove-home --backup --backup-to /var/backups mariana

O --backup guarda o diretório pessoal antes de remover — barato, e evita a descoberta tardia de que havia um script importante ali.

Dono de arquivo em deploy

O ponto onde usuários e permissões se encontram na prática. O padrão que funciona: o código pertence ao usuário de deploy, e o serviço apenas lê.

sudo chown -R deploy:meuapp /var/www/meuapp
sudo chmod -R 750 /var/www/meuapp

# Só o que a aplicação precisa escrever
sudo chown -R meuapp:meuapp /var/www/meuapp/storage

Assim, uma falha na aplicação não permite alterar o próprio código — que é exatamente como uma invasão vira persistente. O artigo sobre permissões e o chmod 777 detalha os números e o que muda em diretório.

Para arquivo com credencial, restrinja ao dono e ao serviço:

sudo chown root:meuapp /etc/meuapp/env
sudo chmod 640 /etc/meuapp/env

O usuário dentro do container

Um ponto cego frequente: todo o cuidado com usuários na máquina hospedeira se perde se o processo dentro do container roda como root — que é o padrão quando ninguém declara o contrário.

O risco não é hipotético. Um container privilegiado, ou com volume montado do host, transforma root interno em acesso ao sistema de arquivos real.

RUN useradd --system --no-create-home --shell /usr/sbin/nologin app
USER app

Quando a imagem é de terceiro e você não controla o Dockerfile, dá para impor na execução:

docker run --user 1000:1000 --read-only \
  --cap-drop=ALL --security-opt no-new-privileges minha-imagem

O --cap-drop=ALL remove as capacidades do kernel que o container herda por padrão, e o no-new-privileges impede escalada por binário com bit setuid. Poucos containers de aplicação precisam de qualquer uma dessas coisas.

Um detalhe que causa confusão ao adotar isso: o UID de dentro e o de fora são o mesmo número, mas os nomes são independentes. Um arquivo criado pelo container com UID 1000 aparece no host como pertencente a quem tiver o UID 1000 lá — que pode ser outra pessoa. Ao montar volume, alinhe os números explicitamente em vez de confiar nos nomes.

Expiração e o que envelhece sozinho

Credencial não avisa quando fica velha. Vale colocar prazo no que dá:

# Data de expiração da conta de um prestador
sudo usermod -e 2026-12-31 consultor

# Ver o que está definido
sudo chage -l consultor

Conta com data de expiração é a única que se desativa sem depender de alguém lembrar — e é a resposta certa para acesso temporário de terceiro, que é justamente o tipo de conta que mais sobrevive além do necessário.

O arranjo que se sustenta

  • Uma conta nominal por pessoa. Sem conta compartilhada, porque log com conta compartilhada não responde nada.
  • Uma conta de serviço por aplicação, sem shell.
  • Permissão via grupo, nunca direto no usuário.
  • `sudo` recortado por lista de comandos quando o acesso total não for necessário.
  • Revisão trimestral cruzando /etc/passwd com quem de fato usa.

Esse conjunto leva uma tarde para montar e economiza a investigação que ninguém quer fazer: descobrir, seis meses depois, quem executou o comando que apagou a tabela — e não conseguir responder porque todo mundo entrava com a mesma conta. O mesmo raciocínio vale para o acesso remoto em si, e o hardening de SSH cobre a camada de autenticação que fica antes desta.

Suba um servidor em minutos

Preço em real, suporte em português e dados no Brasil.

Criar conta