1. Cenário do incidente e hipóteses de bloqueio#
Se a tela de login (wp-login.php) nem sequer carrega, sua investigação precisa focar nas seguintes camadas de bloqueio de requisição:
- Servidor Web ou WAF: Erro
HTTP 403 Forbiddengerado por ModSecurity (Apache) ou regras rígidas no Nginx. - Plugin de Segurança: Bloqueio disparado durante o bootstrap do WordPress por um plugin de segurança instável ou hiperativo.
- Regras no
.htaccess: Bloqueios IP/regras de rewrite aplicadas por plugins que persistem mesmo após sua desativação. - Headers de Proxy/CDN: Interpretação incorreta do IP do administrador por trás do Cloudflare ou proxy reverso.
2. Backups preventivos: etapa P0 obrigatória#
Nunca inicie ações corretivas diretamente no ambiente de produção sem antes assegurar cópias de segurança do banco de dados, dos arquivos de plugins e das configurações do servidor.
# 1. Backup completo do Banco de Dados via WP-CLI
wp db export backup-pre-correcao-$(date +%Y%m%d-%H%M%S).sql
# 2. Backup do diretório de conteúdo (wp-content)
tar czf /tmp/wp-content-backup-$(date +%Y%m%d).tar.gz wp-content/
# 3. Backup do arquivo de regras do servidor web
cp .htaccess .htaccess.bak.$(date +%F-%H%M%S)
3. Diagnóstico por camadas e rastreamento de logs#
3.1 teste de requisição HTTP com cURL#
Valide o retorno do servidor isolando a sessão do seu navegador (para contornar caches locais):
curl -I https://domain.com/wp-admin/
- HTTP 403 Forbidden: Bloqueio ocorrendo na camada do servidor web (Apache/Nginx/WAF).
- HTTP 200 OK com mensagem de bloqueio: O servidor web permitiu a requisição, mas o script PHP/WordPress interceptou e abortou a execução.
3.2 habilitação temporária de debug e rastreamento de logs#
Se o erro for gerado pelo WordPress, os detalhes do bootstrap estarão no log de erros. Adicione temporariamente no seu wp-config.php:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
Após adicionar, force o carregamento da página e inspecione os arquivos de log relevantes:
# 1. Log de debug do WordPress
tail -n 50 wp-content/debug.log
# 2. Log de erros do PHP (exemplo de caminho no Debian/Ubuntu)
tail -n 50 /var/log/php/error.log
# 3. Logs de erros do Servidor Web
tail -n 50 /var/log/apache2/error.log
tail -n 50 /var/log/nginx/error.log
4. Auditoria de arquivos e permissões no host#
4.1 permissões de arquivos e pastas do WordPress#
A falta de permissão correta pode impedir o Apache ou Nginx de ler arquivos vitais da aplicação, simulando um erro de login. Garanta a estrutura de segurança:
# Definir permissões para diretórios (755) e arquivos (644)
find . -type d -exec chmod 755 {} \;
find . -type f -exec chmod 644 {} \;
# Hardening no arquivo de configuração sensível
chmod 400 wp-config.php
# Garantir ownership para o usuário que roda o servidor web
chown -R www-data:www-data /var/www/html
4.2 inspecionando a integridade do .htaccess#
Se você roda Apache, regras de reescrita órfãs ou duplicadas podem bloquear o acesso ao admin.
# Verificar conteúdo completo
cat .htaccess
# Procurar blocos de marcação de segurança
grep -n "BEGIN\|END" .htaccess
# Verificar número de blocos de marcação BEGIN
grep -c "BEGIN" .htaccess
Se houver blocos duplicados de segurança ou regras repetidas, limpe o arquivo re-gerando as regras básicas de permalinks do WordPress.
5. Recuperação de Acesso: Criação de Administrador e Redefinição de Senha via WP-CLI e MySQL#
Se o core do WordPress está íntegro (wp core is-installed), podemos usar a linha de comando para gerenciar os plugins.
5.1 desativação de plugins específicos#
Identifique o plugin de segurança ativo e desative-o usando seu slug real:
# Listar plugins ativos
wp plugin list --status=active
# Desativação do plugin problemático
wp plugin deactivate all-in-one-wp-security-and-firewall
Caso o plugin trave o próprio bootstrap do WP-CLI, force o desvio usando a flag --skip-plugins:
wp plugin deactivate all-in-one-wp-security-and-firewall --skip-plugins
5.2 desativação global (emergência)#
Se você não sabe qual plugin causou a pane, desative todos os plugins ativos simultaneamente:
# Desativar todos os plugins ativos de uma vez
wp plugin deactivate $(wp plugin list --status=active --field=name) --skip-plugins
# Ou usando a flag direta de desativação geral
wp plugin deactivate --all --skip-plugins
Slugs de outros plugins de segurança comuns:#
- Wordfence Security:
wordfence - Solid Security (antigo iThemes):
ithemes-security - Sucuri Security:
sucuri-scanner - BulletProof Security:
bulletproof-security - Shield Security:
wp-security-shield
Se você perdeu acesso ao painel WordPress, este guia cobre os dois cenários mais comuns em produção:
- criar um novo administrador;
- redefinir a senha de um usuário existente.
O WordPress trabalha com diferentes níveis de usuários, cada um com permissões específicas:
- User: acesso apenas à leitura e edição do próprio perfil.
- Manager: herda permissões de user e também pode ler e editar artigos.
- Collaborator: herda permissões de user e pode enviar artigos.
- Administrator: possui todas as permissões do sistema.
Aviso: As permissões podem variar conforme instalação, tema e plugins.
Criação de Administrador de Emergência via WP-CLI#
Via WP-CLI#
Se o WP-CLI estiver instalado, você pode criar o novo administrador rapidamente.
Guia de instalação:
<https://domain.com/article/instalando-wpcli-na-hospedagem/>
Crie o usuário administrador:
php wp user create NOME_USUARIO EMAIL --role=administrator --user_pass="SENHA"
Confirme se foi criado:
php wp user list
Criação de Administrador Direto no Banco (Fallback sem WP-CLI)#
Se não tiver acesso ao WP-CLI, é possível criar o administrador direto no banco.
Identifique o banco usado na instalação:
grep DB wp-config.php
Conecte ao MySQL/MariaDB:
mysql -u USUARIO -p
Se o login estiver correto, verá algo como:
MariaDB [(none)]:
Selecione o banco:
use BANCO_DE_DADOS;
Liste as tabelas para identificar o prefixo:
show tables;
Exemplo de saída:
| wp_e_events |
| wp_e_submissions |
| wp_expm_maker_pages |
| wp_ezoic_endpoints |
Nesse exemplo, o prefixo é wp_.
Agora crie o novo usuário administrador:
INSERT INTO wp_users (user_login, user_pass, user_nicename, user_email, user_status, display_name)
VALUES ('NOME_USUARIO', MD5('SENHA_USUARIO'), 'NOME COMPLETO', 'EMAIL_USUARIO', 0, 'NOME COMPLETO');
- NOME_USUARIO: exemplo
joao - SENHA_USUARIO: use senha forte
- NOME COMPLETO: nome e sobrenome
- EMAIL_USUARIO: e-mail válido do usuário
Exemplo prático:
INSERT INTO wp_users (user_login, user_pass, user_nicename, user_email, user_status, display_name)
VALUES ('usuario', MD5('mudar123'), 'Usuario Teste', '[email protected]', 0, 'Usuario Teste');
Query OK, 1 row affected (0.001 sec)
Verifique o ID atribuído:
SELECT ID FROM wp_users WHERE user_login = 'NOME_USUARIO';
Saída esperada:
SELECT ID FROM wp_users WHERE user_login = 'usuario';
+----+
| id |
+----+
| 90 |
+----+
1 row in set (0.001 sec)
Aviso: O ID muda a cada novo usuário criado. No exemplo acima, o ID é 90.
Agora atribua permissões de administrador:
INSERT INTO wp_usermeta (user_id, meta_key, meta_value)
VALUES (ID_DO_USUARIO, 'wp_capabilities', 'a:1:{s:13:"administrator";b:1;}');
Exemplo:
INSERT INTO wp_usermeta (user_id, meta_key, meta_value)
VALUES (90, 'wp_capabilities', 'a:1:{s:13:"administrator";b:1;}');
Query OK, 1 row affected (0.004 sec)
Adicione também o nível do usuário:
INSERT INTO wp_usermeta (user_id, meta_key, meta_value)
VALUES (ID_DO_USUARIO, 'wp_user_level', '10');
Exemplo:
INSERT INTO wp_usermeta (user_id, meta_key, meta_value)
VALUES (90, 'wp_user_level', '10');
Query OK, 1 row affected (0.001 sec)
Pronto. O usuário já terá permissões administrativas e poderá acessar o wp-admin.
Redefinição Segura de Senhas (WP-CLI e MySQL)#
Quando a conta já existe, redefinir senha costuma ser mais rápido do que criar novo admin.
Via WP-CLI#
Liste usuários e atualize a senha do ID correto:
php wp user list
php wp user update ID_DO_USUARIO --user_pass="NOVA_SENHA_FORTE"
Criação de Administrador Direto no Banco (Fallback sem WP-CLI) (emergencial)#
UPDATE wp_users
SET user_pass = MD5('novaSenha123')
WHERE user_login = 'usuario';
Importante: depois do acesso restabelecido, altere novamente a senha pelo painel para que o WordPress regrave hash moderno.
6. Contingências manuais no servidor web#
Se o banco ou o WP-CLI estiverem inacessíveis, use as seguintes alternativas diretamente no terminal:
6.1 mover a pasta física do plugin#
Renomear a pasta do plugin faz o WordPress ignorá-lo no boot:
mv wp-content/plugins/all-in-one-wp-security-and-firewall \
wp-content/plugins/all-in-one-wp-security-and-firewall.bak
6.2 desativar temporariamente o ModSecurity (Apache WAF)#
Se o ModSecurity estiver ativo e disparando falsos positivos na URL do /wp-admin/, você pode validar sua presença e desativá-lo temporariamente:
# Validar se o módulo está carregado no Apache
apache2ctl -M 2>/dev/null | grep security
# Logs de auditoria do ModSecurity
tail -n 50 /var/log/apache2/modsec_audit.log
Se necessário desativar via .htaccess para teste rápido:
<IfModule mod_security.c>
SecRuleEngine Off
</IfModule>
6.3 validar configurações e logs do Nginx#
Se a stack utiliza Nginx, verifique regras de bloqueio estático na configuração:
# Testar integridade sintática das regras do Nginx
nginx -t
# Rastrear se há diretivas de negação de acesso (deny) ou retorno 403
grep -rn "deny\|return 403" /etc/nginx/
# Consultar logs de erros HTTP 403
tail -n 50 /var/log/nginx/access.log | grep 403
7. Headers de proxy/CDN: IP de origem incorreto#
Em servidores que operam atrás de CDNs como Cloudflare ou proxies como o Nginx, os plugins de segurança podem ler o IP do próprio proxy reverso em vez do IP real do administrador. Se o proxy tentar acessar a área de login e errar a credencial, o plugin bloqueará o IP do proxy, bloqueando efetivamente todos os usuários do site.
Garanta que headers como X-Forwarded-For ou CF-Connecting-IP estejam configurados para repassar o IP real do cliente nas opções do WAF.
8. Verificação pós-fix e rollback#
8.1 validação do acesso restabelecido#
Certifique-se de que a API REST e as páginas cruciais estão respondendo corretamente:
# Testar acesso HTTP à área de admin (esperado redirecionamento ou formulário)
curl -I https://domain.com/wp-admin/
# Testar acesso HTTP direto ao formulário de login
curl -I https://domain.com/wp-login.php
# Testar integridade da REST API
curl -I https://domain.com/wp-json/
8.2 plano de rollback seguro#
Se a desativação do plugin comprometer o funcionamento da aplicação ou se você precisar reverter as regras editadas:
# 1. Reativar o plugin desativado
wp plugin activate all-in-one-wp-security-and-firewall
# 2. Restaurar diretório renomeado
mv wp-content/plugins/all-in-one-wp-security-and-firewall.bak \
wp-content/plugins/all-in-one-wp-security-and-firewall
# 3. Restaurar arquivo .htaccess original
cp .htaccess.bak.* .htaccess
9. Script e checklist de diagnóstico completo#
9.1 script de diagnóstico forense (wp-diagnostic.sh)#
Crie este script no diretório do seu WordPress para auditar a saúde da sua instalação:
#!/bin/bash
# wp-diagnostic.sh - Diagnóstico forense do WordPress
# Execute como proprietário dos arquivos ou root
set -euo pipefail
DOMAIN="${1:-localhost}"
WP_PATH="${2:-.}"
echo "=== Diagnóstico WordPress: $DOMAIN ==="
echo ""
# 1. Teste HTTP
echo "[1] Testando conexões HTTP..."
HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" -I "https://$DOMAIN/wp-admin/")
echo " HTTP Status para /wp-admin/: $HTTP_CODE"
if [ "$HTTP_CODE" = "403" ]; then
echo " ⚠️ Alerta: Bloqueio na camada do servidor/WAF (HTTP 403)"
elif [ "$HTTP_CODE" = "200" ]; then
echo " ✅ Status HTTP 200. Se a tela estiver em branco, cheque logs PHP."
fi
# 2. Verificar Core
echo ""
echo "[2] Validando core do WordPress..."
cd "$WP_PATH"
if wp core is-installed 2>/dev/null; then
echo " ✅ Core instalado"
wp core verify-checksums 2>/dev/null || echo " ⚠️ Alerta: Checagem de checksums do core falhou!"
else
echo " ❌ Core não instalado ou banco inacessível."
fi
# 3. Plugins Ativos
echo ""
echo "[3] Principais plugins ativos:"
wp plugin list --status=active --field=name 2>/dev/null | head -n 10
# 4. Verificar .htaccess
echo ""
echo "[4] Auditando .htaccess..."
if [ -f .htaccess ]; then
BLOCKS=$(grep -c "BEGIN" .htaccess)
echo " Blocos identificados: $BLOCKS"
[ "$BLOCKS" -gt 1 ] && echo " ⚠️ Alerta: Blocos duplicados detectados no .htaccess"
else
echo " ℹ️ Arquivo .htaccess não encontrado."
fi
# 5. logs recentes
echo ""
echo "[5] Inspecionando debug.log..."
if [ -f wp-content/debug.log ]; then
tail -n 5 wp-content/debug.log
else
echo " ℹ️ debug.log não encontrado."
fi
echo ""
echo "=== Fim do diagnóstico ==="
9.2 checklist: WordPress admin bloqueado#
Use este checklist operacional para guiar o seu processo de mitigação passo a passo:
- HTTP/Rede:
- [ ] Executar
curl -I https://domain.com/wp-admin/e validar o código HTTP. - [ ] Verificar se há bloqueios estáticos de IPs ou CDN ativas.
- Servidor Web:
- [ ] Inspecionar logs de ModSecurity (
modsec_audit.log). - [ ] Validar sintaxe do Nginx (
nginx -t). - [ ] Monitorar logs de erros do PHP e servidor.
- WordPress Core:
- [ ] Rodar
wp core is-installedewp core verify-checksums. - [ ] Validar valores de URLs no banco via
wp option get siteurlehome. - Plugins:
- [ ] Listar plugins ativos.
- [ ] Desativar plugins de segurança usando
--skip-pluginsse necessário. - [ ] Validar reações reativando plugins individualmente.
- Arquivos:
- [ ] Inspecionar regras duplicadas no
.htaccess. - [ ] Corrigir permissões de pastas (755) e arquivos (644).
- [ ] Garantir o ownership correto do servidor web (ex:
www-data).
10. Considerações Finais e Governança Operacional#
Bloqueios no /wp-admin que ocorrem antes do login não se resolvem com tentativas aleatórias. Resolvem-se com análise metódica por camadas de rede e aplicação, análise forense de logs e uso cirúrgico do WP-CLI.
Seguindo um runbook bem documentado, o tempo de inatividade (MTTR) cai drasticamente e as credenciais críticas permanecem seguras.
Este artigo foi útil?
Deixe uma reação rápida para apoiar o conteúdo:
Este post está licenciado sob CC BY-NC.



Comentários
Participe da discussão abaixo.
0 comentários