Seguridad de un VPS desde cero: claves SSH, firewall y Fail2ban
Un VPS nuevo no puede considerarse protegido justo después de instalar Ubuntu. Antes de configurar el acceso, el servidor ya es visible para los escáneres: prueban contraseñas de SSH, buscan paneles abiertos y comprueban vulnerabilidades habituales. En esta guía veremos cómo proteger un VPS desde cero: crear un usuario independiente, configurar el acceso mediante una clave SSH, limitar los puertos de red con UFW y añadir Fail2ban. Todos los pasos son válidos para Ubuntu 22.04 y 24.04, siempre que los comandos se ejecuten con un usuario que tenga permisos de sudo.
Antes de configurar: prepara una lista de puertos
No abras puertos «por si acaso». Para un servidor web normal se necesitan:
22/tcp— SSH; es recomendable limitarlo por IP o trasladarlo a otro puerto solo como medida adicional;80/tcp— HTTP, normalmente necesario para redirigir a HTTPS y comprobar el certificado;443/tcp— HTTPS.
Un puerto de aplicación como 3000, 8080 o 9000 no debe estar accesible desde Internet si delante funciona Nginx o Caddy. Vincula la aplicación a 127.0.0.1 o permite su puerto únicamente en la red interna. Primero averigua qué está escuchando en el servidor:
sudo ss -tulpnDespués de instalar Docker, revisa también sus reglas de iptables: publicar -p 3000:3000 puede abrir el puerto sin respetar el esquema esperado. Para un servicio público es más seguro utilizar un proxy HTTPS y ocultar el puerto interno.
Paso 1. Actualiza el sistema y crea un administrador
Conéctate al VPS con la cuenta proporcionada e instala las actualizaciones:
sudo apt update
sudo apt full-upgrade -y
sudo apt install -y ufw fail2ban unattended-upgradesCrea un usuario personal. Sustituye alex por tu propio nombre:
sudo adduser alex
sudo usermod -aG sudo alexNo elimines el acceso original hasta comprobar la nueva cuenta en otra ventana de la terminal. Es una regla importante: es más fácil corregir un error de SSH mientras la sesión actual sigue abierta.
Paso 2. Crea una clave SSH e instálala en el servidor
En tu equipo con Linux, macOS o Windows PowerShell, ejecuta:
ssh-keygen -t ed25519 -C "alex@my-computer"Pulsa Enter para guardar la clave en el archivo predeterminado y establece una passphrase. La clave privada no debe enviarse por chat, guardarse en un repositorio ni copiarse al VPS. Al servidor solo debes transferir el archivo con extensión .pub:
ssh-copy-id alex@SERVER_IPSi ssh-copy-id no está disponible, abre la clave pública con Get-Content $env:USERPROFILE\.ssh\id_ed25519.pub en PowerShell y después añádela al servidor:
sudo install -d -m 700 -o alex -g alex /home/alex/.ssh
sudo nano /home/alex/.ssh/authorized_keys
sudo chown alex:alex /home/alex/.ssh/authorized_keys
sudo chmod 600 /home/alex/.ssh/authorized_keysPega la clave en una sola línea y comprueba el acceso antes de desactivar las contraseñas:
ssh alex@SERVER_IP
sudo whoamiEl resultado esperado del último comando es root. Si el cliente SSH no encuentra la clave, indícala de forma explícita: ssh -i ~/.ssh/id_ed25519 alex@SERVER_IP.
Paso 3. Prohíbe root y el acceso mediante contraseña
Crea una copia de seguridad de la configuración de SSH:
sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
sudo nano /etc/ssh/sshd_configAsegúrate de que el archivo contiene estos parámetros:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
KbdInteractiveAuthentication no
MaxAuthTries 3En Ubuntu, la configuración puede encontrarse en /etc/ssh/sshd_config.d/*.conf, así que comprueba la configuración resultante:
sudo sshd -t
sudo sshd -T | grep -E 'permitrootlogin|passwordauthentication|pubkeyauthentication|maxauthtries'Si sshd -t muestra un error, no reinicies el servicio hasta corregir la sintaxis. Después de comprobarla correctamente, aplica la configuración:
sudo systemctl reload sshDeja abierta la conexión SSH anterior y comprueba en una ventana nueva el acceso con la clave. Desactivar las contraseñas sin haber verificado la clave es la forma más habitual de perder el acceso al servidor.
Paso 4. Configura UFW sin bloquear SSH
UFW es una interfaz cómoda para las reglas de red de Linux. Primero establece valores predeterminados seguros y después permite SSH y los puertos web:
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp comment 'SSH'
sudo ufw allow 80/tcp comment 'HTTP'
sudo ufw allow 443/tcp comment 'HTTPS'
sudo ufw enableConfirma la activación solo después de haber añadido la regla de SSH. Consulta el resultado:
sudo ufw status verbose
sudo ufw status numberedPara una IP de oficina fija, puedes limitar SSH a esa dirección:
sudo ufw delete allow 22/tcp
sudo ufw allow from YOUR.PUBLIC.IP to any port 22 proto tcp comment 'SSH office'Utiliza esta opción solo si tienes una IP fija y acceso a la consola del proveedor: si la dirección cambia, podrías bloquearte el acceso.
Cómo abrir temporalmente el puerto de una aplicación
Si necesitas comprobar un servicio directamente, crea una regla con el origen limitado:
sudo ufw allow from YOUR.PUBLIC.IP to any port 8080 proto tcpDespués de la prueba, elimínala usando el número que aparece en ufw status numbered:
sudo ufw delete RULE_NUMBERNo utilices sudo ufw allow 1:65535/tcp: una regla así convierte el firewall en una formalidad.
Paso 5. Activa Fail2ban para SSH
Fail2ban analiza los registros y añade una regla de bloqueo temporal después de varios intentos de acceso fallidos. No sustituye a las claves SSH ni al firewall, pero reduce el ruido de los ataques automatizados por fuerza bruta.
Crea una configuración local para que una actualización del paquete no sobrescriba tus ajustes:
sudo cp /etc/fail2ban/jail.conf /etc/fail2ban/jail.local
sudo nano /etc/fail2ban/jail.localEn la sección [DEFAULT], establece valores razonables:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
banaction = ufw
[sshd]
enabled = true
port = 22Inicia el servicio y comprueba el jail:
sudo systemctl enable --now fail2ban
sudo fail2ban-client status
sudo fail2ban-client status sshdEn la salida de sshd, revisa el número de intentos fallidos y las direcciones bloqueadas. No añadas tu propia IP a la lista de bloqueos. Para una exclusión permanente, utiliza el parámetro ignoreip = 127.0.0.1/8 YOUR.PUBLIC.IP en [DEFAULT].
Paso 6. Activa las actualizaciones automáticas
Las actualizaciones automáticas son útiles para los paquetes de seguridad, pero aun así debes controlar el reinicio del kernel:
sudo dpkg-reconfigure -plow unattended-upgrades
sudo systemctl status unattended-upgradesUna vez por semana, comprueba si es necesario reiniciar:
test -f /var/run/reboot-required && echo 'Требуется перезапуск'Antes de reiniciar manualmente, asegúrate de tener una clave funcional y acceso a la consola del VPS. Después del reinicio, comprueba los servicios de la aplicación, Nginx, UFW y Fail2ban.
Paso 7. Comprueba el resultado desde fuera
Comprueba la protección desde otro equipo, no solo revisando el contenido de la configuración:
ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no alex@SERVER_IPEl comando debe terminar con un rechazo. El acceso funcional mediante clave se comprueba por separado:
ssh -o IdentitiesOnly=yes -i ~/.ssh/id_ed25519 alex@SERVER_IPEn el VPS, comprueba las direcciones en escucha y las reglas:
sudo ss -lntup
sudo ufw status numbered
sudo fail2ban-client status sshdEl puerto de la aplicación debe escuchar en 127.0.0.1 si no está destinado al acceso directo. Desde un nodo externo puedes utilizar nmap SERVER_IP, pero escanea únicamente tu propio servidor: comprobar una infraestructura ajena sin permiso puede infringir la ley y las reglas del proveedor.
Copias de seguridad y recuperación
La protección de SSH no evita la eliminación de datos, un error del administrador ni la vulneración de una aplicación. Guarda las copias de la base de datos, las configuraciones y los archivos de usuario fuera del VPS. El esquema mínimo consiste en una copia diaria, varias versiones de días anteriores y una comprobación periódica de la restauración.
No guardes contraseñas ni tokens en scripts sin protección. Si se produce una filtración, revoca inmediatamente el secreto y crea uno nuevo.
Cómo elegir un VPS para un proyecto protegido
La seguridad comienza con el control de la infraestructura. En un VPS puedes elegir por tu cuenta el sistema operativo, las reglas del firewall, el método de acceso, las copias de seguridad y la ubicación de los servicios. Para un sitio pequeño o una API, una red estable, SSD y una consola de recuperación son más importantes que un exceso de núcleos virtuales.
Al iniciar un proyecto en un VPS de tropic.host, define con antelación sus puntos de entrada públicos: normalmente bastan SSH, HTTP y HTTPS. Mantén la base de datos y los paneles de administración dentro de la red interna. En un proyecto en crecimiento, separar los VPS de la aplicación, la base de datos y la monitorización divide las zonas de fallo.
Errores frecuentes
- Desactivar la contraseña antes de comprobar el acceso mediante clave. Conserva la sesión actual y prueba el nuevo acceso por separado.
- Abrir
22/tcpa todo el mundo cuando es posible permitirlo solo desde direcciones de confianza. - Publicar directamente los puertos de Docker. Primero revisa las reglas de Docker y UFW.
- Instalar Fail2ban y no volver a consultar los registros. Después de los cambios, comprueba
journalctl -u sshy el estado del jail.
Conclusión
La protección básica de un VPS requiere poco tiempo si se realiza en el orden correcto: crear un usuario independiente, instalar una clave SSH, comprobar el acceso, prohibir root y las contraseñas, activar UFW, configurar Fail2ban y habilitar las actualizaciones automáticas. Después, añade copias de seguridad, registro de eventos y monitorización externa.
Estos pasos no hacen que el servidor sea invulnerable, pero corrigen los errores más habituales de la configuración inicial. A continuación, adapta el nivel de protección a la aplicación concreta: actualiza las dependencias, limita los permisos de los servicios, protege los paneles de administración y revisa con regularidad los puertos abiertos.
FAQ
¿Es necesario cambiar el puerto SSH predeterminado?
No es obligatorio. Cambiar de puerto reduce el ruido de los escáneres automáticos, pero no sustituye a las claves, la desactivación de contraseñas, UFW ni Fail2ban. Si cambias el puerto, actualiza la regla del firewall y el parámetro port del jail de Fail2ban.
¿Qué hago si pierdo el acceso después de configurar UFW?
Utiliza la consola web o la consola de recuperación del proveedor y comprueba la regla de SSH y la configuración de sshd. No cierres la sesión anterior que funciona hasta confirmar el nuevo acceso.
¿Fail2ban es suficiente para proteger SSH?
No. Fail2ban reacciona a errores de acceso que ya se han producido. La base debe ser una clave SSH, la autenticación mediante contraseña desactivada, unos permisos de usuario mínimos y un firewall limitado.
¿Puedo permitir SSH únicamente desde una IP?
Sí, si la dirección es fija: añade en UFW una regla allow from para esa IP. Prevé antes una consola del proveedor o un acceso alternativo, porque después de cambiar de IP la conexión quedará bloqueada.
¿Con qué frecuencia debo comprobar la seguridad del VPS?
Después de cada cambio en SSH, el firewall o la publicación de puertos de Docker, comprueba los puertos y prueba el acceso. De forma planificada, revisa las actualizaciones y los registros al menos una vez por semana, y realiza restauraciones de las copias de seguridad con regularidad.