🛡️ Instalar MySQL / MariaDB en un VPS#
Guía completa y detallada para instalar, asegurar y optimizar MariaDB en un servidor VPS. Este tutorial completo te guía paso a paso para una configuración profesional adecuada para hosting web, aplicaciones empresariales, e-commerce o servidores de juegos.
🎯 Objetivos de la guía#
- ✅ Instalación limpia de MariaDB en Ubuntu/Debian
- 🔒 Seguridad avanzada con autenticación fuerte y aislamiento de servicios
- ⚡ Optimización de rendimiento para uso en producción
- 🔧 Configuración fina adaptada a tu carga de trabajo
- 🛠️ Solución de problemas de las incidencias más comunes
1️⃣ Preparación del sistema#
📦 Actualización completa del sistema#
# Actualizar lista de paquetes sudo apt update # Actualizar todos los paquetes instalados sudo apt upgrade -y
🔧 Instalación de herramientas esenciales#
# Herramientas básicas para administración sudo apt install -y curl wget gnupg2 software-properties-common apt-transport-https ca-certificates
🕒 Configuración de zona horaria#
# Ver hora actual date # Configurar zona horaria (importante para logs) sudo timedatectl set-timezone Europe/Madrid # Verificar configuración timedatectl status
2️⃣ Instalación detallada de MySQL o MariaDB#
Método 1: Desde repositorios Ubuntu/Debian#
# Instalación de MariaDB sudo apt install -y mariadb-server mariadb-client # Iniciar y habilitar sudo systemctl start mariadb sudo systemctl enable mariadb # Verificación sudo systemctl status mariadb
Método 2: Desde repositorio oficial MariaDB (recomendado)#
# Agregar clave GPG de MariaDB sudo apt-key adv --fetch-keys 'https://mariadb.org/mariadb_release_signing_key.asc' # Agregar repositorio curl -LsSO https://r.mariadb.com/downloads/mariadb_repo_setup | bash # Instalación sudo apt update sudo apt install -y mariadb-server
✅ Verificación de instalación#
# Versión instalada mariadb --version # Procesos en ejecución ps aux | grep mysql # Puertos en escucha sudo netstat -tlnp | grep :3306 # Prueba de conexión básica sudo mysql -u root
3️⃣ Seguridad avanzada de la instalación#
🔒 Asistente de seguridad#
sudo mysql_secure_installation
Configuración detallada de opciones:
-
Plugin de validación de contraseñas:
Y
- Nivel de seguridad:
2
(FUERTE) - Longitud mínima: 12 caracteres
- Mezcla de mayúsculas/minúsculas/números/símbolos
- Nivel de seguridad:
-
Contraseña de root: Crear una contraseña fuerte
- Ejemplo:
MiS3gur4P@ssw0rd!2024
- Evitar palabras del diccionario
- Almacenarla en un gestor de contraseñas
- Ejemplo:
-
Eliminar usuarios anónimos:
Y
-
Deshabilitar login remoto de root:
Y
-
Eliminar base de datos de prueba:
Y
-
Recargar privilegios:
Y
4️⃣ Gestión de usuarios y privilegios#
👤 Creación de bases de datos y usuarios locales#
Conectar como root#
sudo mysql -u root -p
Creación de bases de datos#
-- Crear bases de datos CREATE DATABASE app_produccion CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci; CREATE DATABASE app_staging CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
Crear usuarios solo para acceso local#
-- Usuario de aplicación (privilegios limitados) CREATE USER 'usuario_app'@'localhost' IDENTIFIED BY 'AppStr0ng!Pass2024'; GRANT SELECT, INSERT, UPDATE, DELETE ON app_produccion.* TO 'usuario_app'@'localhost'; -- Usuario de respaldo (solo lectura) CREATE USER 'usuario_backup'@'localhost' IDENTIFIED BY 'BackupSecur3!2024'; GRANT SELECT, LOCK TABLES, SHOW VIEW, EVENT, TRIGGER ON app_produccion.* TO 'usuario_backup'@'localhost'; -- Usuario administrador (privilegios extendidos) CREATE USER 'usuario_admin'@'localhost' IDENTIFIED BY 'AdminP0w3r!2024'; GRANT ALL PRIVILEGES ON app_produccion.* TO 'usuario_admin'@'localhost'; GRANT ALL PRIVILEGES ON app_staging.* TO 'usuario_admin'@'localhost'; -- Usuario de monitoreo (privilegios de lectura del sistema) CREATE USER 'usuario_monitor'@'localhost' IDENTIFIED BY 'M0nit0r!Secur3'; GRANT PROCESS, REPLICATION CLIENT ON *.* TO 'usuario_monitor'@'localhost'; -- Aplicar cambios FLUSH PRIVILEGES; -- Verificar usuarios creados SELECT User, Host FROM mysql.user WHERE Host = 'localhost'; EXIT;
5️⃣ Configuración de acceso remoto (opcional)#
⚠️ Advertencia: El acceso remoto presenta riesgos de seguridad. Solo habilitar si es necesario y siempre con restricciones de IP.
🔧 Paso 1: Configuración del servidor MariaDB#
Modificar configuración para escuchar en todas las interfaces#
# Editar archivo de configuración sudo nano /etc/mysql/mariadb.conf.d/50-server.cnf
Encontrar la línea bind-address
y modificarla:
# ANTES (solo acceso local) bind-address = 127.0.0.1 # DESPUÉS (acceso desde todas las interfaces) bind-address = 0.0.0.0
Reiniciar MariaDB para aplicar cambios#
sudo systemctl restart mariadb # Verificar que el servidor escucha en todas las interfaces sudo netstat -tlnp | grep :3306 # Deberías ver: 0.0.0.0:3306 en lugar de 127.0.0.1:3306
🔐 Paso 2: Crear usuarios para acceso remoto#
# Reconectar a MariaDB sudo mysql -u root -p
-- Usuario con IP específica (recomendado) CREATE USER 'admin_remoto'@'192.168.1.100' IDENTIFIED BY 'RemotoStr0ng!2024'; GRANT SELECT, INSERT, UPDATE, DELETE ON app_produccion.* TO 'admin_remoto'@'192.168.1.100'; -- Aplicar cambios FLUSH PRIVILEGES; -- Verificar usuarios remotos SELECT User, Host FROM mysql.user WHERE Host != 'localhost'; EXIT;
🛡️ Paso 3: Configuración del firewall#
# Permitir acceso desde IP específica sudo ufw allow from 192.168.1.100 to any port 3306 # Verificar reglas del firewall sudo ufw status numbered
🧪 Paso 4: Probar conexión remota#
# Desde otro servidor, probar conexión mysql -h 163.5.xxx.xxx -u usuario_remoto -p app_produccion # O con telnet para probar conectividad telnet 163.5.xxx.xxx 3306
6️⃣ Optimización avanzada de rendimiento#
📊 Herramientas de ajuste#
Instalación de MySQLTuner#
# Instalación desde repositorios sudo apt install -y mysqltuner # O descargar última versión wget https://raw.githubusercontent.com/major/MySQLTuner-perl/master/mysqltuner.pl chmod +x mysqltuner.pl # Ejecutar análisis sudo mysqltuner # o sudo perl mysqltuner.pl
7️⃣ Estrategias de respaldo y restauración#
💾 Respaldos con mysqldump#
Script de respaldo automatizado#
# Crear directorio de respaldos sudo mkdir -p /backup/mysql sudo chown mysql:mysql /backup/mysql # Crear script de respaldo sudo nano /usr/local/bin/mysql-backup.sh
#!/bin/bash # Script de respaldo automatizado de MySQL # Configuración BACKUP_DIR="/backup/mysql" MYSQL_USER="usuario_backup" # Reemplazar con tu usuario MYSQL_PASSWORD="BackupSecur3!2024" # Reemplazar con tu contraseña DATE=$(date +%Y%m%d_%H%M%S) RETENTION_DAYS=7 # Crear directorio con fecha mkdir -p "$BACKUP_DIR/$DATE" # Lista de bases de datos a respaldar DATABASES=("app_produccion" "app_staging") for db in "${DATABASES[@]}"; do echo "Respaldando $db..." # Respaldo completo con estructura y datos mysqldump -u $MYSQL_USER -p$MYSQL_PASSWORD \ --single-transaction \ --routines \ --triggers \ --events \ --hex-blob \ --lock-tables=false \ $db > "$BACKUP_DIR/$DATE/${db}_completo.sql" # Comprimir respaldo gzip "$BACKUP_DIR/$DATE/${db}_completo.sql" echo "Respaldo de $db completado: ${db}_completo.sql.gz" done # Respaldar usuarios y privilegios echo "Respaldando usuarios y privilegios..." mysql -u $MYSQL_USER -p$MYSQL_PASSWORD -e "SELECT User, Host FROM mysql.user;" > "$BACKUP_DIR/$DATE/lista_usuarios.txt" # Eliminar respaldos antiguos find $BACKUP_DIR -type d -mtime +$RETENTION_DAYS -exec rm -rf {} + echo "Respaldo completado el $(date)"
# Hacer script ejecutable sudo chmod +x /usr/local/bin/mysql-backup.sh # Probar script sudo /usr/local/bin/mysql-backup.sh
Programar respaldos con cron#
# Editar crontab sudo crontab -e # Agregar estas líneas para respaldos automáticos # Respaldo diario a las 2 AM 0 2 * * * /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup.log 2>&1 # Respaldo completo semanal los domingos a la 1 AM 0 1 * * 0 /usr/local/bin/mysql-backup.sh >> /var/log/mysql-backup-semanal.log 2>&1
🔄 Restauración de respaldos#
Restauración completa de base de datos#
# Descomprimir si es necesario gunzip /backup/mysql/20241201_020000/app_produccion_completo.sql.gz # Restauración mysql -u usuario_admin -p'AdminP0w3r!2024' app_produccion < /backup/mysql/20241201_020000/app_produccion_completo.sql
Restauración selectiva de tabla#
# Extraer solo una tabla del respaldo sed -n '/^-- Table structure for table `mi_tabla`/,/^-- Table structure for table `/p' respaldo.sql > mi_tabla.sql # Restaurar esta tabla específica mysql -u usuario_admin -p app_produccion < mi_tabla.sql
🔍 Monitoreo con herramientas del sistema#
Configuración de Fail2Ban para MySQL#
# Crear filtro para intentos de conexión MySQL sudo nano /etc/fail2ban/filter.d/mysql-auth.conf
[Definition] failregex = ^%(__prefix_line)s.*\[Warning\] Access denied for user '.*'@'<HOST>'.*$ ignoreregex =
# Configuración en jail.local sudo nano /etc/fail2ban/jail.local
[mysql-auth] enabled = true filter = mysql-auth logpath = /var/log/mysql/error.log maxretry = 3 bantime = 3600 findtime = 600
# Reiniciar Fail2Ban sudo systemctl restart fail2ban sudo fail2ban-client status mysql-auth
8️⃣ Solución de problemas comunes#
🚨 Errores de autenticación#
"Access denied for user 'root'@'localhost'"#
# Solución 1: Resetear contraseña de root sudo systemctl stop mysql sudo mysqld_safe --skip-grant-tables & mysql -u root # En MySQL: USE mysql; UPDATE user SET authentication_string=PASSWORD('NuevaContraseña') WHERE User='root'; FLUSH PRIVILEGES; EXIT; # Reiniciar MySQL normalmente sudo systemctl start mysql
🌐 Problemas de conectividad#
Verificación de configuración de red#
# Verificar puertos en escucha sudo netstat -tlnp | grep :3306 # Probar conectividad local telnet localhost 3306 # Verificar reglas de firewall sudo ufw status sudo iptables -L
Diagnósticos de conexión#
-- Ver conexiones activas SHOW PROCESSLIST; -- Ver variables de conexión SHOW VARIABLES LIKE 'max_connections'; SHOW VARIABLES LIKE '%timeout%'; -- Estado de conexiones SHOW STATUS LIKE 'Connections'; SHOW STATUS LIKE 'Threads_connected'; SHOW STATUS LIKE 'Aborted_connects';
🎉 Conclusión#
Tu servidor MySQL/MariaDB ahora está configurado profesionalmente con:
- ✅ Seguridad mejorada - Autenticación fuerte, usuarios dedicados, cifrado
- ✅ Rendimiento optimizado - Configuración fina según tu uso
- ✅ Respaldos confiables - Estrategia automatizada de respaldo/restauración
- ✅ Resolución de errores - Guía completa para problemas comunes
Esta configuración te garantiza una base de datos estable, segura y performante para tus aplicaciones de producción. ¡No olvides mantener tu sistema actualizado y monitorear regularmente el rendimiento!