Proteger VPS Windows contra ataques de força bruta no RDP
Endureça uma VPS Windows Server contra ataques de força bruta no RDP com firewall, troca de porta, lockout policy e bloqueio automático por IP.
Toda VPS Windows exposta na internet pública começa a receber tentativas de login no RDP poucos minutos após o boot. Bots varrem ranges inteiros de IP em busca da porta 3389 aberta e disparam dicionários de senhas comuns contra contas como Administrator, admin, user e variações. Em uma VPS sem proteção, o Event Log enche de Event ID 4625 (falha de logon) em poucas horas — e basta uma senha fraca pra um atacante conseguir entrada.
Este tutorial é pra sysadmins Windows que provisionaram uma VPS recentemente e querem reduzir a superfície de ataque do RDP antes de colocar o servidor em produção. As medidas aqui não exigem software de terceiros — usam só recursos nativos do Windows Server 2019/2022/2025. Tempo estimado: 30 a 45 minutos pra aplicar todas as camadas.
A abordagem é em camadas — nenhuma medida sozinha é suficiente. Você vai aplicar quatro defesas: política de lockout de conta, troca da porta padrão do RDP, restrição de firewall por IP de origem e bloqueio automático de IPs ofensivos via Tarefa Agendada disparada por evento.
Pré-requisitos
VPS Windows Server 2019, 2022 ou 2025 com acesso administrativo. Conexão RDP atual funcionando. Conheça o IP público do seu escritório/casa antes de começar — se você restringir o RDP e perder esse IP, vai precisar do console da VPS pra recuperar acesso.
TCP 3389 4625 TermService Antes de começar, abra o Visualizador de Eventos em Logs do Windows > Segurança e filtre por Event ID 4625. Em uma VPS exposta há mais de 24 horas você tipicamente vê centenas de tentativas vindas de IPs em China, Rússia, Brasil e EUA. Esse é o baseline que vamos derrubar.
Aplicar política de lockout de conta
A política de lockout faz o Windows desabilitar uma conta temporariamente após N tentativas falhas. Sem isso, um atacante pode disparar milhares de senhas por minuto contra a conta Administrator. Com lockout de 5 tentativas e bloqueio de 30 minutos, o atacante consegue testar no máximo 240 senhas por dia por conta — inviabilizando o ataque por dicionário.
Abra o Editor de Diretiva de Grupo Local (gpedit.msc) e navegue até:
Configuração do Computador > Configurações do Windows > Configurações de Segurança >
Diretivas de Conta > Diretiva de Bloqueio de ContaConfigure os três valores:
- Limite de bloqueio de conta: 5 tentativas inválidas
- Duração do bloqueio de conta: 30 minutos
- Zerar contador após: 30 minutos
Aplique a política imediatamente sem esperar o ciclo de 90 minutos do Group Policy:
gpupdate /forceVerifique que ficou ativa:
net accountsVocê deve ver Limite de bloqueio: 5 e Duração do bloqueio (minutos): 30 no output.
Definir duração de bloqueio como 0 (permanente) parece mais seguro mas cria risco operacional: qualquer erro de digitação seu trava a conta até intervenção manual. 30 minutos é o equilíbrio padrão recomendado pela Microsoft e CIS Benchmark.
Trocar a porta padrão do RDP
Mudar de 3389 pra uma porta alta (acima de 49152, range dinâmico) elimina o ruído de scanners automatizados que só procuram a porta padrão. Não é segurança real contra ataque direcionado — nmap -p- IP ainda encontra — mas reduz Event ID 4625 em 90%+ em VPS expostas.
Abra o Editor de Registro (regedit) e navegue até:
HKLM\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-TcpLocalize a chave PortNumber, mude pra decimal e digite a nova porta (exemplo: 54289). Evite portas conhecidas de outros serviços (8080, 8443, 3306).
Adicione a regra de firewall pra nova porta antes de reiniciar o serviço:
New-NetFirewallRule -DisplayName "RDP Custom Port 54289 TCP" `
-Direction Inbound -LocalPort 54289 -Protocol TCP -Action Allow
New-NetFirewallRule -DisplayName "RDP Custom Port 54289 UDP" `
-Direction Inbound -LocalPort 54289 -Protocol UDP -Action AllowReinicie o serviço de Terminal Server pra aplicar a mudança:
Restart-Service TermService -ForceSua sessão atual vai cair. Reconecte usando IP:54289 no cliente RDP (Remote Desktop Connection do Windows aceita o sufixo :porta).
Se você reiniciar o TermService sem ter criado a regra de firewall pra nova porta, o RDP fica inacessível. Em VPS Hostini você consegue voltar via console no painel — mas pra evitar essa dor, garanta as duas regras antes do Restart-Service.
Restringir RDP por IP de origem
A medida mais efetiva: o firewall só aceita conexões RDP de IPs específicos. Funciona bem se sua equipe acessa de IPs fixos (escritório, VPN corporativa). Não funciona se você precisa acessar de redes residenciais com IP dinâmico — nesse caso, considere a alternativa de túnel WireGuard.
Identifique os IPs que devem ter permissão. Cheque o seu IP público agora:
(Invoke-WebRequest -Uri "https://ifconfig.me/ip").ContentAnote esse IP e o de qualquer outro local que precisa acessar.
Edite a regra de firewall que você criou na seção anterior pra aceitar só esses IPs:
Set-NetFirewallRule -DisplayName "RDP Custom Port 54289 TCP" `
-RemoteAddress @("203.0.113.10", "198.51.100.42")Substitua os IPs do exemplo pelos seus. Pra range CIDR use formato 203.0.113.0/24.
Confirme que a regra está restrita:
Get-NetFirewallRule -DisplayName "RDP Custom Port 54289 TCP" |
Get-NetFirewallAddressFilterO campo RemoteAddress deve mostrar os IPs que você definiu, não Any.
Se você acessa de internet residencial com IP dinâmico, em vez de manter atualizando a allowlist, instale um servidor WireGuard na própria VPS, exponha só UDP 51820 publicamente e restrinja o RDP pra 10.0.0.0/24 (rede interna do túnel). Você passa a conectar via VPN antes do RDP.
Bloquear automaticamente IPs ofensivos
Mesmo com lockout e porta trocada, se você não puder restringir por IP de origem (atendimento ao público, equipe distribuída), configure um bloqueio dinâmico: cada vez que aparece Event ID 4625 acima de um threshold, uma Tarefa Agendada dispara um script PowerShell que adiciona o IP de origem a uma regra de firewall de bloqueio.
Salve o script abaixo em C:\Scripts\BlockBruteforceIP.ps1:
param([string]$EventRecordID)
$event = Get-WinEvent -LogName Security -FilterXPath `
"*[System[EventRecordID=$EventRecordID]]"
$ip = ($event.Properties | Where-Object { $_.Value -match '^\d+\.\d+\.\d+\.\d+$' } |
Select-Object -First 1).Value
if (-not $ip -or $ip -eq "127.0.0.1") { exit }
$ruleName = "AutoBlock-$ip"
if (-not (Get-NetFirewallRule -DisplayName $ruleName -ErrorAction SilentlyContinue)) {
New-NetFirewallRule -DisplayName $ruleName -Direction Inbound `
-RemoteAddress $ip -Action Block | Out-Null
Add-Content "C:\Scripts\blocked-ips.log" "$(Get-Date -Format o) BLOCKED $ip"
}Crie a Tarefa Agendada disparada por evento. Abra o Agendador de Tarefas > Criar Tarefa:
- Geral > Executar com privilégios mais altos: marcado
- Disparadores > Novo: Iniciar a tarefa =
Em um evento, Log =Segurança, ID do Evento =4625 - Ações > Novo: Programa =
powershell.exe, Argumentos:
-ExecutionPolicy Bypass -File C:\Scripts\BlockBruteforceIP.ps1 -EventRecordID $(EventRecordID)Pra passar o $(EventRecordID) corretamente, você precisa editar o XML da tarefa após criar — exporte a tarefa, edite o elemento <ValueQueries> adicionando o RecordId, e reimporte.
Teste forçando uma falha de logon de outra máquina e confirme que o IP foi bloqueado:
Get-NetFirewallRule | Where-Object DisplayName -like "AutoBlock-*"Você também pode revisar o arquivo C:\Scripts\blocked-ips.log pra ver o histórico.
Se montar a Tarefa Agendada manualmente parece frágil, o projeto open-source IPBan faz exatamente isso de forma robusta e gratuita. Ele monitora Event Logs em tempo real e mantém regras de firewall otimizadas. Pra ambientes maiores, vale a pena.
Verificação
Depois de aplicar as quatro camadas, confirme cada uma rodando:
# Lockout policy
net accounts | findstr "Lockout"
# Nova porta RDP ativa
Get-ItemProperty "HKLM:\System\CurrentControlSet\Control\Terminal Server\WinStations\RDP-Tcp" `
| Select-Object PortNumber
# Firewall aceita conexão na nova porta
Test-NetConnection -ComputerName localhost -Port 54289
# Conta foi efetivamente "blindada" — tente login errado 5x de outro IP
# e verifique Event Log em busca de Event ID 4740 (Account Locked Out)
Get-WinEvent -LogName Security -MaxEvents 50 |
Where-Object Id -eq 4740 | Format-Table TimeCreated, Message -AutoSize
Espere 24 horas e revisite o Event Viewer. Você deve ver Event ID 4625 cair de centenas/milhares por dia pra dezenas ou zero, dependendo de quão exposta a porta original ficou antes da mudança.
Próximos passos
- Configure NLA (Network Level Authentication) se não estiver ativo — exige autenticação antes do handshake completo de RDP, reduzindo superfície de ataque a vulnerabilidades pré-auth.
- Considere migrar do RDP nativo pro Azure Bastion ou um gateway RDS com MFA se o ambiente justifica.
- Implemente auditoria de logon bem-sucedido (Event ID 4624) e alertas por email pra logins fora do horário comercial.
- Faça backup periódico do registry (
HKLM\System\CurrentControlSet\Control\Terminal Server) — assim você reverte rápido se algo quebrar. - Se você está provisionando uma nova VPS pra produção, uma VPS Hostini Windows já vem com console out-of-band acessível pelo painel — então mesmo que você se tranque fora do RDP aplicando essas regras, recuperação não exige ticket de suporte.
Perguntas frequentes
Mudar a porta do RDP de 3389 pra outra realmente ajuda?
Sim, mas como medida de redução de ruído, não como segurança real. Scanners automatizados que vasculham a internet inteira focam em 3389 e param de te encontrar quando você muda. Atacantes direcionados ainda vão te achar via nmap. Combine com lockout policy e bloqueio por IP — porta alternativa sozinha é segurança por obscuridade.
Por que não basta deixar o Windows Defender Firewall fazer o trabalho?
O firewall padrão permite RDP de qualquer origem assim que você habilita a Área de Trabalho Remota. Ele não tem lógica de detecção de força bruta nativa — bloqueia ou libera baseado em regras estáticas. Você precisa adicionar regras de origem (allowlist por IP) ou um mecanismo de bloqueio dinâmico via Visualizador de Eventos.
É seguro fechar a porta 3389 e usar só um túnel SSH/WireGuard?
É a abordagem mais segura. Você expõe só a porta do túnel (UDP 51820 pro WireGuard, por exemplo) e o RDP passa a aceitar conexões apenas de 127.0.0.1 ou da rede interna do túnel. Atacante na internet pública nem consegue handshake TCP com o RDP. Trade-off: precisa configurar o cliente em cada máquina que vai administrar.
A política de lockout não trava o próprio administrador?
Pode travar se você errar a senha durante uma sessão real. Por isso a recomendação é lockout de 15-30 minutos, não permanente, e manter uma segunda conta administrativa com nome distinto pra recuperação. Em VPS Hostini você ainda tem acesso ao console via painel mesmo se o RDP travar a conta principal.
O Event ID 4625 detecta todas as tentativas de RDP falhadas?
Detecta as que chegam até a camada de autenticação, que é o caso quando NLA (Network Level Authentication) está habilitado e o cliente envia credenciais. Tentativas anteriores ao handshake completo (probe scans) não geram 4625 — elas aparecem no Security Log como Event 4624 (logon) ou nos logs do TerminalServices. Pra cobertura total combine 4625 + Microsoft-Windows-RemoteDesktopServices/Operational.
Vale a pena usar fail2ban no Windows?
Fail2ban é nativo do Linux. No Windows o equivalente funcional é uma combinação de Tarefa Agendada disparada por Event ID 4625 + script PowerShell que adiciona o IP ofensor a uma regra de firewall de bloqueio. Existem ferramentas open-source que empacotam isso (RDPGuard, IPBan, EvlWatcher) — IPBan é gratuito e é o mais próximo de uma experiência fail2ban-like.