Linux vm hardening
Skill gabriel-f-santos/coding-agents/skills/linux-vm-hardening
Gera cloud-init.yaml com hardening completo para VM Linux. Configura: usuário não-root sudo, SSH key-only (root prohibit-password para Coolify), UFW, fail2ban com ban progressivo, Docker, Coolify e unattended-upgrades. Suporta dois modos: SSH público restrito por IP ou SSH exclusivo via Tailscale VPN. Invocada pelo /hetzner-vm ou diretamente para qualquer VPS (DigitalOcean, AWS EC2, etc.).From its SKILL.md
npx -y skills add gabriel-f-santos/coding-agents --skill linux-vm-hardeningAssembled from the repository path, not quoted from the project. Check it against their README if it does not work.
2 things to look at
- no licenseNo license file was found in the repository. Code published without one is not open source by default, so using it at work is a question for whoever answers licensing questions where you are.
- 0 stars0 stars. Stars are a popularity signal and not a quality one, but at this level it is likely that nobody has read this closely except its author, and you would be relying on your own review.
SKILL.md
4.2 KB, ~1.1k tokens by cl100k_base, as published. Nobody here has run it
Linux VM Hardening — Gerador de Cloud-Init
Gera cloud-init.yaml pronto para qualquer VM Linux. Quando invocada pelo /hetzner-vm, todos os parâmetros já estão no contexto — usar diretamente sem perguntar novamente.
Template base
!cat "${CLAUDE_SKILL_DIR}/templates/cloud-init.yaml.tpl"
Parâmetros
Se não estiverem no contexto (invocação standalone), perguntar um por vez:
| Parâmetro | Default | Descrição |
|---|---|---|
admin_username | deploy | Usuário não-root com sudo |
ssh_public_key | — | Conteúdo de ~/.ssh/id_ed25519.pub |
ssh_port | 22 | Porta SSH (só relevante no modo público) |
timezone | UTC | Ex: America/Sao_Paulo |
ssh_mode | public | public ou tailscale |
tailscale_auth_key | — | Obrigatório se ssh_mode=tailscale |
output_path | $output_path | Onde escrever o arquivo |
Modo SSH — perguntar ao usuário
Como prefere acessar o servidor via SSH?
[1] Público (padrão) — porta 22 aberta, restrita ao seu IP no firewall
[2] Tailscale — porta 22 fechada, acesso só via VPN Tailscale
Se ssh_mode = public
Substituir {{UFW_SSH_RULES}} por:
- ufw allow {{SSH_PORT}}/tcp comment "SSH"
Substituir {{TAILSCALE_INSTALL}} por linha vazia.
Se ssh_mode = tailscale
Invocar /tailscale-setup para guiar o usuário pelo setup completo do tailnet
(conta, cliente local, ACL policy e geração do auth key).
Aguardar a conclusão — o /tailscale-setup retorna o auth key tskey-auth-....
Usar esse valor como {{TAILSCALE_AUTH_KEY}} no template.
Substituir {{UFW_SSH_RULES}} por:
- ufw allow in on tailscale0 comment "SSH via Tailscale"
- ufw allow 41641/udp comment "Tailscale direct WireGuard"
Substituir {{TAILSCALE_INSTALL}} por:
# Tailscale VPN — instalar após UFW para não travar na ativação
- curl -fsSL https://tailscale.com/install.sh | sh
- tailscale up --auth-key={{TAILSCALE_AUTH_KEY}} --ssh --advertise-tags=tag:server
Processo
- Confirmar todos os parâmetros
- Substituir cada
{{PLACEHOLDER}}com os valores reais - Para
{{SSH_MODE}},{{UFW_SSH_RULES}}e{{TAILSCALE_INSTALL}}: aplicar a lógica de modo acima - Escrever o YAML resultante no
output_pathcom a ferramenta Write - Confirmar: "cloud-init.yaml gerado em [path] — modo: [ssh_mode]"
Decisões de segurança
| Configuração | Valor | Por que |
|---|---|---|
PermitRootLogin | prohibit-password | Coolify exige root SSH; bloqueia senha, libera chave |
PasswordAuthentication | no | Elimina superfície de ataque de brute-force |
AllowUsers | {{ADMIN_USERNAME}} root | Whitelist — outros usuários rejeitados na autenticação |
MaxAuthTries 3 + fail2ban | ban após 3 erros | Bane IPs atacantes rapidamente |
bantime.increment | até 7 dias | Reincidentes levam ban progressivo |
| Swap 2GB + swappiness=10 | só usa em último recurso | Coolify + PostgreSQL precisa de margem em VMs pequenas |
| UFW | deny incoming + allow explícito | Defense-in-depth além do firewall do provider |
| Tailscale | porta 22 fechada na internet | Maior postura: SSH só via WireGuard mesh criptografado |
Comparação dos modos SSH
| Modo público | Modo Tailscale | |
|---|---|---|
| Porta 22 exposta | Sim, filtrada por IP | Não — completamente fechada |
| IP dinâmico | Problema (precisa atualizar tfvars) | Sem problema |
| Time com múltiplos IPs | Precisa listar todos | Basta estar no tailnet |
| Dependência externa | Nenhuma | Tailscale control plane |
| Recuperação se travado | Hetzner Console | Hetzner Console |
| Recomendado para | Projetos solo, IP fixo | Times, IPs dinâmicos |
What ships with it: 1 file
3.5 KB alongside SKILL.md
templates/
- cloud-init.yaml.tpl3.5 KB