GuíasGuides · Nivel 2Level 2

Ubuntu Server: los primeros 30 minutos tras la instalaciónUbuntu Server: the first 30 minutes after installation

Usuario con sudo, SSH solo con claves, ufw, actualizaciones automáticas de seguridad, hora y nombre. Lo que convierte un Ubuntu recién instalado en un servidor que puedes dejar solo.A sudo user, SSH with keys only, ufw, automatic security updates, time and hostname. What turns a fresh Ubuntu into a server you can leave alone.

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.pub en 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

bash · servidor Ubuntu
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 reboot

timedatectl 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.

bash · servidor Ubuntu
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ña

3. SSH solo con claves

bash · servidor Ubuntu
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 no

sshd -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

bash · servidor Ubuntu
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 app

ufw 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

bash · servidor Ubuntu
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 3

Solo 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

bash · servidor Ubuntu
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 5

ss -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.

What you'll get

An Ubuntu Server (22.04 or 24.04 LTS) hardened just enough for production: nobody gets in with a password, the firewall opens only what you register, security patches install themselves, and the system has the right name and time. Thirty minutes that save you an incident.

Before you start

  • Console access (hypervisor or KVM) or SSH to the user created at install time.
  • Your SSH public key (~/.ssh/id_ed25519.pub on your device; if you don't have one, ssh-keygen -t ed25519).
  • Agreed with the team: server name, which services it will provide and which ports to open.

1. Name, time and first update

bash · Ubuntu server
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 "Reboot required"Reboot requiredsudo reboot

timedatectl has to say synchronized: yes (Ubuntu uses systemd-timesyncd). A server with the wrong time fails on certificates, on Kerberos, and in logs correlated with everything else.

2. Admin user and sudo

One user per person, never a shared account. root with no password and no SSH access.

bash · Ubuntu server
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# Test from your device, in ANOTHER window, before going on:#   ssh laura@srv-app-02   → must log in without asking for a password

3. SSH with keys only

bash · Ubuntu server
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 no

sshd -t checks the syntax before reloading: a mistake here with the session closed means a trip to the console. And the golden rule: don't close the current session until you have logged in with another one using only the key.

Files in /etc/ssh/sshd_config.d/ load before sshd_config and the first occurrence of each option wins. If Ubuntu already ships a 50-cloud-init.conf there with PasswordAuthentication yes, your 10-… file overrides it by alphabetical order.

4. Firewall with ufw

bash · Ubuntu server
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 from the IT network"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 from the IT network[ 2] 443/tcp                    ALLOW IN    Anywhere        # HTTPS app

ufw is a layer over nftables; what is not on the list does not get in. Limiting SSH to the admin network or the VPN is the measure that removes the most automated attacks from the logs.

5. Automatic security updates

bash · Ubuntu server
sudo apt install -y unattended-upgradessudo dpkg-reconfigure -plow unattended-upgrades    # answer Yessudo 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 3

Only the -security origin: security patches install themselves every night, the rest (and reboots) happen in the change window with apt full-upgrade. /var/log/unattended-upgrades/ keeps what was installed each night.

6. Final check

bash · Ubuntu server
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 5

ss -tlnp is the list of what is listening: if there is something you don't expect (a database on 0.0.0.0, an admin panel), either close it or bind it to 127.0.0.1.

Next steps

  • Install the check script from the Bash guide in cron, and fail2ban if SSH has to be exposed.
  • For more than one server, the whole sequence in this guide is a 40-line Ansible playbook (Level 3).
  • Ubuntu Landscape (Level 3) does inventory, patching and reports for the whole fleet from one console.

Is something missing, or different in your environment? Get in touch and I'll fix it.

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.Found this useful? Every two weeks I send one practical idea for IT professionals: LinkedIn, projects, networking and hiring processes.

Apúntate y llévate las 33 ideasSign up and get the 33 ideas →