Primeros 10 pasos tras comprar un VPS: seguridad
Unos minutos después de que un servidor nuevo reciba una IP pública, ya hay quien intenta adivinar sus contraseñas. A continuación tienes diez pasos que en una hora cierran los agujeros más habituales: comandos para Ubuntu y Debian, las diferencias para AlmaLinux y Rocky Linux y las comprobaciones sin las que es fácil quedarte sin acceso a tu propio servidor.
El servidor que acabas de pagar ya es visible para todo internet. Los bots recorren las direcciones una tras otra e intentan entrar por SSH como root con contraseñas populares, así que los primeros intentos ajenos aparecen en el log en la misma hora. La buena noticia es que contra los ataques masivos protegen cosas sencillas: acceso solo por clave, puertos innecesarios cerrados y actualizaciones. Todo lo que sigue se hace una sola vez, en más o menos una hora, y mejor antes de que el servidor tenga una web y datos.
Los comandos son para Ubuntu y Debian; las diferencias para AlmaLinux y Rocky Linux se indican aparte. Ejecútalos como root o con sudo.
Antes de empezar: un acceso de reserva
Busca en el panel del proveedor la consola del servidor: se llama VNC, consola KVM o consola de emergencia y muestra la pantalla del servidor directamente en el navegador. Con ella puedes entrar aunque SSH ya no te deje. Mientras cambias la configuración de acceso, mantén abierta la sesión SSH actual y comprueba cada cambio en una segunda ventana. Así un error de configuración te cuesta un par de minutos y no una reinstalación del sistema.
1. Actualiza el sistema
Los proveedores preparan las plantillas de sistema con antelación, y en el momento de instalarlas a menudo acumulan una decena de parches de seguridad sin aplicar.
apt update && apt full-upgrade -y # Ubuntu, Debian
dnf upgrade -y # AlmaLinux, Rocky Linux
Si se ha actualizado el kernel, reinicia el servidor. En Ubuntu y Debian lo indica el archivo /var/run/reboot-required: si existe, hace falta reiniciar.
2. Crea un usuario propio
Trabajar siempre como root es incómodo y peligroso: cualquier errata se ejecuta con todos los permisos, y el nombre root lo conocen todos los bots. Crea tu usuario y dale permiso para usar sudo:
adduser deploy
usermod -aG sudo deploy # Ubuntu, Debian
usermod -aG wheel deploy # AlmaLinux, Rocky Linux
En AlmaLinux y Rocky Linux el comando adduser no pregunta nada y la contraseña se define aparte: passwd deploy. Elige cualquier nombre, salvo los obvios admin y user.
3. Entra con una clave SSH
A diferencia de una contraseña, una clave no se puede adivinar por fuerza bruta. Crea el par de claves en tu ordenador, no en el servidor, y copia la parte pública al servidor:
ssh-keygen -t ed25519 -C "laptop"
ssh-copy-id deploy@IP_DEL_SERVIDOR
Windows 10 y 11 traen el cliente OpenSSH integrado, pero no ssh-copy-id. En ese caso abre el archivo .pub y pega su línea en el servidor en /home/deploy/.ssh/authorized_keys; la carpeta .ssh debe tener permisos 700, el archivo 600, y el propietario debe ser el propio usuario. Muchos proveedores permiten añadir la clave ya al hacer el pedido, y entonces ya está en la cuenta de root.
Comprueba en una ventana nueva que el acceso funciona sin contraseña y que sudo está disponible: ssh deploy@IP_DEL_SERVIDOR y después sudo -v. Solo entonces pasa al siguiente paso.
4. Prohíbe el acceso con contraseña y como root
Lo más cómodo es no editar el archivo principal, sino poner tu configuración en un archivo aparte dentro de /etc/ssh/sshd_config.d/. Un detalle importante: para cada parámetro sshd toma el primer valor que encuentra, y los archivos de esa carpeta los lee por orden alfabético. En las imágenes de Ubuntu para la nube a veces hay un archivo 50-cloud-init.conf con la línea PasswordAuthentication yes, así que dale a tu archivo un número menor que 50, por ejemplo /etc/ssh/sshd_config.d/10-hardening.conf:
PermitRootLogin no
PasswordAuthentication no
KbdInteractiveAuthentication no
Comprueba la sintaxis y qué valores aplicará realmente el servidor, y luego recarga la configuración:
sshd -t && sshd -T | grep -Ei 'permitrootlogin|passwordauthentication'
systemctl reload ssh # Ubuntu, Debian
systemctl reload sshd # AlmaLinux, Rocky Linux
No cierres la sesión antigua hasta que, en una segunda ventana, entres con tu usuario y tu clave. Un intento de entrar como root debe ser rechazado.
No es obligatorio cambiar el puerto de SSH del 22 a otro. Eso elimina del log casi todos los intentos automáticos de acceso, pero la protección la da la clave, no el número de puerto. Si aun así lo cambias, abre primero el nuevo puerto en el firewall. En Ubuntu 22.10 y posteriores SSH se inicia mediante un socket de systemd, y después de cambiar Port hay que ejecutar systemctl daemon-reload y systemctl restart ssh.socket; si no, el servidor seguirá escuchando en el 22.
5. Activa el firewall
La regla es sencilla: se prohíben todas las conexiones entrantes salvo las que van a servicios que deben ser visibles desde fuera. Para una web, eso es SSH, 80 y 443. En Ubuntu es cómodo ufw; en Debian hay que instalarlo con apt install ufw:
ufw default deny incoming
ufw default allow outgoing
ufw allow OpenSSH
ufw allow 80,443/tcp
ufw enable
ufw status verbose
El orden importa: primero permite SSH y después actívalo. En AlmaLinux y Rocky Linux ya funciona firewalld, y SSH está permitido por defecto; los puertos web se abren así:
firewall-cmd --permanent --add-service=http --add-service=https
firewall-cmd --reload
firewall-cmd --list-all
Si en el servidor va a haber Docker, ten en cuenta una particularidad: escribe sus propias reglas de iptables, y un puerto publicado de un contenedor, por ejemplo -p 3306:3306, queda accesible desde internet aunque ufw no lo permita. Publica los puertos de servicio solo en la dirección local: -p 127.0.0.1:3306:3306. Los planes para contenedores están en la selección VPS para Docker.
Muchos proveedores tienen además en el panel un firewall de red delante del servidor. No sustituye al del sistema, pero es útil como segunda capa. La protección contra DDoS es un servicio aparte a nivel de la red del proveedor; los planes que la incluyen están en la selección VPS con protección DDoS.
6. Instala fail2ban
fail2ban lee los logs y bloquea temporalmente las direcciones que fallan una y otra vez al iniciar sesión. Con acceso solo por clave sirve sobre todo para descargar el log, pero también es útil para otros servicios: el panel de control, el correo o la página de acceso de la web.
apt install fail2ban python3-systemd
Escribe tu configuración en /etc/fail2ban/jail.local, no en jail.conf, que se sobrescribe al actualizar:
[sshd]
enabled = true
backend = systemd
maxretry = 5
bantime = 1h
La línea backend = systemd hace falta en Debian 12 y posteriores: allí no existe por defecto el archivo /var/log/auth.log, el registro de accesos vive en journald, y sin esa línea fail2ban no encuentra qué leer. Sin configuración propia, bloquea una dirección durante 10 minutos tras 5 intentos fallidos en 10 minutos. Después de editar, ejecuta systemctl restart fail2ban y comprueba: fail2ban-client status sshd. En AlmaLinux y Rocky Linux el paquete se obtiene del repositorio EPEL: dnf install epel-release, después dnf install fail2ban y systemctl enable --now fail2ban.
7. Activa las actualizaciones de seguridad automáticas
La mayoría de las intrusiones en servidores aprovechan vulnerabilidades cuyo parche ya ha salido, solo que nadie lo instaló. En Ubuntu el paquete unattended-upgrades viene instalado y activado por defecto; compruébalo con systemctl status unattended-upgrades. En Debian se instala y se activa así:
apt install unattended-upgrades
dpkg-reconfigure -plow unattended-upgrades
Por defecto solo instala actualizaciones de seguridad. El kernel no se actualiza sin reiniciar: o reinicias tú el servidor según la señal del paso 1, o activas el reinicio automático por la noche con los parámetros Unattended-Upgrade::Automatic-Reboot y Automatic-Reboot-Time en /etc/apt/apt.conf.d/50unattended-upgrades.
En AlmaLinux y Rocky Linux lo mismo lo hace dnf-automatic. Instala el paquete con dnf install dnf-automatic, en /etc/dnf/automatic.conf define upgrade_type = security y apply_updates = yes (sin esto las actualizaciones solo se descargan) y activa el temporizador: systemctl enable --now dnf-automatic.timer.
8. Comprueba qué escucha el servidor
Las plantillas de los proveedores y los paneles de control a veces arrancan servicios que no has pedido. Mira todos los puertos abiertos:
ss -tulpn
Todo lo que escucha en 0.0.0.0 o [::] es accesible desde fuera si el firewall lo deja pasar. Aparte de SSH y el servidor web, no debería haber servicios así. Las bases de datos MySQL, MariaDB, PostgreSQL y Redis deben escuchar solo en 127.0.0.1: en los paquetes de Debian y Ubuntu viene así por defecto, pero después de instalarlas con Docker o con un script de terceros conviene comprobarlo. Detén los servicios innecesarios y quítalos del arranque: systemctl disable --now nombre_del_servicio. Para ver el servidor con los ojos de un extraño, ejecuta desde otro ordenador: nmap -Pn IP_DEL_SERVIDOR.
9. Hora, logs y monitorización
Comprueba con timedatectl que el reloj se sincroniza (la línea System clock synchronized: yes). Una hora incorrecta rompe la verificación de certificados, los códigos de un solo uso y el análisis de los logs. Quién ha entrado en el servidor y cuándo lo muestran last -a | head y journalctl -u ssh --since today (en AlmaLinux el servicio se llama sshd).
Conecta una monitorización externa de disponibilidad: hay muchos servicios gratuitos que abren la web una vez por minuto y te avisan si hay un error. Configura aparte una alerta de disco lleno: un disco desbordado es una causa frecuente de que la web y la base de datos dejen de funcionar de noche.
10. Crea un punto de restauración y protege el panel del proveedor
Cuando el servidor esté configurado, haz una instantánea del disco en el panel del proveedor si tiene esa función: podrás volver al sistema limpio y configurado en minutos. Una instantánea no sustituye a las copias de seguridad, porque se guarda en el mismo proveedor. Cómo montar copias de verdad fuera del servidor se explica en Copias de seguridad de un VPS: estrategias y herramientas.
Activa el inicio de sesión en dos pasos en el área de cliente del proveedor. Desde ella se puede reinstalar el servidor, restablecer la contraseña de root o abrir la consola, y un SSH protegido no sirve de nada si alguien entra en el área de cliente con una contraseña robada. Guarda la clave SSH privada solo en tus dispositivos y protégela con una frase de contraseña.
Qué no hacer
- No desactives SELinux en AlmaLinux y Rocky Linux al primer error de acceso. Casi siempre basta con la etiqueta correcta en la carpeta de la web o con un permiso mediante
setsebool. - No pongas permisos 777 en las carpetas de la web. El propietario de los archivos debe ser el usuario del servidor web o un usuario aparte para la web; los permisos de las carpetas, 755, y los de los archivos, 644.
- No ejecutes aplicaciones como root. A un bot, a una web o a una cola de tareas les basta con su propio usuario sin
sudo. - No publiques el panel de control ni phpMyAdmin en direcciones estándar abiertas a todos. Permite el acceso solo desde tu IP o a través de un túnel SSH.
Para elegir el sistema del nuevo servidor son prácticas las selecciones VPS con Ubuntu, VPS con Debian y VPS con AlmaLinux. Si el servidor es para una web que viene de un hosting, el siguiente paso se describe en Cómo migrar una web del hosting compartido a un VPS, y en qué fijarse al elegir el propio plan, en Cómo elegir un VPS: los 7 parámetros que deciden.