Seguridad en WP: seguridad de wp-admin | cambiar la URL de acceso, limitar los intentos de inicio de sesión y XML-RPC

Aviso de afiliados v3.1
Aviso de afiliados v3.2 (móvil)

La seguridad de wp-admin son los ajustes que frenan los ataques de fuerza bruta que llegan por el panel de administración y la pantalla de acceso de WordPress. Al revisar los registros de acceso de un servidor Nginx + Apache con varios sitios WordPress, las solicitudes automÔticas a xmlrpc.php seguían llegando incluso después de cambiar la URL de acceso, así que también apliqué un límite de velocidad en el servidor.

1ļøāƒ£ Por quĆ© atacan wp-admin y wp-login.php

Que la dirección del panel de WordPress sea conocida es un punto débil, pero se puede compensar reforzando la seguridad. Todos los sitios WordPress usan el mismo /wp-admin/ y [wp-login.php], y al abrir /wp-admin/ sin sesión iniciada se pasa a la pantalla de acceso de [wp-login.php].

Los ataques llegan como fuerza bruta, probando una y otra vez usuarios y contraseñas en esta pantalla de acceso. Por eso, en la seguridad de wp-admin, frenar los intentos de acceso va antes que ocultar la dirección.

Dos entradas al acceso de WordPress
Acceso desde el navegador
/wp-admin/
Sin sesión, redirige a la pantalla de acceso (302)
wp-login.php
Pantalla de acceso · usuario y contraseña
Apps · solicitudes automÔticas
xmlrpc.php
Envƭa usuario y contraseƱa en una solicitud POST sin pantalla de acceso
No pasa por la pantalla de acceso
system.multicall prueba varias contraseñas en una solicitud · la dirección no cambia aunque cambies la URL de acceso
Misma comprobación de usuario y contraseña
Ambas entradas comprueban la cuenta con la misma función de autenticación de WordPress
Los ataques de fuerza bruta entran por la entrada que estƩ abierta. Cambiar la URL de acceso solo afecta a la entrada de arriba, asƭ que xmlrpc.php hay que cerrarlo o limitar sus solicitudes por separado.

2ļøāƒ£ Efecto y lĆ­mites de cambiar la URL de acceso

Al cambiar la URL de acceso con un plugin de seguridad, el [wp-login.php] predeterminado devuelve un 404, y los ataques automÔticos que insisten en la dirección por defecto no llegan a la pantalla de acceso. La nueva dirección hay que comunicarla aparte a quien tenga una cuenta de administrador.

🧭 Entradas al acceso de WordPress
Diagrama explicativo
⬜ Sin plugin
šŸ›”ļø Hide My WP
🚪 Entrada de acceso
/wp-login.php · /wp-admin/Misma dirección en todos los WordPress
Pantalla de acceso404
/newloginDirección cambiada · solo la conocen los administradores
Pantalla de acceso
POST /xmlrpc.phpComprueba la contraseƱa sin pantalla de acceso
Responde a la comprobación de contraseñaDesactivado 405
Medido en un sitio de prueba · solicitudes sin sesión
→
šŸ¤– Ataques automĆ”ticos
Entradas donde se pueden probar contraseñas en una dirección conocida
2
1
Ninguna
Sin plugin, las contraseƱas se pueden probar en dos sitios: el mismo [wp-login.php] de todos los WordPress y [xmlrpc.php], que comprueba contraseƱas sin pantalla de acceso.
Al cambiar la URL de acceso, [wp-login.php] y /wp-admin/ devuelven 404, pero [xmlrpc.php] sigue respondiendo si el usuario y la contraseƱa son correctos.
Si ademÔs desactivas XML-RPC, las solicitudes de acceso a [xmlrpc.php] terminan con una respuesta de que el servicio XML-RPC estÔ desactivado, y ya no se pueden probar contraseñas en una dirección conocida.

Este método requiere poco trabajo, pero si olvidas la nueva dirección no podrÔs entrar al panel y tendrÔs que renombrar la carpeta de ese plugin por FTP o con un gestor de archivos para desactivarlo. En un sitio que administran varias personas, conviene anotar la dirección en un solo lugar.

3ļøāƒ£ Limitar los intentos de acceso y la verificación en dos pasos

Aunque cambies la URL de acceso, si la nueva dirección se conoce, los intentos de adivinar contraseñas continúan. El núcleo de WordPress no limita los inicios de sesión fallidos, así que por muchas contraseñas erróneas que se introduzcan, vuelve a abrirse la misma pantalla.

🧭 Limitar intentos de acceso y verificación en dos pasos
Diagrama explicativo
⬜ Sin plugin
šŸ›”ļø Plugin de seguridad
šŸ”‘ Accesos desde la misma IP
1.ºContraseña incorrecta
Otra vez la pantalla de accesoQuedan 3
2.ºContraseña incorrecta
Otra vez la pantalla de accesoQuedan 2
3.ºContraseña incorrecta
Otra vez la pantalla de accesoQueda 1
4.ºContraseña incorrecta
Otra vez la pantalla de accesoBloqueo de 20 min
5.ºBloqueadoContraseña incorrectaAcceso · solicitudes XML-RPC
Otra vez la pantalla de accesoxmlrpc.php tambiƩn 403
Introducir contraseƱaContraseƱa correcta
Pantalla del código
Authentication Code6 dígitos de la app de autenticación · cambia cada 30 s
Administración
Atacante que solo conoce la contraseñaNo conoce el código
Se queda en la pantalla del código
Medido en un sitio de prueba Ā· solicitudes seguidas desde la misma IP
→
šŸ¤– Ataques automĆ”ticos
¿Se pueden seguir probando contraseñas?
Sin lĆ­mite
Bloqueo al 4.Āŗ
Se detiene en el código
Sin plugin, aunque se introduzca una contraseƱa incorrecta seis veces desde la misma IP, cada vez vuelve a abrirse la misma pantalla de acceso.
Con el límite de intentos activo, cada fallo muestra los intentos que quedan, y al 4.º fallo esa IP no puede iniciar sesión durante 20 minutos. Mientras dura el bloqueo, las solicitudes a xmlrpc.php también terminan en 403.
Con la verificación en dos pasos activa, aunque la contraseña sea correcta, el panel solo se abre tras introducir el [Authentication Code] de 6 dígitos que la app de autenticación genera cada 30 segundos.

Un plugin de límite de intentos bloquea durante un tiempo la IP que supera el número permitido, y la verificación en dos pasos pide ademÔs un código de la app de autenticación del móvil aunque la contraseña sea correcta. Al activarla, guarda también los códigos de respaldo por si pierdes el móvil.

4ļøāƒ£ Cerrar xmlrpc.php

[xmlrpc.php] es una segunda entrada que recibe usuario y contraseƱa sin pasar por la pantalla de acceso, y con el mƩtodo [system.multicall] puede probar varias contraseƱas en una sola solicitud.

Los registros de acceso de un servidor Nginx + Apache con varios sitios WordPress mostraron 2.250 solicitudes POST a [xmlrpc.php] entre las 0:00 y las 9:50 del 13 de octubre. Llegaron desde 22 IP y su User-Agent se hacĆ­a pasar por Jetpack y WordPress.com.

Si no usas la app móvil de WordPress ni Jetpack, bloquea las solicitudes a [xmlrpc.php] en la configuración de Nginx o usa el ajuste para desactivar XML-RPC de un plugin de seguridad.

# Dentro del bloque server — rechazar solicitudes a xmlrpc.php
location = /xmlrpc.php {
    deny all;
}

Con este ajuste, las solicitudes GET y POST a [xmlrpc.php] terminan todas en 403 sin llegar a PHP. La opción de desactivar XML-RPC de un plugin de seguridad solo rechaza las solicitudes que requieren acceso y el archivo sigue respondiendo, así que para reducir también las ejecuciones de PHP conviene bloquearlo en Nginx.

5ļøāƒ£ Bloquear en el servidor: restricción de IP para administrar y lĆ­mite de velocidad

Si solo administras desde una IP fija, permitir [wp-login.php] y /wp-admin/ únicamente a esa IP en Nginx es el método mÔs fiable. No sirve si la IP de tu casa u oficina cambia a menudo.

Bloquear todo /wp-admin/ puede parecer suficiente, pero funciones del lado del visitante como la bĆŗsqueda o el carrito suelen enviar solicitudes a [admin-ajax.php], asĆ­ que ese archivo debe quedar abierto.

# Dentro del bloque server — encima del location de PHP
location = /wp-login.php {
    allow 203.0.113.10;   # IP fija desde la que administras
    deny all;
    # Copia aquí debajo la configuración del location de PHP
}

Si abres [wp-login.php] desde una IP distinta de la permitida, sale un 403; desde la IP permitida se abre la pantalla de acceso. Dentro del location tienes que copiar tal cual la configuración de PHP del sitio (fastcgi_pass, etc.) para que la pantalla de acceso funcione con normalidad.

Si no puedes fijar la IP, puedes aplicar un límite de velocidad a las solicitudes PHP de visitantes sin sesión; el proceso de limitarlas a 30 por minuto para que las solicitudes automÔticas no acaparen los recursos del servidor se explica en aviso de php-fpm max_children (artículo aparte).

# Bloque http — contar por IP solo las solicitudes sin cookie de sesión
map $http_cookie $php_anon_key {
    default                 $binary_remote_addr;
    "~*wordpress_logged_in" "";
}
limit_req_zone $php_anon_key zone=php_anon:10m rate=30r/m;

# Dentro del location de PHP
limit_req zone=php_anon burst=60 nodelay;
limit_req_status 429;

Cuando una IP sin sesión envía solicitudes PHP seguidas, se atienden hasta la 61.ª y después se devuelve 429; las solicitudes con cookie de sesión no cuentan. Si la caché de pÔginas responde sin pasar por PHP, la navegación normal de los visitantes no llega a este límite.

ā„¹ļø Aviso de afiliados
El contenido de este sitio incluye enlaces de afiliado. Cuando un visitante compra un producto o servicio a travĆ©s de uno de ellos, el sitio recibe una comisión del vendedor. El importe que paga el comprador(baja durante las promociones ↓)no aumenta. Los precios, descuentos y existencias publicados corresponden al momento de redacción y pueden variar, asĆ­ que confĆ­rmalos con el vendedor antes de comprar. Los productos se eligen y evalĆŗan con criterios propios, y las comisiones no influyen en el orden ni en el contenido de las reseƱas.

Deja una respuesta

Tu dirección de correo electrónico no serÔ publicada. Los campos obligatorios estÔn marcados con *

Demuestra que eres humano: 10   +   9   =