Cómo proteger un VPS antes de implementarlo

Mon Aug 31 2026

Cómo proteger un VPS antes de implementarlo

Abre una segunda sesión de SSH antes de ejecutar ufw enable o desactivar el SSH mediante contraseña. El comando de hardening más peligroso es el que ejecutas antes de demostrar que funciona otra forma de volver a entrar.

Un VPS seguro se obtiene mediante una secuencia: preservar la recuperación, probar la administración basada en claves, reducir la exposición pública, eliminar privilegios innecesarios, aplicar parches al sistema, añadir detección y verificar la restauración. Esta guía es para Ubuntu 24.04 y sistemas similares basados en Debian. Los paneles de los proveedores, las redes de Docker y las imágenes administradas pueden cambiar los detalles, así que considera los comandos como un procedimiento controlado, no como un script universal.

En este artículo

Los primeros diez minutos son cuando el hardening suele bloquearte el acceso

Empieza preguntando si aún podrás administrar, actualizar, monitorizar y restaurar el servidor después del siguiente cambio.

Y mantén abierta la sesión de SSH original mientras cambias la autenticación o las reglas del firewall. Ten preparado el acceso a la consola del proveedor. Registra qué está escuchando antes de bloquear o eliminar algo. Un estado del firewall o una puntuación de CIS demuestra que una operación se completó. No demuestra que tus aplicaciones, la ruta IPv6, los contenedores, las alertas o las copias de seguridad funcionen.

A continuación tienes una base segura, pero ninguna guía puede garantizar que el enrutamiento de tu proveedor, los binds de tu aplicación o las reglas de tus contenedores expongan algo inesperado. Pruébalo desde fuera del VPS.

Así que sigue esta secuencia: recuperación, SSH, exposición de red, servicios y privilegios, actualizaciones, auditoría CIS, detección, tráfico privado y pruebas de aceptación.

Convierte la recuperación en un requisito antes de cambiar SSH

Antes de tocar la autenticación o las reglas del firewall, recopila:

  • Acceso de recuperación del proveedor. Prueba la consola o la función de recuperación que realmente ofrece tu proveedor. Los proveedores son diferentes, y una función que aparece en un panel no sirve hasta que sabes cómo utilizarla.
  • Detalles de acceso actuales. Registra el nombre de usuario, la dirección, el puerto SSH y las credenciales que se están utilizando actualmente.
  • Una copia de seguridad o snapshot. Averigua qué captura, cómo funciona la restauración y qué ocurre con los datos escritos después.
  • Un segundo terminal. Mantén abierta la primera sesión hasta que el inicio de sesión de reemplazo funcione.
  • Un inventario de servicios. Registra los listeners actuales y su propósito.

Un snapshot no es lo mismo que una restauración probada. Para datos de producción, ensaya una restauración representativa en una copia que no sea de producción o sigue el proceso de recuperación documentado por el proveedor antes de la implementación.

Además, la guía de seguridad de servidores de DigitalOcean recomienda mantener abierta una sesión existente mientras pruebas una nueva autenticación SSH. Ese pequeño hábito evita un error sorprendentemente costoso.

Inspecciona los listeners con:

sudo ss -tulpn

Registra cada listener TCP o UDP, su dirección, puerto, proceso propietario y motivo para ser público. Supón que este VPS nuevo con Ubuntu 24.04 aloja una pequeña aplicación web: se requiere administración mediante SSH, HTTPS funciona en el puerto 443, HTTP puede redirigir o permitir la emisión de certificados, y no hay motivo para que la base de datos sea accesible públicamente.

Conserva ese inventario. Lo utilizarás como prueba de aceptación más adelante.

Sustituye el SSH mediante contraseña y como root por una clave probada

Crea una cuenta administrativa con nombre, que no sea root y que tenga sudo. Si tu proveedor solo te proporcionó acceso como root, crea la cuenta mediante el flujo de Ubuntu documentado por el proveedor o mediante la consola del proveedor, y después instala la clave para ella. El comando para crear la cuenta varía según tu entorno, así que esta guía no fingirá que existe una única rama segura para copiar y pegar.

Genera una clave Ed25519 en tu ordenador local:

ssh-keygen -t ed25519 -C "you@example.com"

Protege la clave privada con una passphrase y guárdala en tu ordenador. Una clave privada Ed25519 correctamente protegida hace irrelevantes los intentos de adivinar contraseñas en línea para esta ruta de inicio de sesión. No puede proteger un endpoint comprometido.

Copia la clave pública a la cuenta prevista:

ssh-copy-id user@your-server

Si ssh-copy-id no está disponible, añade la clave pública mediante la consola del proveedor o el flujo de inyección de claves. La clave debe estar en el ~/.ssh/authorized_keys de esa cuenta, no por accidente en el directorio de root.

Comprueba el directorio y el archivo de la clave:

ls -ld ~/.ssh
ls -l ~/.ssh/authorized_keys

Deben pertenecer al usuario previsto. Corrige la propiedad según la estructura del directorio personal de la cuenta antes de realizar la prueba; para un directorio personal de usuario normal, generalmente significa que el usuario es propietario tanto del directorio como del archivo. Aplica permisos restrictivos:

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys

Abre un segundo terminal y prueba:

ssh user@your-server

Deja abierta la primera sesión. Audita los trabajos de implementación, agentes de monitorización y scripts de recuperación antes de desactivar las contraseñas. Migra todo lo que aún dependa de la autenticación mediante contraseña.

Edita la configuración del daemon:

sudoedit /etc/ssh/sshd_config

Establece:

PasswordAuthentication no
PermitRootLogin no

Antes de reiniciar, valida la configuración. En Ubuntu, sshd -t normalmente se resuelve directamente; si no lo hace, utiliza la ruta del binario del daemon proporcionada por tu paquete de OpenSSH instalado. El comando no debe devolver ninguna salida y debe finalizar correctamente:

sudo sshd -t

Mantén abierta la sesión existente mientras validas y reinicias:

sudo systemctl restart ssh

Vuelve a probar el segundo terminal. PermitRootLogin no bloquea root mediante SSH, mientras que la recuperación mediante la consola del proveedor permanece separada.

Fail2ban puede ralentizar el abuso, pero el SSH público sigue necesitando autenticación mediante clave, una cuenta que no sea root, mínimo privilegio y una ruta de recuperación que hayas probado.

Un estado correcto del firewall demuestra muy poco

El firewall debe seguir el inventario de servicios. Para el host de ejemplo, permite SSH y el tráfico web que necesite, y deja la base de datos sin publicar.

En la capa del proveedor, restringe SSH a una dirección de administrador conocida, una VPN o una ruta controlada por el proveedor cuando sea posible. En Ubuntu, permite SSH antes de activar UFW:

sudo ufw allow OpenSSH
sudo ufw allow 80/tcp
sudo ufw allow 443/tcp
sudo ufw enable
sudo ufw status verbose

Si SSH utiliza el puerto 2222, permite ese puerto antes de activar UFW:

sudo ufw allow 2222/tcp

Una regla general OpenSSH puede exponer SSH globalmente. Si conoces la dirección de origen del administrador, restríngela:

sudo ufw allow from 203.0.113.25 to any port 22 proto tcp

Sustituye la dirección de ejemplo por un origen de confianza real. Mantén disponible el acceso a la consola antes de cambiarla.

Las reglas allow mostradas dependen de la política predeterminada de UFW. Confirma que la salida detallada indique:

Default: deny (incoming)

Que un firewall indique “active” no demuestra que tus aplicaciones estén protegidas. Docker puede instalar reglas de iptables para los puertos publicados, y IPv6 puede seguir expuesto a través de una dirección que nunca probaste.

Comprueba la configuración IPv6 de UFW en /etc/default/ufw, y después prueba las direcciones públicas IPv4 e IPv6 reales desde una red externa. ufw status verbose muestra la política, no si tu aplicación es accesible mediante todas las rutas.

El comportamiento de Docker requiere una decisión independiente (consulta nuestra guía para asegurar contenedores Docker en producción). Si el reverse proxy se ejecuta en el host y la aplicación no necesita una ruta externa, publica el contenedor en loopback:

docker run -p 127.0.0.1:8080:8080 example/app

Eso es una decisión de publicación en el host, no una política de red completa de Docker. Verifica el puerto externamente. Para una base de datos, utiliza una red interna de Docker o localhost y no publiques ningún puerto del host.

Elimina servicios y privilegios que no puedas justificar

Utiliza el inventario de listeners para investigar, en lugar de ejecutar un script de eliminación. Identifica el proceso detrás de cada socket público y comprende sus dependencias antes de desactivar una unidad o eliminar un paquete.

Vincula las bases de datos, paneles de administración, servidores de desarrollo y APIs internas a localhost o a direcciones privadas cuando sea posible. Revisa también las rutas del reverse proxy y las direcciones bind de la aplicación. Un firewall no puede solucionar un endpoint que la aplicación expone deliberadamente.

Ejecuta la aplicación con un usuario dedicado que no sea root. Dale propiedad únicamente de los directorios que necesita. Restringe los archivos y directorios secretos con una propiedad y permisos adecuados, y mantén las credenciales fuera de los repositorios, de las rutas de configuración legibles por todos y del historial del shell.

Revisa las cuentas humanas. Elimina los accesos abandonados, utiliza cuentas con nombre para permitir la atribución y concede sudo únicamente para el trabajo que lo requiera.

La regla para detenerse es sencilla: si no puedes explicar por qué existe un listener, una cuenta o un proceso con privilegios, investígalo antes de la implementación. Investígalo antes de eliminarlo. Mantenlo privado a menos que tengas un motivo para exponerlo.

Aplica parches al sistema base y decide quién es responsable de las actualizaciones

Actualiza el sistema base:

sudo apt update
sudo apt upgrade

Revisa los cambios de los paquetes antes de aceptarlos. Las actualizaciones pueden cambiar el comportamiento de los servicios, las dependencias, los formatos de configuración y los requisitos de reinicio. Define una ventana de mantenimiento, una ruta de rollback, una prueba smoke de la aplicación y un responsable.

En Ubuntu, comprueba si hay un reinicio pendiente con:

test -f /var/run/reboot-required && cat /var/run/reboot-required

Programa el reinicio cuando el servicio lo permita. Una actualización del kernel es el caso más evidente, pero las bibliotecas y los servicios importantes también pueden requerir reinicios.

La documentación de Ubuntu Security Guide de Canonical describe Ubuntu Pro como una opción que proporciona más de 10 años de correcciones de seguridad y aplicación de parches al kernel sin reinicio. Pro es una opción para requisitos de soporte o cobertura; no protege tu aplicación ni sustituye las actualizaciones rutinarias. La aplicación de parches al kernel sin reinicio tampoco se aplica a todas las actualizaciones.

CIS Level 1 es una base, no un veredicto

Los benchmarks formales ayudan cuando necesitas comprobaciones repetibles, evidencias de auditoría o un estándar de hardening compartido. Se vuelven perjudiciales cuando aplicas controles sin comprender tu aplicación y tu plan de recuperación.

Estos comandos son para Ubuntu 24.04 con Ubuntu Pro asociado. No son un procedimiento genérico para Debian. USG requiere Ubuntu Pro:

sudo pro enable usg
sudo apt install usg

Audita antes de cambiar la configuración activa:

sudo usg audit cis_level1_server

Lee cada hallazgo. Registra excepciones para los servicios requeridos, el registro, la sincronización de tiempo, la elección del firewall, el acceso remoto y la recuperación. Solo entonces considera la corrección:

sudo usg fix cis_level1_server

usg fix puede modificar la configuración activa. Ejecútalo únicamente después de revisar los hallazgos, conservar una ruta de rollback y mantener disponible el acceso a la consola.

Para una auditoría adaptada, utiliza el archivo generado según la documentación de USG de Ubuntu:

sudo usg generate-tailoring cis_level1_server tailoringfile.xml
sudo usg audit --tailoring-file tailoringfile.xml

Level 1 es la base práctica para la mayoría de las implementaciones de VPS de producción pequeñas. Level 2 encaja en entornos donde la seguridad tiene prioridad sobre la comodidad y puede aumentar el registro, el uso de almacenamiento o los costes de rendimiento. Aplicar Level 2 a ciegas a un servidor de producción en funcionamiento es security theatre con costes operativos. Mide el entorno y realiza excepciones deliberadamente.

La alineación con CIS no demuestra que tu aplicación sea segura, que las alertas lleguen o que las restauraciones funcionen.

Elige una detección que puedas operar

Envía los registros y alertas importantes fuera del host. Una advertencia que existe únicamente en un VPS comprometido es una evidencia débil, y una herramienta que nadie revisa es decoración costosa.

AIDE o Tripwire pueden comparar el sistema de archivos actual con una base de datos conocida como buena e informar de cambios inesperados. Yo crearía esa línea base después de que el servidor alcance un estado aprobado, y después enviaría las notificaciones a un lugar que el VPS no pueda borrar.

Utiliza psad cuando necesites alertas sobre escaneos de puertos registrados por el firewall. Puede cambiar las reglas del firewall según su configuración, así que prueba esas respuestas antes de depender de ellas.

Bro, ahora llamado Zeek, proporciona una monitorización más amplia de eventos y políticas de red. Omítelo en un único VPS pequeño a menos que ya tengas un collector y una persona responsable de revisar los eventos. De lo contrario, estarás recopilando papeleo con forma de tráfico.

HerramientaElígela cuandoDetente si
AIDE o TripwireLos cambios del sistema de archivos requieren revisiónNo puedes mantener una línea base de confianza o alertas fuera del host
psadLos escaneos de puertos requieren alertas o respuestaNadie es responsable de revisar los eventos del firewall
Bro/ZeekYa operas una recopilación de eventos de redNo tienes collector, almacenamiento ni un responsable de revisar eventos

Fail2ban ralentiza los abusos repetidos de inicio de sesión. Las claves, el mínimo privilegio y la recuperación protegen la cuenta en sí.

Mantén privado el tráfico privado

Las prácticas recomendadas de VPC de DigitalOcean describen las redes VPC como una forma de aislar los recursos de Internet pública. El enrutamiento privado no autoriza el tráfico por sí mismo. Los controles del proveedor, los firewalls del host, los binds de los servicios y la autenticación de la aplicación siguen siendo necesarios.

Para varios recursos, diseña subredes privadas y gateways en el momento del aprovisionamiento. Mover un servidor existente a una VPC puede requerir cambios de IP y de enrutamiento. Utiliza primero una VPC del proveedor para una carga de trabajo en una sola región; añade una VPN cuando necesites tráfico cifrado entre regiones o acceso de usuarios remotos.

Un diseño defendible tiene este aspecto:

  • El VPS expone públicamente únicamente los puertos web necesarios.
  • SSH utiliza un administrador restringido, una VPN o una ruta de recuperación del proveedor.
  • La base de datos escucha en localhost o en una interfaz privada.
  • Las copias de seguridad van a un destino separado con acceso controlado.
  • Los registros y las alertas salen del VPS.
  • La restauración se ha ensayado.

Verifica el resultado y asigna responsabilidades

Ejecuta la prueba de aceptación desde el servidor y desde una red externa:

  1. Abre una nueva sesión de SSH con la clave administrativa.
  2. Confirma que la aplicación funciona mediante HTTPS.
  3. Confirma que HTTP redirige o sirve únicamente el endpoint previsto.
  4. Compara las reglas de UFW y del firewall del proveedor.
  5. Prueba los puertos inesperados mediante IPv4 externa y, si está habilitado, mediante IPv6 externa.
  6. Compara los listeners actuales con el inventario del aprovisionamiento.
  7. Confirma que la base de datos no es accesible desde Internet pública.
  8. Confirma que los registros y las alertas de detección llegan fuera del host.
  9. Restaura datos de producción representativos en una copia que no sea de producción. ¿No puedes hacerlo? Ensaya el proceso de recuperación del proveedor con datos equivalentes y registra la limitación.
  10. Vuelve a ejecutar la auditoría de USG si adoptaste una base CIS.

Escribe el acuerdo operativo:

Owner:
Public ports and protocols:
IPv4/IPv6 exposure checked on:
SSH recovery method:
Last backup-restore test:
Last external exposure test:
Next patch window:
Last hardening audit:

Actualízalo después de cada cambio importante y durante el mantenimiento adecuado para el servicio. Si no puedes probar la restauración, el acceso y la exposición externa, detén la implementación y corrige esa carencia.