Qué vas a conseguir
Un Ubuntu Server (22.04 o 24.04 LTS) endurecido lo justo para producción: nadie entra por contraseña, el firewall solo abre lo que das de alta, los parches de seguridad se instalan solos y el sistema tiene nombre y hora correctos. Treinta minutos que te ahorran un incidente.
Antes de empezar
- Acceso a la consola (hipervisor o KVM) o por SSH al usuario creado en la instalación.
- Tu clave pública SSH (
~/.ssh/id_ed25519.puben tu equipo; si no la tienes,ssh-keygen -t ed25519). - Decidido con el equipo: nombre del servidor, qué servicios dará y qué puertos abrir.
1. Nombre, hora y actualización inicial
sudo hostnamectl set-hostname srv-app-02sudo timedatectl set-timezone Europe/Madridtimedatectl | grep -E "Time zone|synchronized" Time zone: Europe/Madrid (CEST, +0200)System clock synchronized: yessudo apt update && sudo apt full-upgrade -y[ -f /var/run/reboot-required ] && echo "Reinicio necesario"Reinicio necesariosudo reboottimedatectl tiene que decir synchronized: yes (Ubuntu usa systemd-timesyncd). Un servidor con la hora mal falla en certificados, en Kerberos y en los logs correlacionados con el resto.
2. Usuario de administración y sudo
Un usuario por persona, nunca una cuenta compartida. root sin contraseña y sin acceso por SSH.
sudo adduser laurasudo usermod -aG sudo laurasudo mkdir -p /home/laura/.ssh && sudo chmod 700 /home/laura/.sshecho "ssh-ed25519 AAAAC3Nza... laura@laptop" | sudo tee /home/laura/.ssh/authorized_keyssudo chmod 600 /home/laura/.ssh/authorized_keys && sudo chown -R laura:laura /home/laura/.ssh# Probar desde tu equipo, en OTRA ventana, antes de seguir:# ssh laura@srv-app-02 → debe entrar sin pedir contraseña3. SSH solo con claves
sudo nano /etc/ssh/sshd_config.d/10-hardening.confPasswordAuthentication noPermitRootLogin noKbdInteractiveAuthentication noMaxAuthTries 3sudo sshd -t && sudo systemctl reload sshsudo sshd -T | grep -E "^(passwordauthentication|permitrootlogin)"passwordauthentication nopermitrootlogin nosshd -t comprueba la sintaxis antes de recargar: un error aquí con la sesión cerrada es un viaje a la consola. Y la regla de oro: no cierres la sesión actual hasta haber entrado con otra usando solo la clave.
Los ficheros en /etc/ssh/sshd_config.d/ se cargan antes que sshd_config y la primera aparición de cada opción gana. Si Ubuntu ya trae ahí un 50-cloud-init.conf con PasswordAuthentication yes, tu fichero 10-… lo adelanta por orden alfabético.
4. Firewall con ufw
sudo ufw default deny incomingsudo ufw default allow outgoingsudo ufw allow from 10.20.0.0/16 to any port 22 proto tcp comment "SSH desde la red de IT"sudo ufw allow 443/tcp comment "HTTPS app"sudo ufw enableFirewall is active and enabled on system startupsudo ufw status numbered To Action From -- ------ ----[ 1] 22/tcp ALLOW IN 10.20.0.0/16 # SSH desde la red de IT[ 2] 443/tcp ALLOW IN Anywhere # HTTPS appufw es una capa sobre nftables; lo que no está en la lista no entra. Limitar SSH a la red de administración o a la VPN es la medida que más ataques automáticos quita de los logs.
5. Actualizaciones de seguridad automáticas
sudo apt install -y unattended-upgradessudo dpkg-reconfigure -plow unattended-upgrades # responde Sísudo nano /etc/apt/apt.conf.d/50unattended-upgradesUnattended-Upgrade::Allowed-Origins { "${distro_id}:${distro_codename}-security";};Unattended-Upgrade::Automatic-Reboot "false";Unattended-Upgrade::Mail "it@contoso.com";sudo unattended-upgrade --dry-run --debug 2>&1 | tail -n 3Solo el origen -security: los parches de seguridad entran solos cada noche, el resto (y los reinicios) se hacen en la ventana de cambios con apt full-upgrade. /var/log/unattended-upgrades/ guarda lo que instaló cada noche.
6. Comprobación final
hostnamectl --static; timedatectl show -p NTPSynchronized --valuesrv-app-02yessudo ss -tlnp | awk 'NR==1 || /LISTEN/' | awk '{print $4, $7}'Local Address:Port Process0.0.0.0:22 users:(("sshd",pid=812,fd=3))0.0.0.0:443 users:(("nginx",pid=1204,fd=6))sudo ufw status | head -n 1; systemctl is-active unattended-upgradesStatus: activeactivesudo journalctl -p err -b --no-pager | tail -n 5ss -tlnp es la lista de lo que escucha: si hay algo que no esperas (una base de datos en 0.0.0.0, un panel de administración), o se cierra o se limita a 127.0.0.1.
Siguientes pasos
- Instala el script de comprobación de la guía de Bash en cron, y fail2ban si SSH tiene que estar expuesto.
- Para más de un servidor, la secuencia entera de esta guía es un playbook de Ansible de 40 líneas (Nivel 3).
- Ubuntu Landscape (Nivel 3) hace el inventario, el parcheo y los informes de toda la flota desde una consola.
¿Falta algo o en tu entorno es distinto? Escríbeme y lo corrijo.
Tech Career Lab · newsletter
¿Te ha servido? Cada dos semanas envío una idea práctica para perfiles IT: LinkedIn, proyectos, networking y procesos de selección.
Apúntate y llévate las 33 ideas →