Hosting Equipo Avantys 8 min

Seguridad WordPress en VPS: Guía Definitiva

Protege tu WordPress en VPS contra hackers. Hardening, plugins de seguridad, configuración servidor, backups y mejores prácticas.

// Compartir

Seguridad WordPress en VPS: Guía Definitiva
Seguridad WordPress en VPS

WordPress alimenta el 43% de internet. Eso lo convierte en el objetivo número uno de los hackers.

En un VPS tienes control total sobre la seguridad, pero también toda la responsabilidad. Un WordPress mal configurado es una puerta abierta.

Esta guía cubre todas las capas de seguridad: desde el servidor hasta la aplicación.

Por qué WordPress es tan atacado

Las estadísticas

DatoCifra
Sitios WordPress43% de internet
Ataques diarios90.000+ intentos por sitio
Vulnerabilidades plugins98% de los hackeos
Contraseñas débiles8% de los hackeos

Vectores de ataque comunes

  1. Plugins vulnerables: La causa principal
  2. Fuerza bruta: Intentos de login masivos
  3. xmlrpc.php: API antigua muy explotada
  4. Temas nulled: Con malware incluido
  5. Versiones desactualizadas: Vulnerabilidades conocidas

Capas de seguridad

Capas de seguridad para WordPress

La seguridad efectiva tiene múltiples capas:

Capa 1: Servidor (firewall, SSH, actualizaciones)
Capa 2: Web server (Nginx/Apache hardening)
Capa 3: PHP (configuración segura)
Capa 4: WordPress (core, plugins, temas)
Capa 5: Usuario (contraseñas, 2FA)

Capa 1: Seguridad del servidor

Firewall obligatorio

sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow ssh
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable

Guía completa: Firewall en VPS

Fail2ban para WordPress

sudo apt install fail2ban -y

Crear filtro WordPress:

sudo nano /etc/fail2ban/filter.d/wordpress-login.conf
[Definition]
failregex = ^<HOST> .* "POST /wp-login.php
            ^<HOST> .* "POST /xmlrpc.php
ignoreregex =

Crear jail:

sudo nano /etc/fail2ban/jail.local
[wordpress-login]
enabled = true
port = http,https
filter = wordpress-login
logpath = /var/log/nginx/access.log
maxretry = 3
findtime = 300
bantime = 3600
sudo systemctl restart fail2ban

Guía completa: Fail2ban en VPS

Actualizaciones automáticas

sudo apt install unattended-upgrades -y
sudo dpkg-reconfigure unattended-upgrades

Capa 2: Configuración web server

Nginx - Bloquear archivos sensibles

# Bloquear acceso a archivos sensibles
location ~ /\.(htaccess|htpasswd|ini|log|sh|sql)$ {
    deny all;
}

# Bloquear wp-config.php
location ~* wp-config.php {
    deny all;
}

# Bloquear xmlrpc.php (si no lo usas)
location = /xmlrpc.php {
    deny all;
    access_log off;
    log_not_found off;
}

# Bloquear acceso directo a PHP en uploads
location ~* /wp-content/uploads/.*\.php$ {
    deny all;
}

# Bloquear acceso a wp-includes
location ~* /wp-includes/.*\.php$ {
    deny all;
}

# Bloquear readme y license
location ~* (readme|license)\.(html|txt)$ {
    deny all;
}

Nginx - Limitar wp-admin por IP

location /wp-admin {
    allow 203.0.113.5;  # Tu IP
    allow 10.0.0.0/24;  # Red VPN
    deny all;
    
    location ~ \.php$ {
        # config PHP-FPM
    }
}

location = /wp-login.php {
    allow 203.0.113.5;
    allow 10.0.0.0/24;
    deny all;
    
    # config PHP-FPM
}

Nginx - Headers de seguridad

add_header X-Frame-Options "SAMEORIGIN" always;
add_header X-Content-Type-Options "nosniff" always;
add_header X-XSS-Protection "1; mode=block" always;
add_header Referrer-Policy "strict-origin-when-cross-origin" always;
add_header Permissions-Policy "geolocation=(), microphone=(), camera=()" always;

Apache - .htaccess seguro

# Bloquear xmlrpc
<Files xmlrpc.php>
    Order Deny,Allow
    Deny from all
</Files>

# Proteger wp-config
<Files wp-config.php>
    Order Allow,Deny
    Deny from all
</Files>

# Bloquear acceso a includes
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteRule ^wp-admin/includes/ - [F,L]
    RewriteRule !^wp-includes/ - [S=3]
    RewriteRule ^wp-includes/[^/]+\.php$ - [F,L]
    RewriteRule ^wp-includes/js/tinymce/langs/.+\.php - [F,L]
    RewriteRule ^wp-includes/theme-compat/ - [F,L]
</IfModule>

# Deshabilitar listado de directorios
Options -Indexes

# Headers de seguridad
<IfModule mod_headers.c>
    Header set X-Content-Type-Options "nosniff"
    Header set X-Frame-Options "SAMEORIGIN"
    Header set X-XSS-Protection "1; mode=block"
</IfModule>

Capa 3: PHP seguro

php.ini hardening

; Deshabilitar funciones peligrosas
disable_functions = exec,passthru,shell_exec,system,proc_open,popen,curl_exec,curl_multi_exec,parse_ini_file,show_source

; Ocultar versión PHP
expose_php = Off

; Limitar recursos
max_execution_time = 30
max_input_time = 60
memory_limit = 256M
post_max_size = 64M
upload_max_filesize = 64M

; Sesiones seguras
session.cookie_httponly = 1
session.cookie_secure = 1
session.use_strict_mode = 1

; Otros
allow_url_fopen = Off
allow_url_include = Off

PHP-FPM pool seguro

; /etc/php/8.3/fpm/pool.d/wordpress.conf
[wordpress]
user = www-data
group = www-data

listen = /run/php/php8.3-fpm-wordpress.sock

pm = dynamic
pm.max_children = 50
pm.start_servers = 5
pm.min_spare_servers = 5
pm.max_spare_servers = 35

; Seguridad
php_admin_value[disable_functions] = exec,passthru,shell_exec,system
php_admin_flag[allow_url_fopen] = off

Capa 4: WordPress hardening

wp-config.php seguro

<?php
// Claves de seguridad únicas (genera en https://api.wordpress.org/secret-key/1.1/salt/)
define('AUTH_KEY',         'tu-clave-unica-aqui');
define('SECURE_AUTH_KEY',  'tu-clave-unica-aqui');
define('LOGGED_IN_KEY',    'tu-clave-unica-aqui');
define('NONCE_KEY',        'tu-clave-unica-aqui');
define('AUTH_SALT',        'tu-clave-unica-aqui');
define('SECURE_AUTH_SALT', 'tu-clave-unica-aqui');
define('LOGGED_IN_SALT',   'tu-clave-unica-aqui');
define('NONCE_SALT',       'tu-clave-unica-aqui');

// Forzar SSL en admin
define('FORCE_SSL_ADMIN', true);

// Deshabilitar editor de archivos
define('DISALLOW_FILE_EDIT', true);

// Limitar revisiones
define('WP_POST_REVISIONS', 5);

// Deshabilitar actualizaciones automáticas de plugins/temas (gestionar manualmente)
define('AUTOMATIC_UPDATER_DISABLED', false);
define('WP_AUTO_UPDATE_CORE', 'minor');

// Tabla prefix personalizado (no wp_)
$table_prefix = 'wp7x9k_';

// Debug solo en desarrollo
define('WP_DEBUG', false);
define('WP_DEBUG_LOG', false);
define('WP_DEBUG_DISPLAY', false);

Permisos de archivos

# Directorios: 755
find /var/www/wordpress -type d -exec chmod 755 {} \;

# Archivos: 644
find /var/www/wordpress -type f -exec chmod 644 {} \;

# wp-config.php más restrictivo
chmod 600 /var/www/wordpress/wp-config.php

# Propietario
chown -R www-data:www-data /var/www/wordpress

Deshabilitar xmlrpc.php

Si no usas la app móvil de WordPress ni Jetpack:

Opción 1: Nginx (recomendada)

location = /xmlrpc.php {
    deny all;
}

Opción 2: Plugin Instala “Disable XML-RPC-API”

Opción 3: functions.php

add_filter('xmlrpc_enabled', '__return_false');

Ocultar versión WordPress

// functions.php
remove_action('wp_head', 'wp_generator');

function remove_version_strings($src) {
    if (strpos($src, 'ver=')) {
        $src = remove_query_arg('ver', $src);
    }
    return $src;
}
add_filter('style_loader_src', 'remove_version_strings', 9999);
add_filter('script_loader_src', 'remove_version_strings', 9999);

Cambiar URL de login

Con plugin “WPS Hide Login” o manualmente:

// functions.php (básico, mejor usar plugin)
function custom_login_url() {
    return home_url('mi-acceso-secreto');
}
add_filter('login_url', 'custom_login_url');

Limitar intentos de login

Plugin recomendado: Limit Login Attempts Reloaded

O con código:

function check_attempted_login($user, $username, $password) {
    if (get_transient('attempted_login')) {
        $data = get_transient('attempted_login');
        if ($data['tried'] >= 3) {
            $until = get_option('_transient_timeout_attempted_login');
            $time = time_to_go($until);
            return new WP_Error('too_many_tried', sprintf(__('ERROR: Demasiados intentos. Espera %s.'), $time));
        }
    }
    return $user;
}
add_filter('authenticate', 'check_attempted_login', 30, 3);

Capa 5: Usuarios y accesos

Contraseñas fuertes

  • Mínimo 16 caracteres
  • Mayúsculas, minúsculas, números, símbolos
  • Única por sitio
  • Usar gestor de contraseñas

2FA obligatorio

Plugins recomendados:

  • Two Factor Authentication (gratuito)
  • Wordfence (incluye 2FA)
  • Google Authenticator

No usar “admin” como usuario

-- Cambiar nombre de usuario admin
UPDATE wp_users SET user_login = 'nuevo_usuario' WHERE user_login = 'admin';
UPDATE wp_users SET user_nicename = 'nuevo_usuario' WHERE user_nicename = 'admin';

Roles y permisos mínimos

RolPara quién
AdministratorSolo tú
EditorGestores de contenido
AuthorEscritores
ContributorColaboradores externos
SubscriberUsuarios registrados

Nunca des admin a quien no lo necesite.

Plugins de seguridad

Wordfence (recomendado)

  • Firewall aplicación
  • Escaneo malware
  • 2FA
  • Bloqueo de IPs
  • Alertas en tiempo real
Configuración recomendada:
- Firewall: Extended Protection
- Scan: High Sensitivity
- 2FA: Todos los admins
- Login Security: Enable

Sucuri Security

  • Firewall WAF (de pago)
  • Escaneo malware
  • Hardening automático
  • CDN incluido

iThemes Security

  • Hardening automático
  • Detección de cambios
  • 2FA
  • Backups de base de datos

Comparativa

FeatureWordfenceSucuriiThemes
Firewall app✓ GratisPago
WAF cloudPago
Malware scan
2FA
PrecioFree/PremiumFree/PremiumFree/Pro

Recomendación: Wordfence free para empezar.

Backups: tu última defensa

Regla 3-2-1

  • 3 copias de tus datos
  • 2 tipos de almacenamiento diferentes
  • 1 copia offsite (fuera del servidor)

Plugins de backup

UpdraftPlus:

  • Backup automático
  • Restauración fácil
  • Cloud storage (Dropbox, Google Drive, S3)

Configuración recomendada:

  • Archivos: Diario
  • Base de datos: Diario
  • Retención: 14 días
  • Destino: Cloud externo

Backup desde servidor

#!/bin/bash
# /root/scripts/backup-wordpress.sh

FECHA=$(date +%Y%m%d)
WP_DIR="/var/www/wordpress"
BACKUP_DIR="/backups/wordpress"
DB_NAME="wordpress"
DB_USER="wp_user"
DB_PASS="password"

# Backup base de datos
mysqldump -u $DB_USER -p$DB_PASS $DB_NAME | gzip > $BACKUP_DIR/db-$FECHA.sql.gz

# Backup archivos
tar -czf $BACKUP_DIR/files-$FECHA.tar.gz $WP_DIR

# Eliminar backups antiguos (30 días)
find $BACKUP_DIR -mtime +30 -delete

# Sincronizar a cloud (ejemplo con rclone)
rclone sync $BACKUP_DIR remote:backups/wordpress

Guía completa: Backups en VPS

Checklist de seguridad WordPress

Checklist seguridad WordPress

Crítico (hacer hoy)

Tarea
WordPress actualizado
Plugins actualizados
Tema actualizado
Contraseñas fuertes
Backup funcionando
SSL activo

Importante (esta semana)

Tarea
Firewall servidor activo
Fail2ban configurado
xmlrpc.php bloqueado
Plugin seguridad instalado
2FA habilitado
Permisos archivos correctos

Recomendado (este mes)

Tarea
Limitar acceso wp-admin por IP
Cambiar URL de login
Headers de seguridad
Auditoría de plugins
Eliminar temas/plugins sin usar
wp-config.php hardening

Qué hacer si te hackean

1. No entres en pánico

2. Aísla el sitio

# Poner en mantenimiento
echo "<?php header('HTTP/1.1 503 Service Unavailable'); ?>" > /var/www/wordpress/index.php

3. Identifica el problema

# Buscar archivos modificados recientemente
find /var/www/wordpress -type f -mtime -2

# Buscar código sospechoso
grep -r "eval(" /var/www/wordpress
grep -r "base64_decode" /var/www/wordpress

4. Restaura desde backup limpio

5. Cambia todas las contraseñas

  • WordPress admin
  • Base de datos
  • FTP/SFTP
  • Hosting/VPS

6. Actualiza todo

7. Escanea con Wordfence/Sucuri

8. Refuerza seguridad

Preguntas frecuentes

¿Necesito plugin de seguridad si tengo firewall en servidor?

Sí. El firewall del servidor protege a nivel red. Los plugins protegen a nivel aplicación. Son complementarios.

¿Wordfence ralentiza mi sitio?

Puede añadir algo de carga. Usa caché agresivo y considera el firewall cloud de Sucuri para alto tráfico.

¿Debo pagar por seguridad premium?

Para sitios pequeños, las versiones gratuitas son suficientes. Para e-commerce o sitios críticos, considera premium.

¿Con qué frecuencia debo actualizar?

Actualizaciones de seguridad: inmediatamente. Otras: semanalmente, probando primero en staging.

Nuestra recomendación

Mínimo para cualquier WordPress:

  1. Actualizaciones al día
  2. Wordfence free instalado
  3. Backups diarios
  4. 2FA para admins
  5. xmlrpc bloqueado

Para e-commerce/sitios críticos: Añade WAF cloud (Sucuri/Cloudflare Pro) y monitorización 24/7.

¿No tienes tiempo? La administración gestionada incluye seguridad WordPress profesional.


Conclusión

La seguridad de WordPress en un VPS requiere atención en múltiples capas. No basta con un plugin; necesitas servidor seguro, configuración correcta y buenos hábitos.

Implementa este checklist progresivamente. Empieza por lo crítico hoy y completa el resto esta semana.

¿Quieres WordPress seguro sin complicaciones? Explora el hosting WordPress de Avantys con seguridad incluida.


Guías relacionadas


¿Quieres la guía completa con todos los casos de uso?

→ Volver a la guía maestra: Mejor VPS en España 2026

¿Quieres que lo hagamos por ti?

En Avantys gestionamos tu web, hosting y crecimiento digital de punta a punta. Tú a lo importante.

Hablar con Avantys
// Boletín

Suscríbete al boletín

Guías nuevas, sin spam. Cancela cuando quieras.