A primeira hora não é opcional
O espaço de IPv4 da internet é pequeno o bastante para que escaneá-lo por completo exija apenas alguns minutos de um desconhecido bem financiado, e algumas horas de um laptop. As faixas de hosting são publicadas, catalogadas e escaneadas de novo constantemente, então um endereço novo não é obscuro — é uma entrada recente em uma lista que já existe. Na prática, a primeira tentativa automatizada de login por SSH em uma máquina recém-iniciada chega bem antes de você terminar de ler o seu e-mail de boas-vindas, e ela será seguida por milhares de outras, vindas de fontes sem relação entre si, todas tentando as mesmas poucas centenas de senhas contra os mesmos poucos nomes de usuário. Nada disso é direcionado a você. É uma máquina separando a internet entre responde e não responde, e a única coisa que decide em qual pilha você cai é o que você fez na primeira hora.
A boa notícia é que o trabalho é chato e finito. Quatro controles resolvem quase tudo: autenticar com chaves em vez de senhas, recusar toda porta de entrada que você não está servindo deliberadamente, aplicar atualizações de segurança sem que ninguém peça, e parar de operar como root. Cada um leva alguns minutos, e nada disso é exótico. O que faz valer a pena detalhar isso especificamente para um servidor offshore e sem KYC é a assimetria do outro lado — o caminho de recuperação. Em um host mainstream, um sshd_config quebrado termina em um ticket de suporte, uma verificação de identidade e uma sessão de console. Aqui não há identidade registrada para checar, o que é o objetivo inteiro do produto, e também o motivo pelo qual um toque de tecla descuidado custa a sua máquina, em vez de vinte minutos. Cada passo abaixo foi escrito com isso em mente.
O que realmente ataca um servidor pequeno
Duas populações bem diferentes aparecem nos logs, e vale a pena separá-las, porque cada uma é vencida por coisas diferentes. A esmagadora maioria é escaneamento em massa indiscriminado: bots vasculhando o espaço de endereços em busca de SSH que aceita senha, bancos de dados vinculados a 0.0.0.0, painéis de administração com credenciais padrão, cópias de staging esquecidas, aplicações web sem patch com um exploit público. Essa população não liga para o que o seu servidor faz. Não dá para negociar com ela, ela nunca para, e é derrotada por completo pelo checklist deste guia — não porque o checklist seja inteligente, mas porque os bots estão procurando máquinas que pularam essas etapas, e sobra máquina dessas.
A segunda população é direcionada — alguém que quer especificamente a sua máquina — e ela é rara, cara, e quase nunca entra pelo SSH. Ela chega pela aplicação que você implantou, uma dependência que você não auditou, uma credencial que você reutilizou, ou um laptop que foi comprometido antes mesmo de tocar no servidor. É por isso que proteger o servidor não termina no firewall: as perguntas que realmente importam passam a ser com qual usuário o seu serviço roda, o que ele consegue alcançar para fora, e com que rapidez você aplica patches. Vale saber enquanto você planeja: nossos planos de VPS são virtualização completa em KVM, então você roda o seu próprio kernel, e toda a caixa de ferramentas — nftables, ufw, namespaces, seccomp, sysctl personalizado — realmente funciona, o que não é verdade em produtos de "VPS" baseados em contêiner, onde o kernel pertence a outra pessoa.
SSH: chaves, e exatamente uma porta
Autenticação por senha em uma porta SSH pública é o maior risco autoinfligido em um servidor alugado, e removê-la representa os cinco minutos mais valiosos deste guia. Gere um par de chaves Ed25519 na sua própria máquina — nunca no servidor, onde a metade privada nasceria exatamente no host que você está tentando proteger — proteja-a com uma frase secreta, e carregue-a em um agente, para que a frase secreta custe um prompt por sessão, em vez de um por login. Envie a metade pública para lá, confirme que funciona, e só então desligue as senhas. Com PasswordAuthentication no e KbdInteractiveAuthentication no em vigor, os milhares de tentativas diárias deixam de ser um risco e passam a ser mero ruído: não há senha para adivinhar, então a tentativa falha antes mesmo de ficar interessante.
O root merece a sua própria decisão. PermitRootLogin prohibit-password mantém o acesso root baseado em chave para emergências; PermitRootLogin no é mais rígido, e força toda sessão a passar por uma conta nomeada com sudo, que é exatamente o que você quer assim que mais de uma pessoa mexer na máquina. Adicione AllowUsers para que uma conta órfã, criada por algum pacote, nunca vire um caminho de login. Mover o daemon para fora da porta 22 vale a pena, mas seja honesto sobre o motivo: não é um controle de segurança — qualquer um que escaneie o seu endereço vai encontrar a nova porta em segundos — é higiene de logs, e isso remove a grande maioria do ruído automatizado, para que as entradas que sobram no auth.log sejam coisas que valha a pena ler de fato. O que quer que você mude, valide com sshd -t antes de recarregar, e mantenha a sessão atual aberta até que um segundo terminal tenha se conectado com sucesso. Esse hábito é a diferença entre um erro de digitação e um servidor perdido.
Bloqueio por padrão, e a metade do firewall que ninguém configura
Um firewall em um servidor tem um único trabalho: fazer a resposta para "o que está escutando aqui?" ser igual à lista de coisas que você publicou deliberadamente. Bloqueie por padrão na entrada, permita na saída, e então abra as portas uma de cada vez, com um motivo associado a cada uma. Antes de escrever uma única regra, rode ss -tulpen e veja o que já está vinculado — uma instalação padrão escuta em mais coisas do que a maioria das pessoas espera, e um banco de dados ou cache vinculado a 0.0.0.0 em vez de 127.0.0.1 é o jeito clássico de um servidor pequeno acabar no dataset de alguém. Vincule os serviços locais ao loopback primeiro; o firewall é a sua segunda linha de defesa, não a única.
Depois tem a metade que fica de fora. Todo plano aqui já vem com um /64 de IPv6 junto com o IPv4, e a maioria dos daemons modernos se vincula tranquilamente às duas famílias. Se as suas regras só cobrem v4, um serviço que você acredita estar protegido por firewall fica acessível por v6 para qualquer um que resolva o endereço — e o escaneamento de IPv6 de um prefixo de hosting conhecido é rotina completa. O ufw lida com as duas, sim, mas só quando IPV6=yes está definido em /etc/default/ufw; verifique com ufw status verbose em vez de presumir. O Docker merece a mesma desconfiança: publicar uma porta de contêiner com -p insere regras na própria chain do iptables dele, avaliadas antes das do ufw, então um contêiner que você achava protegido muitas vezes está completamente aberto. Vincule-o explicitamente a 127.0.0.1:port e coloque um proxy reverso na frente. O que quer que você configure, teste a partir de outro lugar na internet — uma regra que só foi lida é uma regra que nunca foi testada.
Atualizações que você não precisa lembrar
É por software desatualizado que a maioria dos servidores pequenos se perde de verdade, e o motivo é humano, não técnico: aplicar patches é uma tarefa chata que compete com tudo mais que você precisa fazer. Automatize o canal de segurança, e o problema desaparece. O unattended-upgrades, no Debian e no Ubuntu, aplica atualizações de segurança em um temporizador e não atrapalha; restrinja-o ao canal de segurança, e não a toda atualização disponível, para que um lançamento de recursos de rotina nunca reinicie a sua aplicação às três da manhã. Isso importa mais em uma máquina offshore autogerenciada do que em uma plataforma gerenciada, porque ninguém está aplicando patches por você, e nenhum gerente de conta vai te mandar um e-mail sobre um CVE crítico — não há nenhum endereço de e-mail registrado para alcançar.
Atualizações de kernel precisam de uma reinicialização para valer, então decida a sua política de reinicialização de forma deliberada, em vez de descobri-la depois. O needrestart vai te dizer quais serviços ainda estão rodando contra bibliotecas apagadas, e uma janela de Unattended-Upgrade::Automatic-Reboot de madrugada é tranquila para um serviço sem estado. Uma interação importante: se você seguiu o nosso guia de criptografia de disco completo e a sua raiz está criptografada, uma reinicialização automática para em um prompt de frase secreta e fica ali até que você a desbloqueie pela rede. Ou mantenha as reinicializações automáticas desligadas nessas máquinas, ou garanta que o desbloqueio remoto esteja testado e que você esteja acordado durante a janela. Seja qual for a sua escolha, escreva isso — uma política que só existe na sua cabeça deixa de existir no momento em que você sai de férias.
Limitação de taxa, fail2ban, e o piso de ruído
Depois que a autenticação por senha está desligada, força bruta contra o SSH não tem como funcionar. Vale deixar claro o que ferramentas como o fail2ban ainda entregam depois desse ponto: não uma defesa contra tentativas de adivinhação — isso já é impossível — mas um log mais silencioso, menos CPU gasta em handshakes fadados ao fracasso, e um controle genuíno nas camadas onde segredos ainda podem ser adivinhados. Aponte-o para os lugares que importam: o formulário de login de uma aplicação web, o SMTP AUTH de um servidor de e-mail, um caminho de admin que alguém está enumerando. O ufw limit te dá um teto barato de taxa de conexão sem nenhum software extra. Um punhado de ajustes de kernel vale os mesmos cinco minutos — SYN cookies ligados, filtragem de caminho reverso ligada, respostas a broadcast ICMP desligadas, e anúncios de roteador IPv6 ignorados em um servidor com endereço estático.
Saiba onde o host para, no entanto. Nada disso sobrevive a um ataque volumétrico, porque uma inundação enche o link de rede bem antes de incomodar a CPU: quando os pacotes chegam às suas regras do nftables, eles já consumiram a banda que você estava tentando proteger. É por isso que o scrubbing de L3/L4 de até 1.5 Tbps fica a montante da frota, e está incluído em todo plano, em vez de ser vendido à parte, com um escudo opcional de L7 para inundações da camada de aplicação que parecem requisições legítimas. O firewall do seu host cuida da precisão; a rede cuida do volume. Tratar um como substituto do outro é como as pessoas acabam se surpreendendo.
Trancar-se para fora é o risco real aqui
De tudo que pode dar errado nessa primeira hora, o resultado mais provável, de longe, não é uma invasão. É você, no fim de uma sessão longa, recarregando um sshd_config quebrado ou ativando um firewall cuja regra de permissão tem um erro de digitação, e descobrindo que a porta se fechou atrás de você. Em um provedor mainstream, isso é um incômodo. Aqui, isso merece respeito de verdade, porque o registro é um nome de usuário e uma senha, com oito códigos de recuperação e nenhum e-mail em qualquer parte do processo, justamente para que não haja identidade a vazar — e um provedor que não consegue te identificar também não consegue te identificar de volta para dentro do seu servidor. Ninguém pode dar aval por você. Essa característica é o produto funcionando como projetado, e é por isso que as salvaguardas abaixo são hábitos, não sugestões.
Quatro delas não custam nada. Tire um snapshot antes de mexer no SSH ou no firewall, para que um reload ruim vire um rollback, e não uma reconstrução do zero. Cadastre uma segunda chave pública de um dispositivo diferente — um celular, um laptop de trabalho, um backup offline — porque uma chave em um único disco está a um café derramado de distância de virar nenhuma chave. Mantenha um segundo terminal conectado enquanto você muda qualquer coisa que possa derrubar o primeiro, e sempre teste a configuração nova a partir de uma conexão nova antes de soltar a antiga. E aceite onde a escada de recuperação termina: snapshots ficam no mesmo host e são uma conveniência de rollback, não um backup, então qualquer coisa de que você realmente sentiria falta pertence a um armazenamento fora do host — o complemento de backups diários criptografados, ou as suas próprias cópias criptografadas do lado do cliente, enviadas para outro lugar. O seu pior cenário deveria ser reimplantar e restaurar, medido em minutos, e não perdido para sempre.
SP·08O que adicionar depois, dependendo do que a máquina faz
O checklist acima é o piso, e é o mesmo para toda máquina. O que vem em cima depende inteiramente da função dela. Um servidor web público quer TLS, um proxy reverso terminando essa conexão, a aplicação rodando como um usuário sem privilégios, e o banco de dados no loopback ou em outra máquina completamente à parte. Um endpoint de VPN tem um formato diferente — uma porta UDP, nenhuma stack web, nenhum serviço público — e é tratado do início ao fim em montar a sua própria VPN WireGuard. Um servidor de e-mail é o mais exigente dos três, e precisa de controle de rDNS sobre o endereço, o que todo plano inclui; hospedar seu próprio e-mail em um VPS offshore cobre a metade da entregabilidade. Um relé Tor é, de propósito, o oposto de anônimo — é um serviço publicado e contatável — e as concessões envolvidas estão detalhadas em rodar um relé em um VPS sem KYC. Qualquer coisa que guarde estado privado em repouso também deveria estar criptografada, o que é um controle separado, com seus próprios modos de falha, coberto em LUKS e desbloqueio remoto.
Vale terminar mostrando onde a proteção se encaixa no quadro geral, porque ela é só uma de três camadas, e elas falham de forma independente. O que o host sabe sobre você é a primeira, e aqui isso é próximo de nada: um nome de usuário financiado por um saldo pré-pago em cripto a partir de $30.00, sem cartão e sem documento na cadeia — o assunto de pagar por hosting de forma anônima. Qual lei se aplica é a segunda, decidida por onde a máquina está, entre as nossas 6 regiões, e não por onde você está, e trabalhada região por região em qual localização offshore você deveria escolher?. O que a própria máquina permite é a terceira, e essa é só sua — nenhum provedor pode configurar isso por você. Um VPS a partir de $8.00/mês fica online em cerca de 15 min, o que significa que a hora seguinte é onde a segurança de fato dessa coisa é decidida. Gaste-a de propósito.
SP·09Passo a passo
-
01
Implante, depois entre antes de qualquer outra coisa
Implante pelo painel e escolha uma distribuição que você realmente vai manter atualizada — um Debian atual ou um Ubuntu LTS é a resposta chata e certa. Um VPS fica online em cerca de 15 min e as credenciais de root chegam no seu painel. Conecte-se imediatamente, deixe o sistema totalmente atualizado, e defina um hostname para que os logs depois sejam legíveis. Nada mais acontece nessa máquina até que o resto destes passos esteja feito.
ssh root@203.0.113.10 apt update && apt full-upgrade -y hostnamectl set-hostname edge-01 apt install -y ufw unattended-upgrades needrestart
-
02
Saia do root: um usuário nomeado, uma chave, e sudo
Gere o par de chaves no seu laptop, nunca no servidor. Depois crie uma conta nomeada na máquina, coloque a metade pública no
authorized_keysdela, e dê a elasudo. Abra um segundo terminal e faça login como esse usuário agora mesmo — antes de mudar qualquer outra coisa, enquanto o root por SSH ainda funciona como alternativa.# on your own machine ssh-keygen -t ed25519 -C "laptop" ssh-copy-id -i ~/.ssh/id_ed25519.pub root@203.0.113.10 # on the server adduser --disabled-password --gecos "" ops usermod -aG sudo ops install -d -m 700 -o ops -g ops /home/ops/.ssh cp /root/.ssh/authorized_keys /home/ops/.ssh/ chown ops:ops /home/ops/.ssh/authorized_keys chmod 600 /home/ops/.ssh/authorized_keys
-
03
Tranque o daemon SSH — com um segundo terminal aberto
Escreva as mudanças em um arquivo drop-in, em vez de editar a configuração original, para que uma atualização de distribuição nunca as reverta silenciosamente. Valide a sintaxe com
sshd -tantes de recarregar, recarregue, depois prove que funciona a partir de uma conexão totalmente nova, enquanto a atual ainda está viva. Se a nova conexão falhar, você ainda tem uma sessão funcionando para desfazer a mudança. Uma armadilha de distribuição: no Ubuntu 24.04 o daemon é ativado por socket, entãoPortemsshd_configé ignorado — defina a porta comsystemctl edit ssh.socket, ou desative a unidade de socket.cat > /etc/ssh/sshd_config.d/10-hardening.conf <<'EOF' Port 2222 PermitRootLogin prohibit-password PasswordAuthentication no KbdInteractiveAuthentication no AllowUsers ops X11Forwarding no MaxAuthTries 3 LoginGraceTime 20 EOF sshd -t && systemctl reload ssh # new terminal, do not close the old one: ssh -p 2222 ops@203.0.113.10
-
04
Bloqueie o firewall por padrão, nas duas famílias de IP
Confirme que o IPv6 está habilitado no ufw, depois negue tudo na entrada e abra só as portas que você está servindo deliberadamente — incluindo a nova porta SSH, que precisa ser permitida antes de você ativar o firewall. Aproveite para checar o que está realmente escutando, e mova para o loopback qualquer coisa que devesse ser local.
grep IPV6 /etc/default/ufw # must read IPV6=yes ufw default deny incoming ufw default allow outgoing ufw limit 2222/tcp ufw allow 80,443/tcp ufw enable ufw status verbose ss -tulpen # anything on 0.0.0.0 or :: ?
-
05
Ative as atualizações de segurança automáticas
Ative só o canal de segurança, para que os patches cheguem sem que uma atualização de recursos reinicie a sua aplicação sem avisar. Decida a política de reinicialização explicitamente — e deixe as reinicializações automáticas desligadas se a raiz estiver criptografada e precisar de um desbloqueio manual.
dpkg-reconfigure -plow unattended-upgrades cat > /etc/apt/apt.conf.d/51-local <<'EOF' Unattended-Upgrade::Automatic-Reboot "false"; Unattended-Upgrade::Remove-Unused-Kernel-Packages "true"; EOF unattended-upgrade --dry-run --debug | tail -20
-
06
Reduza o ruído e ajuste os parâmetros do kernel
Adicione o
fail2banpara as camadas onde ainda é possível adivinhar um segredo, e defina o punhado de valores de sysctl que são simplesmente corretos em um servidor público com endereço estático. Isso é barato, e faz valer a pena ler os logs.apt install -y fail2ban cat > /etc/sysctl.d/99-harden.conf <<'EOF' net.ipv4.tcp_syncookies = 1 net.ipv4.conf.all.rp_filter = 1 net.ipv4.icmp_echo_ignore_broadcasts = 1 net.ipv4.conf.all.accept_redirects = 0 net.ipv6.conf.all.accept_ra = 0 kernel.kptr_restrict = 2 EOF sysctl --system
-
07
Verifique de fora, depois escreva o runbook
Confie na visão a partir da internet, não na visão de dentro da máquina. Confirme que a porta SSH antiga sumiu, que nada inesperado responde, e que o login só por chave está realmente em vigor. Depois anote os três fatos que você vai precisar no seu pior dia: onde está a sua segunda chave, qual snapshot você tirou, e onde está o backup fora do host.
# from another machine ssh -p 22 ops@203.0.113.10 # must time out or be refused ssh -p 2222 -o PreferredAuthentications=password ops@203.0.113.10 # expected: Permission denied (publickey) ssh -p 2222 ops@203.0.113.10 'sudo ufw status verbose; uptime'


