vps-forge: agentes com root em VPS ganham rollback automático, e autobanimentos caem de 7 em 60 para 0

Um desenvolvedor lançou o vps-forge, um Agent Skill aberto para Claude Code, Codex, Cursor e outros agentes que recebem root em um VPS. O problema é bem real: no benchmark, o Claude Opus 5.5, sem nenhuma orientação, baniu o próprio IP via fail2ban em 7 de 60 execuções, e ainda cortou o acesso do notebook do dono. O principal recurso do skill é o timer de rollback vps-forge-deadman. Antes de editar SSH, firewall, sudo ou PAM, o agente arma um timer do systemd de 5 minutos. Se o novo login não for confirmado, as configurações voltam ao estado anterior sozinhas. Em 120 execuções, a nota subiu de 79–92 para 99–100 de 100. • Cada execução custa $1.87, contra $0.62 sem o skill • Ninguém perdeu acesso ao servidor, nem sem o skill • Código sob licença MIT, sem telemetria

Processado por IA de Habr AI; editado por Hamidun News
vps-forge: agentes com root em VPS ganham rollback automático, e autobanimentos caem de 7 em 60 para 0
Fonte: Habr AI. Colagem: Hamidun News.
Ouvir artigo
Ficha técnica e números-chave
ParâmetroDados
Fonte originalHabr AI ↗
Editor-chefe
Dado-chave #1Cada execução custa $1.87, contra $0.62 sem o skill
Dado-chave #2Ninguém perdeu acesso ao servidor, nem sem o skill
Dado-chave #3Código sob licença MIT, sem telemetria

Um agente com root em um VPS recém-criado instala o fail2ban, confere o login por chave, testa a senha e, na quinta tentativa malsucedida, bane o IP de onde vêm os testes. Ou seja, o seu. Depois disso, todos os comandos estouram o tempo limite, e você precisa procurar o console web no painel da hospedagem. No benchmark do autor do projeto vps-forge, o Claude Opus 5.5, sem orientação, baniu a si mesmo em 7 de 60 execuções. O modelo é inteligente; ninguém apenas lhe disse para incluir o próprio endereço em ignoreip antes da primeira inicialização do fail2ban.

O vps-forge é um Agent Skill aberto: um conjunto de instruções e scripts bash que Claude Code, Codex, Cursor e outros agentes carregam quando a tarefa envolve um servidor. A instalação é feita com `npx skills add mountain-beaver/vps-forge -g`. Há um plugin para o Claude Code e um arquivo zip para o Claude.ai.

Por que «tome cuidado» não funciona

Um sshd_config quebrado parece funcionar. O `sshd -t` não reclama, o reload passa, a sessão atual continua de pé, mas o novo login já está bloqueado: por exemplo, `AllowUsers deploy` quando você é admin, ou um AllowGroups ao qual você esqueceu de se adicionar.

Os agentes têm uma armadilha própria. Eles mantêm uma única conexão via ControlMaster, e a verificação `ssh host true` passa pelo canal antigo. Ela não toca no novo sshd nem nas novas regras de firewall: o teste dá verde, mas ninguém consegue entrar. A instrução «verifique o login a partir de uma nova conexão» não resolve se o agente já perdeu o acesso. É preciso um mecanismo que funcione sem ele.

Pedal de homem morto para o sshd

Antes de cada alteração em SSH, firewall, sudo ou PAM, o agente executa `vps-forge-deadman arm`. O script tira um snapshot das configurações e cria um timer do systemd de 5 minutos. O agente altera a configuração, entra de novo com `ssh -o ControlPath=none` e, se o login funcionar, executa disarm. Se não funcionar, não é preciso fazer nada: em 5 minutos o timer restaura tudo como estava.

No papel, eram 20 linhas de bash; no fim, viraram algumas centenas. Quase cada linha corresponde a uma falha encontrada:

  • Reinicialização. O timer criado com systemd-run vive na memória e desaparece junto com o servidor. Agora o arm também ativa uma unit que, na inicialização, detecta o estado «armado, mas não desarmado» e faz o rollback por conta própria.
  • nftables. O rollback parava um serviço que estava desligado antes do arm, e o ExecStop continha `nft flush ruleset`. Junto com a regra necessária, sumiam o ufw, os bans do fail2ban e as chains do Docker. Agora são removidas apenas as tabelas da configuração que está sendo revertida.
  • Localidade russa do ufw. O script procurava a linha `Status: active`, mas o ufw escreve «Состояние: активен». O firewall era considerado desligado e acabava desativado no rollback. A correção é usar `LC_ALL=C`.
  • Ban depois do rollback. As configurações voltavam, mas o IP continuava banido. Agora o arm memoriza o endereço do cliente SSH, e o rollback o desbane. Sob sudo, a variável SSH_CLIENT não existe, então o endereço é obtido do ambiente do processo pai.

Tudo isso roda no CI: um contêiner com systemd de verdade, em que o teste quebra o sshd, o firewall e o fail2ban, reinicia o contêiner no estado armado e verifica a recuperação. O firewall do painel do provedor não pode ser revertido, porque fica fora do servidor. Ali só funciona a ordem certa: primeiro adicionar a nova regra, verificar o login e só depois remover a antiga.

Armadilhas de imagens de nuvem e o benchmark

A mais traiçoeira é o cloud-init. Em muitos VPS existe um `50-cloud-init.conf` com `PasswordAuthentication yes`. O sshd usa o primeiro valor lido, e os arquivos são lidos em ordem alfabética, então o conselho popular de usar `99-hardening.conf` não faz nada. O arquivo do skill se chama `00-vps-forge.conf`, e o resultado é conferido com `sshd -T`. Há mais casos: o Debian 12 não tem auth.log, o Docker publica portas contornando o ufw, a imagem da Oracle Cloud traz uma regra REJECT própria no iptables, e o Coolify acessa o próprio host por SSH como root, de modo que `PermitRootLogin no` quebra o deploy.

O ambiente de testes usa VMs reais em QEMU (Debian 12 e 13, Ubuntu 22.04, 24.04 e 26.04) e quatro cenários, cada um rodado três vezes sem o skill e três com ele, somando 120 execuções do Opus 5.5. O juiz verifica o servidor por fora, antes e depois da reinicialização. Sem o skill, a nota foi de 79–92 em 100; com ele, 99–100.

  • ssh-audit sem falhas: 4/60 sem o skill, 60/60 com ele
  • Alerta de login por SSH: 16/30 e 30/30
  • Firewall ativado: 46/60 e 60/60
  • Força bruta de senhas é banida: 50/60 e 60/60
  • Root não consegue entrar: 30/60 e 57/60
  • O agente baniu a si mesmo: 7/60 e 0/60
  • Perda de acesso: 0/60 e 0/60

O autor aponta os pontos fracos com franqueza. Um servidor intocado recebe 25–42 pontos. Cerca de 70% da diferença vem de três verificações que coincidem com as próprias configurações do skill: ssh-audit limpo, proibição de root e alerta de login. O juiz e o skill foram escritos pela mesma pessoa, e o Lynis, que é independente, quase não se move: 69 e 71, 72 e 72, 64 e 72, 73 e 72. Três dos quatro cenários foram usados no refinamento do skill. Há apenas um modelo, mais quatro execuções manuais do GLM-5.3. O benchmark não provou o rollback: ninguém perdeu acesso, nem sem o skill.

Custo e como aplicar

O skill é mais lento e custa cerca de três vezes mais: $1.87 contra $0.62 por execução. O benefício que de fato resta é o fail2ban banindo de verdade em um servidor em produção (6 de 15 sem o skill, 15 de 15 com ele), o firewall ativado e zero autobanimentos.

Na prática, funciona assim. Antes da primeira alteração em SSH, confirme que o agente executou `vps-forge-deadman arm`: se não executou, o skill não foi carregado e não há rede de proteção. O script funciona também sem agente, e dá para testá-lo manualmente em um servidor descartável: arme por um minuto, aplique `AllowUsers deploy`, confirme que o login foi bloqueado e aguarde o status ROLLED BACK. Snapshot do provedor e acesso ao console continuam necessários. O RHEL ainda não é suportado, e o skill não mexe em nós de Kubernetes. O código é MIT, sem telemetria, e o ambiente de testes está no diretório bench/ do repositório mountain-beaver/vps-forge.

História

Perguntas frequentes sobre a notícia

Por que «tome cuidado» não funciona?

Um sshd_config quebrado parece funcionar. O `sshd -t` não reclama, o reload passa, a sessão atual continua de pé, mas o novo login já está bloqueado: por exemplo, `AllowUsers deploy` quando você é admin, ou um AllowGroups ao qual você esqueceu de se adicionar. Os agentes têm uma armadilha própria. Eles mantêm uma única conexão via ControlMaster, e a verificação `ssh host true` passa pelo canal antigo. Ela não toca no novo sshd nem nas novas regras de firewall: o teste dá verde, mas ninguém consegue entrar. A instrução «verifique o login a partir de uma nova conexão» não res

O que se sabe sobre Pedal de homem morto para o sshd?

Antes de cada alteração em SSH, firewall, sudo ou PAM, o agente executa `vps-forge-deadman arm`. O script tira um snapshot das configurações e cria um timer do systemd de 5 minutos. O agente altera a configuração, entra de novo com `ssh -o ControlPath=none` e, se o login funcionar, executa disarm. Se não funcionar, não é preciso fazer nada: em 5 minutos o timer restaura tudo como estava. No papel, eram 20 linhas de bash; no fim, viraram algumas centenas. Quase cada linha corresponde a uma falha encontrada: Reinicialização. O timer criado com systemd-run vive na memória e de

O que se sabe sobre Armadilhas de imagens de nuvem e o benchmark?

A mais traiçoeira é o cloud-init. Em muitos VPS existe um `50-cloud-init.conf` com `PasswordAuthentication yes`. O sshd usa o primeiro valor lido, e os arquivos são lidos em ordem alfabética, então o conselho popular de usar `99-hardening.conf` não faz nada. O arquivo do skill se chama `00-vps-forge.conf`, e o resultado é conferido com `sshd -T`. Há mais casos: o Debian 12 não tem auth.log, o Docker publica portas contornando o ufw, a imagem da Oracle Cloud traz uma regra REJECT própria no iptables, e o Coolify acessa o próprio host por SSH como root, de modo que `PermitRoo

ZK
Zhemal Khamidun — CPO da Alpina Digital, gerente de produto do AlpinaGPT. Cria produtos de IA desde 2019. O Hamidun News é um projeto pessoal que virou um agregador em produção com mais de 6.000 leitores.
✦ Hands-On AI Engineering · Hamidun Academy

Build & Ship Production AI Agents Without Boilerplate Code

Start your free 72-hour trial at Hamidun Academy (academy.hamidun.com) — interactive lessons on Claude Code & Cursor, live Tech Radar, and production agent templates.

Start 72h Free Trial →Vibe-Coding Intensive
O que você acha?
Carregando comentários…