Proteger un VPS nuevo: la checklist
Última actualización:
Un VPS nuevo está en internet desde el momento en que arranca, y los escáneres llegan a él en pocos minutos. Estos diez pasos son la primera hora de trabajo en un servidor Debian, Ubuntu o de la familia RHEL recién creado (RHEL, Rocky Linux, AlmaLinux, Oracle Linux, CentOS Stream, Fedora), en el orden que evita que te quedes fuera.
Ejecútalos como un usuario con sudo, mantén abierta una sesión SSH mientras cambias SSH o el firewall, y ten localizada la consola web de tu proveedor: funciona cuando SSH no funciona.
1. Instalar todas las actualizaciones
Las imágenes cloud suelen tener semanas. Actualiza todo antes de instalar cualquier otra cosa, y reinicia si han cambiado el kernel o las bibliotecas básicas.
sudo apt update && sudo apt full-upgrade -y
[ -f /var/run/reboot-required ] && echo "reboot needed"sudo dnf upgrade --refresh -y
sudo dnf needs-restarting -rEn la familia RHEL, needs-restarting -r indica si hace falta reiniciar. Reinicia con sudo reboot y vuelve a entrar.
2. Crear tu propio usuario con sudo
Trabaja con un usuario con nombre y sudo, no como root: las acciones quedan registradas a un nombre, y el acceso de root se puede desactivar en el paso siguiente.
sudo adduser deploy
sudo usermod -aG sudo deploysudo useradd -m deploy
sudo passwd deploy
sudo usermod -aG wheel deployCopia tu clave SSH al usuario (ssh-copy-id deploy@SERVER_IP desde tu ordenador), entra con ese usuario desde un segundo terminal y comprueba sudo -v. Después asegúrate de que solo root tiene el ID de usuario 0 y de que ninguna cuenta tiene la contraseña vacía: el primer comando debe mostrar solo root y el segundo, nada.
awk -F: '$3 == 0 {print $1}' /etc/passwd
sudo awk -F: '$2 == "" {print $1}' /etc/shadow3. Blindar SSH
Solo claves, sin acceso de root, pocos intentos por conexión. El procedimiento completo, con las comprobaciones y el cambio de puerto, está en Cómo frenar los ataques de fuerza bruta SSH. La versión corta, cuando ya funcione el acceso con clave:
sudo tee /etc/ssh/sshd_config.d/00-hardening.conf > /dev/null <<'EOF'
PubkeyAuthentication yes
PasswordAuthentication no
KbdInteractiveAuthentication no
PermitRootLogin no
MaxAuthTries 4
EOF
sudo sshd -t && echo "config OK"sudo systemctl reload sshsudo systemctl reload sshdAtención: Prueba un nuevo acceso con clave desde un segundo terminal antes de cerrar la sesión actual. Si grep -i '^Include' /etc/ssh/sshd_config no muestra nada (RHEL 8 y sus derivadas), pon estas líneas directamente en /etc/ssh/sshd_config.
4. Activar el firewall
Bloquea todo el tráfico entrante y abre solo lo que ofrece el servidor. Aquí, SSH en el 22 y un servidor web en el 80 y el 443; quita lo que no uses.
sudo apt install -y ufw
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow 22/tcp
sudo ufw allow 80,443/tcp
sudo ufw enable
sudo ufw status verbosesudo dnf install -y firewalld
sudo systemctl enable --now firewalld
sudo firewall-cmd --permanent --add-service=ssh
sudo firewall-cmd --permanent --add-service=http --add-service=https
sudo firewall-cmd --reload
sudo firewall-cmd --list-allAtención: Permite tu puerto SSH antes de ufw enable o de la recarga, o se rechazarán las nuevas conexiones SSH. Si has movido SSH a otro puerto, abre ese.
- En RHEL 9 y sus derivadas, la zona por defecto también permite
cockpit: quítalo consudo firewall-cmd --permanent --remove-service=cockpitsi no lo usas y después recarga. - Docker publica los puertos de los contenedores con sus propias reglas de iptables, que ufw no ve: un puerto publicado con
-p 8080:80está abierto aunque ufw diga lo contrario. Publica en127.0.0.1:8080:80cuando solo lo necesite el proxy local. - La mayoría de los proveedores tienen también un firewall cloud o un security group. Úsalo como segunda capa con las mismas reglas.
5. Activar las actualizaciones de seguridad automáticas
La mayoría de los servidores comprometidos ejecutan software para el que había una corrección disponible desde hacía semanas. Deja que el servidor instale solo las actualizaciones de seguridad.
sudo apt install -y unattended-upgrades
sudo tee /etc/apt/apt.conf.d/20auto-upgrades > /dev/null <<'EOF'
APT::Periodic::Update-Package-Lists "1";
APT::Periodic::Unattended-Upgrade "1";
EOF
sudo unattended-upgrade --dry-run --debug 2>&1 | tail -n 20Qué actualizaciones se instalan se define en /etc/apt/apt.conf.d/50unattended-upgrades (las de seguridad en Ubuntu; las de seguridad y las de las point releases en Debian). Los reinicios automáticos están desactivados salvo que pongas ahí Unattended-Upgrade::Automatic-Reboot "true";.
sudo dnf install -y dnf-automatic
sudo sed -i -e 's/^upgrade_type.*/upgrade_type = security/' \
-e 's/^apply_updates.*/apply_updates = yes/' /etc/dnf/automatic.conf
sudo systemctl enable --now dnf-automatic.timer
systemctl list-timers dnf-automatic.timer- CentOS Stream no publica avisos de seguridad, así que ahí
upgrade_type = securityno instala nada: usaupgrade_type = default. - Fedora 41 y posteriores usan dnf5: instala
dnf5-plugin-automaticy pon las mismas opciones en/etc/dnf/automatic.conf(consultaman dnf5-automatic). - Ninguna de las dos herramientas reinicia por defecto. Planifica un reinicio cuando se actualice el kernel.
6. Configurar copias de seguridad que salgan del servidor
Una copia en el mismo servidor, o solo en la misma cuenta del proveedor, desaparece con el servidor o con la cuenta. Guarda al menos una copia en otro sitio, cifrada, y prueba una restauración. Las snapshots del proveedor son útiles como complemento, no como sustituto.
restic es una opción sencilla: cifrado, con deduplicación, hacia SFTP, S3 y otros destinos. Está empaquetado para Debian y Ubuntu, y en EPEL para la familia RHEL. Sustituye BACKUP_HOST por tu servidor de copias; restic pide una contraseña del repositorio, que tienes que guardar fuera de este servidor.
sudo apt install -y resticsudo dnf install -y epel-release
sudo dnf install -y resticsudo restic -r sftp:backup@BACKUP_HOST:/srv/restic/$(hostname) init
sudo restic -r sftp:backup@BACKUP_HOST:/srv/restic/$(hostname) backup /etc /home /root /var/www
sudo restic -r sftp:backup@BACKUP_HOST:/srv/restic/$(hostname) snapshotsVuelca las bases de datos a un archivo antes de la copia (mysqldump --single-transaction, pg_dump) en lugar de copiar sus directorios de datos mientras están en marcha. Después demuestra que la restauración funciona:
sudo restic -r sftp:backup@BACKUP_HOST:/srv/restic/$(hostname) restore latest --target /tmp/restore-test --include /etc/hostname
cat /tmp/restore-test/etc/hostnameNota: Programa la copia con un timer de systemd o con cron, y revisa su resultado: una tarea de copia que lleva meses fallando sin avisar es el caso habitual.
7. Configurar la monitorización y las alertas
Necesitas saber, sin entrar, cuándo el servidor está caído, cuándo se llena el disco y cuándo alguien entra o lo ataca. Como mínimo:
- Una comprobación externa de disponibilidad del sitio o del servicio, desde fuera de tu proveedor.
- Una alerta sobre el espacio en disco y sobre los servicios que fallan.
- Un registro de quién ha entrado, y una alerta ante ataques y cambios en los archivos del sistema.
Hasta que algo lo haga por ti, estos comandos muestran los últimos accesos, los errores desde el arranque y el espacio libre en disco:
last -n 20
sudo journalctl -p err -b --no-pager | tail -n 30
df -h /8. Cerrar los puertos que no necesitas
Haz una lista de lo que está escuchando. Una dirección 0.0.0.0 o [::] significa todas las interfaces, es decir, internet, salvo que el firewall lo impida.
sudo ss -tulpn- Detén y desactiva los servicios que no usas.
- Las bases de datos y cachés que solo usa el propio servidor escuchan en localhost:
bind-address = 127.0.0.1para MySQL y MariaDB,listen_addresses = 'localhost'para PostgreSQL,bind 127.0.0.1 -::1para Redis. - No expongas nunca a internet la API de Docker (2375, 2376) ni Redis sin contraseña: son dos vías de entrada habituales para los mineros de criptomonedas.
sudo systemctl disable --now SERVICE_NAMEDespués compruébalo desde fuera, desde otra máquina con nmap instalado. Solo deben responder los puertos que abriste en el paso 4.
nmap -Pn SERVER_IP9. Mantener el reloj sincronizado
Los logs de distintos servidores solo cuadran si sus relojes coinciden, y TLS, los códigos de doble factor y la cronología de un incidente dependen de la hora. Compruébala:
timedatectlLo que quieres ver es System clock synchronized: yes. Si dice no:
sudo apt install -y systemd-timesyncd
sudo timedatectl set-ntp truesudo dnf install -y chrony
sudo systemctl enable --now chronyd
chronyc trackingNota: Algunas imágenes traen chrony en lugar de systemd-timesyncd. Usa el que haya: instalar uno elimina o sustituye al otro.
10. Conservar los logs el tiempo suficiente
Cuando pasa algo, la primera pregunta es qué pasó antes. Haz persistente el journal del sistema, con un límite de tamaño y una retención que elijas tú:
sudo mkdir -p /etc/systemd/journald.conf.d
sudo tee /etc/systemd/journald.conf.d/retention.conf > /dev/null <<'EOF'
[Journal]
Storage=persistent
SystemMaxUse=1G
MaxRetentionSec=1year
EOF
sudo systemctl restart systemd-journald
journalctl --disk-usage- Ajusta el límite al disco: 1 GB es más que suficiente para un servidor pequeño.
- Cuánto tiempo debes conservar los logs depende de tus contratos y obligaciones (por ejemplo, la notificación de incidentes de NIS2). Decídelo, déjalo por escrito y configúralo aquí.
- Los logs que solo están en el servidor los puede borrar quien entre. Envía también una copia a otra máquina o a un servicio de logs.
- Los archivos de
/var/log(servidor web, auth.log en Debian y Ubuntu) los rota logrotate: el valorrotateen/etc/logrotate.d/define cuántos archivos antiguos se conservan.
Qué comprueba y vigila InfraFence en un servidor nuevo
Tras la instalación, InfraFence revisa el servidor cada día, o cuando lo pidas, y lo sigue vigilando en tiempo real. Cubre varios pasos de esta lista, no todos:
- De 40 a 50 comprobaciones de hardening, según el servidor: ajustes de SSH, cuentas con ID de usuario 0 o contraseña vacía, bases de datos abiertas a internet, actualizaciones de seguridad pendientes, un sistema operativo al final de su vida útil, permisos de archivos sensibles, ajustes del servidor web, secretos expuestos.
- Las vulnerabilidades conocidas (CVE) de los paquetes instalados, a partir de los trackers de seguridad de Debian, Ubuntu, AlmaLinux y Rocky Linux, ordenadas según su explotación real.
- Una puntuación de seguridad de 0 a 100, con lo que la hace bajar. Las correcciones seguras se aplican con un clic y se pueden deshacer; las que podrían dejarte fuera, como el acceso SSH y el puerto, se explican paso a paso en su lugar.
- Detección y bloqueo en tiempo real: fuerza bruta contra SSH y otros servicios, ataques web, bots, malware, amenazas salientes y DNS, y cambios en archivos críticos.
- Alertas por email, Slack, Discord, Telegram o webhook, y métricas de CPU, memoria, disco y red.
No hace copias de seguridad, no sincroniza el reloj ni conserva tus logs: esos pasos siguen siendo cosa tuya.
Preguntas
- ¿Basta con el firewall del proveedor, o también necesito ufw o firewalld?
- Usa los dos cuando puedas. El firewall del proveedor detiene el tráfico antes de que llegue al servidor; el del servidor lo sigue protegiendo si alguien cambia las reglas cloud por error o el servidor se traslada.
- ¿Son seguras las actualizaciones automáticas en un servidor de producción?
- Las actualizaciones de seguridad de las versiones estables de estas distribuciones son pequeñas y están probadas, y son mucho menos arriesgadas que mantener agujeros conocidos. Deja desactivados los reinicios automáticos y planifícalos, y ten una copia de seguridad probada.
- ¿Cuánto tiempo debo conservar los logs?
- No hay una cifra única. Depende de tus contratos y de normas como NIS2 para las empresas a las que se aplica. Decide un plazo, guarda una copia lejos del servidor y asegúrate de que el servidor conserva al menos lo suficiente para investigar las últimas semanas.
Pruébalo gratis en 1 servidor
Starter es gratuito para un servidor, con protección completa y bloqueo automático. Sin tarjeta de crédito.
Instala el agente como root, con tu token en lugar de <TOKEN>:
curl -fsSL https://github.com/infrafence/infrafence-agent/releases/latest/download/install.sh | sudo bash -s -- --token <TOKEN>El token se crea en el panel, en Servidores › Añadir servidor.
