1. Home
  2. Aplicaciones y CMS
  3. Wordpress
  4. Proteccion basica DDoS al index.php en WordPress

Proteccion basica DDoS al index.php en WordPress

🛡️ Protección de Emergencia contra Ataques DDoS en WordPress

Un ataque DDoS a un sitio WordPress es, lamentablemente, cada vez más común. Este tipo de ataque de saturación consiste en miles de «visitas» falsas desde distintas partes del mundo que sobrecargan tu servidor, consumiendo todos los recursos y evitando que los visitantes reales puedan acceder a tu sitio.

La Solución Recomendada vs. La Solución de Emergencia

La mejor solución a largo plazo para proteger tu sitio es utilizar un servicio como Cloudflare. Sin embargo, si estás bajo ataque en este preciso momento y necesitas una medida de contención inmediata, este tutorial te enseñará a crear una barrera de verificación manual (un «captcha») para frenar el ataque.

Esta técnica es especialmente útil cuando el ataque se concentra en saturar el archivo principal de tu web, el index.php.

⚠️ ¡Importante! Antes de Empezar

  • Haz una copia de seguridad: Antes de modificar cualquier archivo, es fundamental que hagas una copia de seguridad de tu archivo index.php actual. Un error podría dejar tu sitio inaccesible.
  • Necesitarás acceso a tus archivos: Estos pasos se realizan utilizando el «Administrador de Archivos» de tu panel de control (cPanel o DirectAdmin).

Implementando la Protección Paso a Paso

  1. Accede al Administrador de Archivos de tu panel de control y navega a la carpeta raíz de tu sitio WordPress (normalmente es public_html).
  2. Haz una copia de seguridad: Busca el archivo index.php, haz clic derecho sobre él y selecciona «Copiar» o «Copy». Nombra a la copia index.php.bak. Así tendrás un respaldo seguro.
  3. Renombra el archivo original: Ahora, renombra el index.php original a wp-index.php. Este es el archivo real de WordPress que queremos proteger.
  4. Crea el nuevo archivo de verificación: Crea un archivo completamente nuevo en la misma carpeta y llámalo index.php.
  5. Pega y configura el código: Abre el nuevo index.php que acabas de crear, pega el código que te proporcionamos a continuación y, muy importante, personaliza las opciones de configuración como te explicamos en el siguiente punto.

⚙️ Configurando el Código de Protección

Dentro del código, hay una sección llamada // --- CONFIGURACIÓN --- que debes editar para que se ajuste a tu sitio:

  • $admin_ips: Esta es la parte más importante. Añade tu propia dirección IP aquí para que tú y tu equipo nunca vean la pantalla de verificación. Puedes saber cuál es tu IP buscando en Google «what is my ip«.
  • $logo_path: Si quieres que tu logo aparezca en la página de verificación, sube tu logo a la web y pega la URL completa aquí. Por ejemplo: 'https://[su-dominio.com]/logo.png'.
  • $site_name: Escribe el nombre de tu sitio web. Aparecerá en el título de la pestaña del navegador.
<?php
// Inicia la sesión para recordar al usuario verificado y los intentos.
session_start();

// --- CONFIGURACIÓN ---
// Añade tu IP aquí para saltarte siempre la verificación.
// Puedes encontrar tu IP buscando en Google "what is my ip".
$admin_ips = ['TU_IP_AQUI', 'OTRA_IP_SI_ES_NECESARIO']; 

// Ruta al logo de tu sitio web. Déjalo en blanco ('') si no quieres usar uno.
$logo_path = ''; 

// Nombre de tu sitio web para el título de la página.
$site_name = 'El Nombre de mi Sitio Web';
// --------------------


// --- LISTA BLANCA (WHITELIST) ---
// User agents de bots conocidos que queremos dejar pasar para no afectar el SEO.
$whitelisted_user_agents = ['Googlebot', 'Bingbot', 'Slurp', 'DuckDuckBot', 'Baiduspider'];
$user_agent = $_SERVER['HTTP_USER_AGENT'] ?? '';

foreach ($whitelisted_user_agents as $bot) {
    if (stripos($user_agent, $bot) !== false) {
        $_SESSION['is_human'] = true; // Lo marcamos como "humano" para futuras visitas en la misma sesión.
        require_once 'wp-index.php';
        exit();
    }
}

// Revisa si la IP del visitante está en la lista de administradores.
if (in_array($_SERVER['REMOTE_ADDR'], $admin_ips)) {
    require_once 'wp-index.php';
    exit();
}
// ---------------------------------


// Si el usuario ya está verificado en la sesión, carga WordPress.
if (isset($_SESSION['is_human']) && $_SESSION['is_human'] === true) {
    require_once 'wp-index.php';
    exit();
}

// --- LÓGICA DEL CAPTCHA Y SEGURIDAD ---
$error = '';
// Inicializa el contador de intentos fallidos si no existe.
if (!isset($_SESSION['failed_attempts'])) {
    $_SESSION['failed_attempts'] = 0;
}

// Si se ha superado el límite de intentos, muestra un mensaje y no proceses más.
if ($_SESSION['failed_attempts'] >= 3) {
    http_response_code(429); // Too Many Requests
    $error = 'Has superado el número de intentos permitidos. Por favor, inténtalo de nuevo más tarde.';
} 
// Si el formulario fue enviado
elseif ($_SERVER['REQUEST_METHOD'] === 'POST') {
    // 1. Verificación de Honeypot: si el campo oculto tiene algo, es un bot.
    if (!empty($_POST['contact_email'])) {
        http_response_code(403);
        die('Acceso denegado.');
    }

    // 2. Verificación de tiempo: si se envió en menos de 2 segundos, es un bot.
    $time_submitted = time();
    if (isset($_SESSION['form_load_time']) && ($time_submitted - $_SESSION['form_load_time']) < 2) {
        http_response_code(403);
        die('Acceso denegado.');
    }

    // 3. Verificación de la respuesta del CAPTCHA.
    if (isset($_POST['captcha_answer'], $_SESSION['captcha_sum'])) {
        if ($_POST['captcha_answer'] == $_SESSION['captcha_sum']) {
            // Respuesta correcta: marca al usuario como humano y resetea los intentos.
            $_SESSION['is_human'] = true;
            $_SESSION['failed_attempts'] = 0;
            unset($_SESSION['captcha_sum'], $_SESSION['captcha_question'], $_SESSION['form_load_time']); // Limpia la sesión
            header('Location: ' . $_SERVER['REQUEST_URI']);
            exit();
        } else {
            // Respuesta incorrecta: incrementa el contador de fallos.
            $_SESSION['failed_attempts']++;
            $error = 'Respuesta incorrecta. Por favor, intenta de nuevo.';
        }
    }
}

// Genera una nueva pregunta si no existe una o si la página se recarga.
$num1 = rand(1, 9);
$num2 = rand(1, 9);
$_SESSION['captcha_question'] = "¿Cuánto es $num1 + $num2?";
$_SESSION['captcha_sum'] = $num1 + $num2;
// Guarda el tiempo en que el formulario fue cargado.
$_SESSION['form_load_time'] = time();

?>
<!DOCTYPE html>
<html lang="es">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Verificación de seguridad | <?php echo htmlspecialchars($site_name); ?></title>
    <link rel="preconnect" href="https://fonts.googleapis.com">
    <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
    <link href="https://fonts.googleapis.com/css2?family=Roboto:wght@400;700&display=swap" rel="stylesheet">
    <style>
        :root {
            --primary-color: #0073aa; /* Color primario (similar al de WordPress) */
            --background-color: #f0f2f5;
            --container-bg: #ffffff;
            --text-color: #333;
            --error-color: #d9534f;
        }
        body {
            font-family: 'Roboto', sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            height: 100vh;
            margin: 0;
            background-color: var(--background-color);
            color: var(--text-color);
        }
        .container {
            padding: 40px;
            background-color: var(--container-bg);
            border-radius: 8px;
            box-shadow: 0 4px 12px rgba(0,0,0,0.1);
            text-align: center;
            max-width: 400px;
            width: 90%;
        }
        .logo {
            max-width: 150px;
            margin-bottom: 20px;
        }
        h1 {
            margin-top: 0;
            font-size: 1.5em;
        }
        p {
            margin-bottom: 20px;
        }
        form label {
            font-weight: 700;
            margin-bottom: 10px;
            display: block;
        }
        /* Estilo para el campo trampa (Honeypot) - ¡No lo borres! */
        .honeypot-field {
            opacity: 0;
            position: absolute;
            top: 0;
            left: 0;
            height: 0;
            width: 0;
            z-index: -1;
        }
        input[type="text"] {
            padding: 12px;
            border: 1px solid #ccc;
            border-radius: 4px;
            width: 80px; /* Ancho justo para la respuesta */
            text-align: center;
            font-size: 1.1em;
        }
        input[type="submit"] {
            padding: 12px 25px;
            background-color: var(--primary-color);
            color: #fff;
            border: none;
            border-radius: 4px;
            cursor: pointer;
            font-size: 1em;
            font-weight: 700;
            transition: background-color 0.3s;
        }
        input[type="submit"]:hover {
            background-color: #005a87;
        }
        .error {
            color: var(--error-color);
            margin-top: 15px;
            font-weight: 700;
        }
    </style>
</head>
<body>
    <div class="container">
        <?php if ($logo_path): ?>
            <img src="<?php echo htmlspecialchars($logo_path); ?>" alt="Logo de <?php echo htmlspecialchars($site_name); ?>" class="logo">
        <?php endif; ?>
        
        <h1>Verificación de Seguridad</h1>

        <?php if ($_SESSION['failed_attempts'] >= 3): ?>
            <p class="error"><?php echo $error; ?></p>
        <?php else: ?>
            <p>Para proteger el sitio contra actividad automatizada, por favor, responde la siguiente pregunta.</p>
            <form method="post" action="">
                <label for="captcha_answer"><?php echo $_SESSION['captcha_question']; ?></label>
                
                <div class="honeypot-field">
                    <label for="contact_email">Email</label>
                    <input type="email" name="contact_email" id="contact_email" tabindex="-1" autocomplete="off">
                </div>
                
                <input type="text" name="captcha_answer" id="captcha_answer" required autofocus inputmode="numeric" pattern="[0-9]*">
                <br><br>
                <input type="submit" value="Verificar Acceso">
            </form>
            <?php if ($error): ?>
                <p class="error"><?php echo $error; ?></p>
            <?php endif; ?>
        <?php endif; ?>
    </div>
</body>
</html>

✅ ¿Cómo Funciona y Qué Verán tus Visitantes?

¡Listo! Con estos cambios, la situación será la siguiente:

  • Cualquier visitante nuevo (o bot de ataque) no cargará tu WordPress. En su lugar, verá una página simple con una pregunta matemática. Esto consume una cantidad mínima de recursos del servidor.
  • Una vez que un visitante humano resuelve la suma, el sistema lo recordará y no le volverá a pedir la verificación durante su sesión de navegación.
  • Los bots de buscadores importantes (Google, Bing, etc.) están en una lista blanca para que puedan indexar tu sitio sin problemas y no afectar tu SEO.

Esta es una excelente medida de contención para recuperar el control de tu sitio. Una vez que el ataque haya cesado, te recomendamos investigar e implementar una solución permanente como Cloudflare.

Updated on 8 de octubre de 2025

Was this article helpful?

Related Articles

Leave a Comment