Cómo configurar un bastión SSH con claves y autenticación de dos factores (2FA) en Ubuntu Server 22.04

Linux & Sistemas · Por · Publicado el · Actualizado el · 9 min de lectura

Bahías frontales de un dispositivo de almacenamiento en rack, enfoque en los compartimentos de disco
Detalle de unidades de almacenamiento en un equipo de rack, representando infraestructura de servidores Foto: Jakub Zerdzicki / Pexels

Esta guía muestra cómo configurar un bastión SSH con claves y autenticación de dos factores en Ubuntu Server 22.04. Tendrás un jump host que solicita clave pública y TOTP, reduciendo el riesgo de accesos no autorizados y facilitando la auditoría del tráfico SSH.

Requisitos y arquitectura del bastión SSH

Un bastión SSH es un servidor de salto centralizado. Centraliza los accesos administrativos a redes internas y aplica políticas estrictas. Aquí exigiremos clave pública y TOTP (2FA) para iniciar sesión en el bastión.

Antes de empezar, asegúrate de estos puntos. Los cambios en SSH pueden bloquear tu acceso. Mantén una sesión abierta hasta que todo funcione y ten acceso por consola para emergencias.

Si aún no has instalado el sistema, sigue el paso a paso en cómo instalar Ubuntu Server.

  • Ubuntu Server 22.04 actualizado, con IP pública.
  • Acceso sudo al servidor y copia de seguridad reciente de la configuración de SSH.
  • Clave SSH en tu equipo ya creada (ed25519 preferible).
  • Aplicación TOTP en el móvil (Aegis, Google Authenticator, Authy, etc.).
  • Lista de los hosts internos a los que accederás vía bastión.
  • Firewall planificado para exponer solo el puerto 22 del bastión.

Actualiza el sistema, crea el usuario de acceso e instala paquetes

Crearemos un usuario dedicado para el bastión, instalaremos OpenSSH y el módulo de 2FA. También activaremos la sincronización horaria, esencial para TOTP.

Sustituye el valor de PUBLIC_KEY por tu clave real. No pegues claves de ejemplo.

Para un hardening detallado del firewall, consulta también Configurar firewall en Ubuntu con UFW.

# 1) Atualize e instale pacotes
sudo apt update && sudo apt -y upgrade
sudo apt install -y openssh-server libpam-google-authenticator qrencode

# 2) Habilite o serviço SSH e NTP
timedatectl set-ntp true
sudo systemctl enable --now ssh

# 3) Crie usuário dedicado (ajuste o nome, se quiser)
USER=bastion
sudo adduser --disabled-password --gecos "" "$USER"
sudo usermod -aG sudo "$USER"

# 4) Adicione sua chave pública ao usuário (substitua pela sua)
PUBLIC_KEY='ssh-ed25519 AAAA... cole_sua_chave_aqui'
sudo -u "$USER" mkdir -p "/home/$USER/.ssh"
echo "$PUBLIC_KEY" | sudo tee "/home/$USER/.ssh/authorized_keys" >/dev/null
sudo chown -R "$USER:$USER" "/home/$USER/.ssh"
sudo chmod 700 "/home/$USER/.ssh"
sudo chmod 600 "/home/$USER/.ssh/authorized_keys"

Habilita TOTP con Google Authenticator vía PAM

Generaremos el secreto TOTP del usuario e integraremos PAM para pedir el código al conectar vía SSH. Hazlo para cada administrador que accederá al bastión.

El comando siguiente es interactivo. Guarda los códigos de recuperación. Si pierdes el app y esos códigos, podrías quedar sin acceso.

Después insertaremos la línea del módulo en el PAM del sshd. Hacemos una copia de seguridad antes de modificar.

# 1) Gere o segredo e códigos TOTP para o usuário (interativo)
sudo -u bastion -H bash -lc 'google-authenticator'

# 2) Faça backup e habilite o módulo no PAM do sshd
sudo cp /etc/pam.d/sshd /etc/pam.d/sshd.bak
# Insere a linha na primeira linha do arquivo PAM
sudo sed -i '1iauth required pam_google_authenticator.so' /etc/pam.d/sshd

# Valide que o arquivo não ficou corrompido (visual)
sed -n '1,10p' /etc/pam.d/sshd

Exigir clave + 2FA en OpenSSH y aplicar hardening

Ahora forzaremos que el inicio de sesión use clave pública Y TOTP. También aplicaremos ajustes de seguridad recomendados en sshd.

Crearemos un archivo de inclusión en sshd_config.d. No cierres la sesión actual hasta probar con otra conexión.

Abajo tienes los parámetros y el motivo de cada uno. Ajusta AllowUsers con los usuarios autorizados.

Parámetro Efecto Por qué
PasswordAuthentication no Desactiva contraseña en SSH Evita ataques de fuerza bruta a contraseñas
AuthenticationMethods publickey,keyboard-interactive:pam Exige clave + TOTP Factor doble obligatorio
PermitRootLogin no Bloquea root remoto Reduce el impacto de credenciales filtradas
MaxAuthTries 3 Limita intentos Dificulta fuerza bruta
LoginGraceTime 20s Ventana corta de login Reduce sesiones pendientes
AllowUsers bastion Restringe a usuarios Superficie de ataque menor
X11Forwarding no / AgentForwarding no Bloquea reenvíos innecesarios Menos vectores de pivoteo
AllowTcpForwarding yes Permite ProxyJump Necesario para usar bastión como jump host
# 1) Arquivo de hardening (incluído pelo sshd)
cat <<'EOF' | sudo tee /etc/ssh/sshd_config.d/10-hardening.conf >/dev/null
KbdInteractiveAuthentication yes
UsePAM yes
PubkeyAuthentication yes
PasswordAuthentication no
AuthenticationMethods publickey,keyboard-interactive:pam
PermitRootLogin no
AllowUsers bastion
MaxAuthTries 3
LoginGraceTime 20s
ClientAliveInterval 300
ClientAliveCountMax 2
X11Forwarding no
AllowAgentForwarding no
AllowTcpForwarding yes
GatewayPorts no
PermitTunnel no
#Banner /etc/issue.net
EOF

# 2) Teste a configuração e reinicie
sudo sshd -t && sudo systemctl restart ssh

# 3) Teste em um novo terminal antes de encerrar esta sessão

Firewall UFW y protección contra intentos

Limita la exposición del puerto 22 y aplica rate limiting. Si puedes, permite solo orígenes conocidos. Opcionalmente usa Fail2ban para bloquear IPs tras fallos repetidos.

Para otras reglas y escenarios, consulta la guía de UFW ya enlazada. Si usar VPN es una opción, un bastión detrás de WireGuard road‑warrior aumenta la seguridad.

# 1) UFW: permitir e aplicar rate limit
sudo ufw allow OpenSSH
sudo ufw limit OpenSSH
# Opcional: restrinja a IPs conhecidos (substitua 203.0.113.10)
# sudo ufw delete allow OpenSSH
# sudo ufw allow from 203.0.113.10 to any port 22 proto tcp
sudo ufw enable
sudo ufw status verbose

# 2) Fail2ban básico para sshd
sudo apt install -y fail2ban
sudo tee /etc/fail2ban/jail.local >/dev/null <<'EOF'
[sshd]
enabled = true
bantime = 1h
findtime = 10m
maxretry = 4
EOF
sudo systemctl restart fail2ban
sudo fail2ban-client status sshd

Configura ProxyJump en el cliente SSH

Usa ProxyJump para acceder a hosts internos a través del bastión de forma transparente. Así te autenticas en el bastión y SSH encamina la conexión al destino.

Crea un bloque para el bastión y otro para tus servidores. Ajusta HostName, User e IdentityFile según tu entorno.

  • ProxyJump simplifica: un comando accede a la máquina interna.
  • Funciona con claves y 2FA en el bastión sin exponer hosts internos.
# No seu computador, configure o SSH
mkdir -p ~/.ssh && chmod 700 ~/.ssh
cat <<'EOF' >> ~/.ssh/config
Host bastion
  HostName 198.51.100.10        # IP ou DNS do bastion
  User bastion                   # usuário no bastion
  IdentityFile ~/.ssh/id_ed25519
  IdentitiesOnly yes
  ServerAliveInterval 60

Host app-interno
  HostName 10.0.0.20             # IP interno do destino
  User ubuntu                    # usuário no host interno
  IdentityFile ~/.ssh/id_ed25519
  ProxyJump bastion
EOF
chmod 600 ~/.ssh/config

# Teste o salto
ssh app-interno
# Ou explicitamente:
# ssh -J bastion [email protected]

Cómo confirmar que funcionó y solución de problemas

Usa los comandos abajo para verificar autenticación, logs y hora. La mayoría de problemas con TOTP se deben a desincronización horaria o al orden de métodos en sshd.

Si algo falla, mantén acceso por consola. Evita aplicar cambios sin una ventana de pruebas.

  • Prueba con verbosidad: confirma que pide la clave y luego el TOTP.
  • Verifica la hora con timedatectl; ajústala si hace falta.
  • Revisar los logs del sshd en vivo ayuda a identificar fallos de PAM.
  • Valida la sintaxis: sshd -t antes de reiniciar.
  • Fail2ban muestra bloqueos y contadores.
# Testes de conexão e diagnóstico
ssh -vvv app-interno

# Logs do serviço SSH no bastion
sudo journalctl -u ssh -f

# Validação da configuração
sudo sshd -t

# Sincronismo de tempo
timedatectl status

# Status do Fail2ban
sudo fail2ban-client status sshd

Preguntas frecuentes

¿Cómo recuperar acceso si pierdo mi app TOTP?

Usa uno de los códigos de emergencia generados por google-authenticator durante la configuración. Funcionan como backups de uso único. Si también perdiste esos códigos, será necesario acceso por consola para revertir temporalmente los cambios del PAM/SSHD o registrar un nuevo secreto en el archivo del usuario.

¿Puedo habilitar 2FA solo para algunos usuarios?

Sí. Puedes usar la opción nullok en PAM para hacer el TOTP opcional y controlar quién tiene el archivo ~/.google_authenticator. Sin embargo, para máxima seguridad, es preferible exigir 2FA a todos y usar AllowUsers para listar quién puede acceder al bastión.

¿Funciona con YubiKey u otros tokens?

Sí, pero la configuración cambia. En lugar de TOTP con google-authenticator, puedes integrar PAM con métodos como WebAuthn/U2F. El proceso implica módulos PAM específicos. Esta guía se centra en TOTP por ser simple y ampliamente compatible con clientes SSH.

¿Por qué mi TOTP es rechazado aunque lo escriba bien?

Normalmente es por diferencia horaria entre el servidor y el móvil. Verifica timedatectl y habilita NTP. Confirma también el orden de autenticación en sshd_config y que el módulo pam_google_authenticator esté cargando en /etc/pam.d/sshd.

¿Cómo auditar quién accedió por los saltos?

En el bastión, usa los logs del SSH y, si es necesario, activa logs estructurados y retención centralizada. Combínalos con ProxyJump por usuario, sin compartir cuentas. Puedes correlacionar sesiones por claves públicas e IPs de origen para trazabilidad.

¿Debo deshabilitar AgentForwarding en el bastión?

En general, sí. Deshabilitar AgentForwarding reduce el riesgo de uso indebido de tus claves en hosts comprometidos. ProxyJump no depende de agent forwarding. Actívalo solo si hay una necesidad justificada y con restricciones adicionales.

Sigue elevando la seguridad de tu Linux

Aplica las mismas prácticas en otros servicios: firewall, VPN y monitorización. Consulta las guías relacionadas y refuerza tu entorno.

Ver más guías Linux

Ver también