7.8 KiB
🛡️ Guia de Segurança e Liberdade para o Usuário deploy
Na cultura de DevOps moderna, a "lenda" do usuário deploy poder trabalhar com total liberdade sem ter acesso ao usuário root é, na verdade, uma melhor prática de segurança chamada "Princípio do Menor Privilégio" (Least Privilege).
Se o usuário deploy pudesse dar sudo su e virar root a qualquer momento, qualquer vulnerabilidade na sua aplicação web (ex: um upload de arquivo malicioso ou injeção de código) daria controle total do servidor inteiro para um invasor.
Para dar ao usuário deploy toda a liberdade de desenvolvimento e publicação de aplicações com segurança absoluta, implementamos 4 pilares práticos:
🏗️ Pilar 1: Controle Total do Diretório Web (Sem sudo)
O usuário deploy não precisa de permissão de root para alterar os arquivos da aplicação. Basta torná-lo dono dos diretórios de publicação.
Prática:
Geralmente usamos a pasta /var/www/ ou criamos um diretório de aplicações na própria Home do usuário (/home/deploy/apps/).
Para dar controle total ao deploy sem precisar de sudo para editar arquivos:
# Criar a pasta do seu projeto
sudo mkdir -p /var/www/meu-app
# Definir o usuário deploy como proprietário da pasta
sudo chown -R deploy:deploy /var/www/meu-app
# Aplicar permissões recomendadas (pastas 755 e arquivos 644)
find /var/www/meu-app -type d -exec chmod 755 {} \;
find /var/www/meu-app -type f -exec chmod 644 {} \;
Resultado: O usuário deploy agora pode usar Git, SFTP, VSCode, criar arquivos, deletar e subir atualizações dentro de /var/www/meu-app com total liberdade e zero necessidade de usar sudo.
🐋 Pilar 2: Gerenciamento do Docker sem Root
Caution
Esta infraestrutura usa Docker Rootless (VPS 1). As instruções abaixo são válidas para instalações com Docker tradicional. Para Docker Rootless, veja a seção específica mais abaixo.
Se as suas aplicações rodam em Docker (ou Docker Compose) com o daemon tradicional (root), o usuário deploy não precisa usar sudo docker para gerenciar os containers.
Prática (Docker tradicional):
Adicionar o usuário deploy ao grupo docker:
sudo usermod -aG docker deploy
Resultado: O usuário deploy poderá rodar docker compose up -d, builds etc. sem sudo.
Warning
Nunca faça isso em servidores que também rodam Docker Rootless. Adicionar
deployao grupodockerdá acesso ao socket/var/run/docker.sock(root), criando um vetor de escalonamento de privilégios. Qualquerdocker compose upsemDOCKER_HOSTexplícito cria containers como root silenciosamente.
Prática correta para Docker Rootless (VPS 1):
A VPS 1 usa Docker Rootless (rootlesskit + vpnkit, daemon rodando como deploy). A configuração correta é:
deployNÃO está no grupodocker— sem acesso ao socket root/var/run/docker.sockDOCKER_HOSTdefinido por padrão no~/.bashrce~/.profile:export DOCKER_HOST=unix:///run/user/1000/docker.sock- Daemon root desabilitado (
docker.serviceedocker.socketdisabled)
Com isso, qualquer docker ou docker compose executado pelo deploy — interativo ou via script SSH — sempre usa o daemon rootless automaticamente.
Verificar estado correto:
# deploy NÃO deve aparecer em:
groups deploy # não deve conter "docker"
# daemon root deve estar morto:
sudo systemctl status docker # inactive (dead)
# rootless deve responder:
DOCKER_HOST=unix:///run/user/1000/docker.sock docker ps
Incidente registrado — 2026-05-14
O que aconteceu: O daemon root (/usr/bin/dockerd) estava ativo em paralelo com o rootless. O usuário deploy pertencia ao grupo docker. Durante um deploy, docker compose up --build executou sem DOCKER_HOST, criando containers duplicados como root (frontend, backend, nginx) que rodavam ao lado dos containers rootless corretos — invisíveis ao monitoramento normal (docker ps sem sudo não os mostrava).
Consequência direta: O docker-proxy root reteve a porta 8020 após um docker rm -f, bloqueando o nginx rootless de reiniciar. O site ficou inacessível até o docker-proxy zumbi ser identificado (sudo ss -tlnp) e morto.
Correção aplicada:
# 1. Remover containers e imagens duplicados do daemon root
cd /home/deploy/stack/scoreodonto.com
sudo docker compose down --remove-orphans
sudo docker image rm scoreodontocom-scoreodonto-frontend scoreodontocom-scoreodonto-backend
sudo docker network rm soc web
sudo docker builder prune -af
# 2. Desabilitar daemon root definitivamente
sudo systemctl disable --now docker docker.socket
# 3. Remover deploy do grupo docker
sudo gpasswd -d deploy docker
# 4. Garantir DOCKER_HOST nos shells de login (já estava no .bashrc, adicionado ao .profile)
echo 'export DOCKER_HOST=unix:///run/user/1000/docker.sock' >> ~/.profile
⚙️ Pilar 3: Sudoers com Limitação Cirúrgica (Segurança Avançada)
Muitas vezes, a aplicação precisa apenas de tarefas muito específicas do sistema operacional, como por exemplo:
- Reiniciar o servidor web Nginx (
systemctl restart nginx). - Recarregar as configurações do Nginx (
systemctl reload nginx). - Reiniciar um serviço específico da sua aplicação em NodeJS/Python criado no Systemd (
systemctl restart api-app).
Prática:
Em vez de dar acesso total ao sudo para o deploy, nós liberamos apenas estes comandos específicos, sem requisição de senha!
- Criamos um arquivo de configuração exclusivo no Sudoers para o
deploy:sudo nano /etc/sudoers.d/deploy - Adicionamos a regra cirúrgica:
# Permite que o usuário deploy execute APENAS estes comandos listados como root, sem pedir senha: deploy ALL=(ALL) NOPASSWD: /usr/bin/systemctl restart nginx, /usr/bin/systemctl reload nginx, /usr/bin/systemctl status nginx - Aplicamos a permissão correta ao arquivo do sudoers:
sudo chmod 440 /etc/sudoers.d/deploy
Resultado: O usuário deploy agora pode rodar sudo systemctl reload nginx para aplicar uma mudança de domínio na web com total liberdade, mas se ele tentar rodar sudo apt update ou sudo userdel, o sistema negará o acesso.
🔄 Pilar 4: Processos em Espaço de Usuário (PM2 / Systemd User)
Se a sua aplicação web não roda em Docker e precisa ficar ativa em segundo plano (ex: aplicações Node.js, Python FastAPI, Go), o usuário deploy pode gerenciá-la de duas formas sem root:
A. Utilizando o PM2 (NodeJS Process Manager)
O PM2 roda diretamente no espaço de memória do usuário deploy.
# Como usuário deploy, instalar e rodar apps:
pm2 start app.js --name "minha-api"
pm2 save
O deploy tem controle total para reiniciar (pm2 restart minha-api), parar, e ver logs sem precisar do root.
B. Serviços Systemd do Usuário (systemd --user)
O Linux moderno permite que usuários criem seus próprios arquivos de serviço que rodam sob sua conta na pasta:
~/.config/systemd/user/
Você pode gerenciar o serviço rodando:
systemctl --user daemon-reload
systemctl --user restart meu-servico.service
📊 Tabela de Comparação de Segurança:
| Ação | Como o Root faria (Inseguro) | Como o deploy faz com segurança |
|---|---|---|
| Subir arquivos Web | Usa sudo ou loga como root |
Altera livremente dentro de /var/www/ (Dono da pasta) |
| Gerenciar Containers | sudo docker compose restart |
docker compose restart (Membro do grupo docker) |
| Reiniciar Nginx | sudo systemctl restart nginx |
sudo systemctl restart nginx (Autorizado via Sudoers Cirúrgico) |
| Atualizar Código (Git) | Roda git pull como root |
Roda git pull usando suas chaves SSH do usuário |