Resposta rápida: como proteger o wp-admin contra força bruta
Para blindar a área administrativa do WordPress sem depender só de plugin, empilhe sete camadas: (1) limitar tentativas de login com Limit Login Attempts Reloaded, (2) ativar 2FA com o plugin oficial Two Factor, (3) renomear a URL de login com WPS Hide Login como obscuridade complementar, (4) restringir wp-login.php e /wp-admin por IP no .htaccess (Apache) ou via allow/deny no Nginx, (5) adicionar HTTP Basic Auth com auth_basic no Nginx, (6) criar WAF Custom Rules e Rate Limiting gratuitos no Cloudflare para /wp-login.php, e (7) desativar XML-RPC quando não houver Jetpack ou app mobile em uso. Cada camada sozinha falha — o conjunto vence o ataque automatizado.
Como funciona um ataque de força bruta contra wp-admin
Botnets distribuídas disparam milhares de POSTs contra /wp-login.php e /xmlrpc.php tentando combinações de usuário e senha. O xmlrpc.php é particularmente perigoso porque o método system.multicall permite empacotar centenas de tentativas em uma única requisição HTTP, segundo a referência oficial do XML-RPC API. Como os IPs variam (rotação por proxy residencial), bloquear um IP só não basta. A documentação oficial de Hardening WordPress recomenda senhas fortes, limitação de acesso ao wp-admin por IP e DISALLOW_FILE_EDIT — três medidas complementares, nunca isoladas.

Camada 1: Limitar tentativas de login com Limit Login Attempts Reloaded
O Limit Login Attempts Reloaded bloqueia o IP após N tentativas falhas e tem versão gratuita com mais de 2 milhões de instalações ativas. Configuração que uso em produção: 4 tentativas, lockout de 20 minutos, 4 lockouts elevam para 24 horas. Ative o GDPR compliance e o XMLRPC gateway no menu do plugin — sem isso, o atacante pula a porta da frente e bate direto no XML-RPC. Para não travar usuário legítimo, adicione o IP do escritório na allowlist do próprio plugin.

Camada 2: Ativar 2FA com o plugin oficial Two Factor
O Two Factor, mantido por contribuidores do core, adiciona segundo fator via TOTP (Google Authenticator, Authy), e-mail e chaves FIDO U2F. Ative para todas as roles administrator e editor — não confie apenas no admin. Detalhamos a configuração no 2FA no WordPress: como proteger o login sem travar, incluindo o fluxo de backup codes para não perder acesso se o celular sumir.

Camada 3: Renomear a URL com WPS Hide Login
O WPS Hide Login altera a URL de login sem mexer em arquivos do core. Aviso direto: isso é segurança por obscuridade. Reduz ruído de bots burros que batem em /wp-login.php, mas não engana scanner sério que segue redirects ou olha o HTML. Use como filtro de poluição de log, nunca como defesa única. Defina algo memorável só pelo time, tipo /entrar-time-x, e documente — esquecer essa URL é o erro mais comum.

Camada 4: Bloquear /wp-login.php e /wp-admin por IP

Apache (.htaccess)
Usando Require ip do mod_authz_host, libere só seu IP fixo:

<Files wp-login.php>
Require ip 203.0.113.45
Require ip 198.51.100.0/24
</Files>
Nginx
Combine allow/deny do ngx_http_access_module com limit_req para defesa em profundidade:
limit_req_zone $binary_remote_addr zone=login:10m rate=5r/m;
location = /wp-login.php {
limit_req zone=login burst=3 nodelay;
allow 203.0.113.45;
allow 198.51.100.0/24;
deny all;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
Se você usa cache no mesmo servidor, garanta que /wp-login.php está no fastcgi_cache_bypass — veja o Cache HTTP no Nginx para WordPress sem quebrar login.
Se você usa cache no mesmo servidor, garanta que /wp-login.php está no fastcgi_cache_bypass — detalhes em Cache HTTP no Nginx para WordPress sem quebrar login.
Camada 5: HTTP Basic Auth no wp-admin via Nginx
O auth_basic coloca uma senha HTTP antes mesmo do PHP rodar — qualquer brute force quebra na borda:
location ^~ /wp-admin/ {
auth_basic "Restrito";
auth_basic_user_file /etc/nginx/.htpasswd-wpadmin;
location ~ \.php$ {
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
}
location = /wp-admin/admin-ajax.php {
auth_basic off;
include fastcgi_params;
fastcgi_pass unix:/run/php/php8.2-fpm.sock;
}
Gere o arquivo com htpasswd -c /etc/nginx/.htpasswd-wpadmin admin. A exceção do admin-ajax.php é obrigatória — esquecer isso quebra frontend de plugins como WooCommerce e Contact Form 7.
Camada 6: WAF Cloudflare gratuito em /wp-login.php
O plano free da Cloudflare permite criar WAF Custom Rules e Rate Limiting Rules. Para um site brasileiro, bloqueie tudo que não venha do Brasil:
(http.request.uri.path eq "/wp-login.php" and ip.geoip.country ne "BR")
→ Action: Block
Em seguida, uma regra de rate limiting: 5 requests por minuto em /wp-login.php com ação Block por 1 hora. Isso filtra 95% do tráfego automatizado antes de chegar ao seu Nginx. Se está escolhendo CDN, veja o comparativo Cloudflare vs BunnyCDN para WordPress.
Camada 7: Desativar XML-RPC com segurança
Se você não usa Jetpack, app mobile WordPress nem pingbacks, desative o XML-RPC. No Nginx:
location = /xmlrpc.php { deny all; return 444; }
No Apache:
<Files xmlrpc.php>
Require all denied
</Files>
Atenção: isso quebra o app mobile oficial, Jetpack e pingbacks. Se precisa do Jetpack, mantenha o XML-RPC e restrinja apenas o método system.multicall via WAF, ou confie em plugins que filtram esse método específico.
Wordfence vs Solid Security vs All-In-One Security
| Recurso | Wordfence Free | Solid Security Free | AIOS Free |
|---|---|---|---|
| WAF | Endpoint (PHP) | — | Regras básicas (.htaccess) |
| 2FA | Sim (Login Security) | Sim | Sim |
| Limit login | Sim | Sim | Sim |
| Malware scan | Sim | Pago | Sim |
| Impacto perf. | Médio-alto | Baixo | Baixo-médio |
Critério prático: VPS pequena com pouco RAM → Solid Security. Site exposto com histórico de invasão → Wordfence pela combinação WAF + scanner. Quem só quer um setup-and-forget gratuito → AIOS.
Hardening do wp-config.php e SALT keys
No wp-config.php:
define('DISALLOW_FILE_EDIT', true);
define('DISALLOW_FILE_MODS', true);
Regenere as SALT keys em https://api.wordpress.org/secret-key/1.1/salt/ e cole no wp-config.php — isso invalida todas as sessões atuais (ótimo após suspeita de comprometimento). Para integrações externas, use Application Passwords, disponíveis no core desde a 5.6, em vez de expor a senha principal.
Checklist de validação pós-hardening
- Abra janela anônima e tente acessar
/wp-login.phpsem estar no IP allowlisted — deve dar 403. - Confira o access.log:
tail -f /var/log/nginx/access.log | grep wp-loginpara ver o que ainda passa. - Teste recuperação por e-mail: dispare “esqueci a senha” e confirme que o link chega — se SMTP estiver quebrado, você perde acesso.
- Verifique loop de redirect: WPS Hide Login + cache mal configurado causa redirect infinito.
- Allowlist do próprio IP em todas as camadas (plugin, .htaccess/Nginx, Cloudflare).
- Plano B via SSH: tenha o WP-CLI para gestão avançada no terminal instalado para resetar senha via
wp user update admin --user_pass=NovaSenhase travar fora.
Hardening é iterativo. Aplique uma camada, valide, parta para a próxima. Tentar empilhar as sete de uma vez é como você se trancou para fora do painel — pergunte a qualquer admin que já fez isso.