Phpost

Versión completa: Protección de Login v1.0
Actualmente estas viendo una versión simplificada de nuestro contenido. Ver la versión completa con el formato correcto.
Protección de Login v1.0
Nuevo módulo para Risus Nova 2.0 — PHPost


Protección contra ataques de fuerza bruta en el login. Bloquea automáticamente por IP y por nick tras demasiados intentos fallidos, con bloqueo progresivo y log completo de accesos visible desde el panel de admin.


Capturas
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]
 
[img]Registrate o inicia tu sesión para ver este contenido[/img]


🛡️ Características
 
  • Doble bloqueo — por IP y por nombre de usuario de forma independiente
  • Bloqueo progresivo — 1er bloqueo 15 min, 2do 1 hora, 3er bloqueo y siguientes 24 horas
  • 5 intentos antes de bloquear (configurable en el código)
  • Admin nunca se bloquea
  • Login correcto resetea los contadores
  • Log completo — fecha, IP, nick y resultado de cada intento (guardado 7 días)
  • Panel en el admin — ver intentos y desbloquear manualmente con un clic
  • Aviso al usuario — muestra cuántos intentos le quedan antes del bloqueo
 


📋 Requisitos
 
  • Risus Nova 2.0 instalado y funcionando
  • PHP 8.0+
  • MySQL 5.7+ / MariaDB 10.4+
 


🛠️ Instalación

Paso 1 — Ejecutar el instalador

Sube la carpeta install/ a la raíz del sitio y accede a:
 
Código:
Registrate o inicia tu sesión para ver este contenido

Pulsa Instalar ahora. El instalador creará:
  • w_login_log — registro de todos los intentos de login
  • w_login_bloqueos — bloqueos activos por IP y nick

⚠️ Elimina la carpeta install/ del servidor cuando termine.


Paso 2 — Subir los archivos
 
Código:
inc/class/c.loginlog.php                  →  inc/class/
inc/php/ajax/ajax.loginlog.php            →  inc/php/ajax/
themes/default/css/loginlog.css          →  themes/default/css/
themes/default/templates/modules/
  m.loginlog_admin.tpl                    →  themes/default/templates/modules/

Paso 3 — En ajax.login.php

Abre inc/php/ajax/ajax.login.php y reemplaza el case 'login-user' completo por:

 
Código:
case 'login-user':
            //<---
                $user = $tsCore->setSecure($_POST['nick']);
                $pass = $tsCore->setSecure($_POST['pass']);
                $reme = (($_POST['rem'] ?? '') == 'true') ? true : false;
                //
                if(empty($user) or empty($pass)) echo '0: Faltan datos';
                else echo $tsUser->loginUser($user, $pass, $reme);
            //--->
        break;
 
Cambiar por:
 
Código:
case 'login-user':
    //<---
    $user = $tsCore->setSecure($_POST['nick']);
    $pass = $tsCore->setSecure($_POST['pass']);
    $reme = (($_POST['rem'] ?? '') == 'true') ? true : false;
    $ip   = $tsCore->getIP();

    if (empty($user) || empty($pass)) {
        echo '0: Faltan datos';
        break;
    }

    // ── Protección login ──
    require_once TS_CLASS . 'c.loginlog.php';
    $tsLL = new tsLoginLog();

    $bloqueo = $tsLL->estaBloqueado($user, $ip);
    if ($bloqueo) {
        $tiempo = $tsLL->formatearTiempo($bloqueo['faltan']);
        echo '0: Demasiados intentos fallidos. Inténtalo de nuevo en ' . $tiempo . '.';
        break;
    }

    $resultado = $tsUser->loginUser($user, $pass, $reme);

    if ($resultado === TRUE || is_numeric($resultado)) {
        $tsLL->registrar($user, $ip, true);
        $tsLL->resetear($user, $ip);
        echo $resultado;
    } else {
        $tsLL->registrar($user, $ip, false);
        $info = $tsLL->procesarFallo($user, $ip);
        $restantes = $info['restantes'];
        if ($restantes > 0) {
            echo $resultado . ' (' . $restantes . ' intento' . ($restantes != 1 ? 's' : '') . ' restante' . ($restantes != 1 ? 's' : '') . ')';
        } else {
            echo '0: Cuenta bloqueada temporalmente por seguridad.';
        }
    }
    // ────────────────────
    //--->
break;

Paso 4 — Panel en el admin (opcional)

Para ver el log desde el panel de admin añade en la plantilla t.admin.pl arriba de:

Código:
{/if}
 

Código:
{elseif $tsAction == 'loginlog'}
                                {include file='admin_mods/m.loginlog_admin.tpl'}

En admin.php buscar:
 
Código PHP:
} elseif($action == 'feed'){ 


Agregar antes:
 
Código:
} elseif($action == 'loginlog'){
    require_once TS_CLASS . 'c.loginlog.php';
    $tsLL = new tsLoginLog();
    $smarty->assign('tsLoginLog', $tsLL->getLog());
    $smarty->assign('tsBloqueos', $tsLL->getBloqueos());


En m.admin_sidemenu.tpl buscar:
 
Código PHP:
<h4>Usuarios</h4>
<
ul class="admin-nav-list">
<
li id="a_users"><a href="{$tsConfig.url}/admin/users"><span class="nav-icon">👤</spanUsuarios</a></li>
<
li id="a_sesiones"><a href="{$tsConfig.url}/admin/sesiones"><span class="nav-icon">🔑</spanSesiones</a></li>
<
li id="a_nicks"><a href="{$tsConfig.url}/admin/nicks"><span class="nav-icon">🆔</spanNicks</a></li>
<
li id="a_rangos"><a href="{$tsConfig.url}/admin/rangos"><span class="nav-icon">💎</spanRangos</a></li>
</
ul


Debajo agregar:
 
Código PHP:
<h4>Seguridad</h4>
<
ul class="admin-nav-list">
<
li id="a_loginlog"><a href="{$tsConfig.url}/admin/loginlog"><span class="nav-icon">🛡️</spanProtección Login</a></li>
</
ul


Paso 5 — Borrar la caché

Borra el contenido de la carpeta /cache/ del sitio.


🗑️ Desinstalar
 
Código:
DROP TABLE IF EXISTS w_login_log;
DROP TABLE IF EXISTS w_login_bloqueos;

Elimina los archivos subidos y restaura el case 'login-user' original en ajax.login.php.

 
Descarga

Mediafire
http://Registrate o inicia tu sesión par... contenido

Google Drive
http://Registrate o inicia tu sesión par... contenido



¿Tienes dudas o encuentras algún problema? Déjalo en los comentarios.