Contents
Introducción
En la actualidad, los ataques de fuerza bruta y los intentos masivos de acceso no autorizado son amenazas constantes para las aplicaciones web, especialmente aquellas basadas en WordPress. Implementar un plugin de seguridad que detecte y bloquee ataques de login puede proteger tu sitio y tus usuarios. En este artículo se describe de forma detallada cómo diseñar, desarrollar e instalar un plugin de seguridad que limite intentos de acceso, almacene registros y notifique al administrador.
1. Objetivos y requisitos
- Bloquear direcciones IP o nombres de usuario tras un número de intentos fallidos.
- Registrar cada intento fallido con fecha, hora e IP.
- Enviar alerts por correo al administrador.
- Ofrecer una interfaz de configuración sencilla.
Requisitos previos:
- Conocimientos básicos de PHP y WordPress Hooks.
- Un entorno de desarrollo local o de staging.
- Acceso FTP o gestor de archivos al servidor donde alojas WordPress.
2. Arquitectura del plugin
La siguiente tabla resume los componentes principales:
Componente | Responsabilidad |
---|---|
Archivo principal (plugin) | Declaración del plugin, hooks de inicialización. |
Manejador de intentos | Detecta intentos fallidos y lleva el conteo. |
Bloqueador | Impide accesos tras superar el límite. |
Registro y notificaciones | Guarda logs y envía emails al administrador. |
3. Estructura de archivos
Recomendación de árbol de archivos:
- login-blocker.php – Archivo principal.
- includes/
- handler.php – Lógica de conteo de intentos.
- blocker.php – Funciones de bloqueo.
- notifier.php – Envía correos y registra logs.
- admin/
- settings.php – Página de configuración en el panel.
4. Declaración del plugin
ltphp
/
Plugin Name: Login Blocker Security
Plugin URI: https://developer.wordpress.org/plugins/intro/
Description: Bloquea intentos de login después de un número de intentos fallidos y notifica al administrador.
Version: 1.0.0
Author: Tu Nombre
Author URI: https://example.com/
License: GPL2
/
defined(ABSPATH) exit
// Inclusión de archivos
require_once plugin_dir_path(__FILE__) . includes/handler.php
require_once plugin_dir_path(__FILE__) . includes/blocker.php
require_once plugin_dir_path(__FILE__) . includes/notifier.php
// Inicialización
add_action(init, lbs_init_plugin)
function lbs_init_plugin() {
LBS_Handler::setup()
LBS_Blocker::setup()
LBS_Notifier::setup()
}
5. Manejador de intentos fallidos
En includes/handler.php creamos la clase que captura login fallidos:
class LBS_Handler {
const OPTION_KEY = lbs_failed_logins
public static function setup() {
add_action(wp_login_failed, [__CLASS__, on_login_failed], 10, 1)
}
public static function on_login_failed(username) {
ip = _SERVER[REMOTE_ADDR]
attempts = get_transient(self::OPTION_KEY . _{ip}) : 0
attempts
set_transient(self::OPTION_KEY . _{ip}, attempts, HOUR_IN_SECONDS)
if (attempts >= 5) {
LBS_Blocker::block_ip(ip)
LBS_Notifier::notify_admin(ip, username, attempts)
}
}
}
Explicación:
- Usamos transients para almacenar intentos por IP.
- Tras 5 intentos, invocamos bloqueo y notificación.
6. Bloqueo de IP
En includes/blocker.php definimos cómo se impide el acceso:
class LBS_Blocker {
const BLOCK_KEY = lbs_blocked_ips
public static function setup() {
add_action(init, [__CLASS__, enforce_block])
}
public static function block_ip(ip) {
blocked = get_option(self::BLOCK_KEY, [])
if (!in_array(ip, blocked, true)) {
blocked[] = ip
update_option(self::BLOCK_KEY, blocked)
}
}
public static function enforce_block() {
ip = _SERVER[REMOTE_ADDR]
blocked = get_option(self::BLOCK_KEY, [])
if (in_array(ip, blocked, true)) {
wp_die(Acceso denegado. Tu IP ha sido bloqueada por múltiples intentos fallidos., Bloqueo de seguridad, [response =gt 403])
}
}
}
Este método enforce_block se ejecuta en cada carga y detiene el acceso si la IP está en la lista negra.
7. Registro y notificaciones
En includes/notifier.php se envía un correo y se guarda un log:
class LBS_Notifier {
public static function setup() {
// Posible hook adicional para administración
}
public static function notify_admin(ip, username, attempts) {
admin_email = get_option(admin_email)
subject = Alerta de bloqueo de login
message = Se han detectado {attempts} intentos de login fallidos.nIP: {ip}nUsuario: {username}
wp_mail(admin_email, subject, message)
error_log([LBS] IP bloqueada: {ip}, usuario: {username}, intentos: {attempts})
}
}
Recomendación: revisar wp_mail() y configurar SMTP seguro.
8. Panel de configuración
Para ofrecer opciones (umbral, duración de bloqueo), se puede añadir una página en el dashboard usando add_options_page
y campos con settings_api
. No entraremos en detalles aquí, pero recomendamos:
- Registrar opciones con
register_setting
. - Gestionar formularios con
settings_fields
,do_settings_sections
ysubmit_button
.
9. Pruebas y despliegue
- Activar el plugin en un entorno de pruebas.
- Simular varios intentos de login fallido desde la misma IP.
- Verificar que se bloquea la IP y que el mensaje de error es claro.
- Comprobar que las notificaciones llegan al admin_email.
- Revisar logs de errores para asegurar que no hay warnings.
10. Buenas prácticas y mejoras
- Implementar whitelist de IPs confiables.
- Utilizar rate limiting en servidor (OWASP Top Ten recomienda monitorear el flujo de requests).
- Almacenar logs en base de datos propia o servicio externo para análisis profundo.
- Agregar reCAPTCHA u otros mecanismos de validación.
- Permitir desbloqueo automático tras período definido.
Conclusión
Crear un plugin de seguridad que bloquea intentos de login ofrece una capa adicional contra ataques de fuerza bruta. Siguiendo esta guía, dispondrás de un sistema modular, fácil de mantener y extensible. Para profundizar, revisa la documentación oficial de WordPress en WordPress Plugin Developer Handbook y las recomendaciones de OWASP.
|
Acepto donaciones de BAT's mediante el navegador Brave 🙂 |