Qué hacemos y por qué
- No trabajamos como root, creamos un administrador con sudo.
- La conexión se realiza exclusivamente a través de una clave SSH, las contraseñas están desactivadas.
- Activamos UFW: «Todo está cerrado, excepto lo necesario». »
- Instalamos Fail2Ban: bloquea las direcciones IP al seleccionar una contraseña/clave.
Usuarios y grupos administradores
Creamos un usuario y lo añadimos a sudo + al grupo SSH restrictivo:
sudo adduser admin
sudo usermod -aG sudo admin
sudo groupadd -f sshusers
sudo usermod -aG sshusers admin
id admin
Clave SSH: generar y añadir
En local (Windows/macOS/Linux):
ssh-keygen -t ed25519 -C "key-for-admin"
En el servidor como administrador root o existente:
sudo -u admin -H bash -lc 'mkdir -p ~/.ssh && chmod 700 ~/.ssh'
sudo -u admin -H bash -lc 'cat >> ~/.ssh/authorized_keys' # insert content *.pub, затем Ctrl+D
sudo -u admin -H bash -lc 'chmod 600 ~/.ssh/authorized_keys'
Importante: solo la clave pública .pub se envía al servidor. La clave privada se almacena localmente.
Reforzar SSH (desactivar las contraseñas y la conexión root)
Abra /etc/ssh/sshd_config e indique los siguientes elementos:
PermitRootLogin no
PasswordAuthentication no
PubkeyAuthentication yes
AllowGroups sshusers
Reiniciar SSH:
sudo systemctl restart sshd
Comprueba que las claves funcionan antes de desactivar las contraseñas, ya que de lo contrario perderás el acceso.
UFW: «cerrado por defecto»
sudo ufw default deny incoming
sudo ufw default allow outgoing
sudo ufw allow OpenSSH # port 22
sudo ufw allow 80,443/tcp # if you need a website
sudo ufw enable
sudo ufw status numbered
¿Necesita puertos adicionales (por ejemplo, 8080)? Añada una regla explícita: sudo ufw allow 8080/tcp.
Fail2Ban: instalación e inicio automático
sudo apt -y install fail2ban
sudo systemctl enable --now fail2ban
sudo systemctl status fail2ban --no-pager
Configuración de Fail2Ban: jail.local para sshd
Crear/modificar
/etc/fail2ban/jail.local:
[DEFAULT]
bantime = 1h
findtime = 10m
maxretry = 5
backend = systemd
bantime.increment = true
[sshd]
enabled = true
port = ssh
filter = sshd
logpath = /var/log/auth.log
action = %(action_mwl)s
Reinicio:
sudo systemctl restart fail2ban
%(action_mwl)s envía un correo electrónico (si el correo electrónico está configurado) + un registro y también bloquea la dirección IP.
Integración de Fail2Ban con UFW (alternativa)
Cree un archivo
/etc/fail2ban/jail.d/ufw-sshd.local:
[sshd]
enabled = true
action = ufw
maxretry = 5
findtime = 10m
bantime = 1h
Solicitar:
sudo systemctl restart fail2ban
Verificación del funcionamiento y los protocolos
sudo fail2ban-client status
sudo fail2ban-client status sshd
sudo tail -n 200 /var/log/fail2ban.log
sudo journalctl -u ssh --since "today"
sudo ufw status verbose
Para probar el bloqueo: realice entre 5 y 6 intentos fallidos de conexión desde otro nodo y compruebe el estado de sshd: la dirección IP aparecerá en la lista de direcciones IP bloqueadas.
Bonificación de seguridad (opcional)
- Cambie el puerto SSH (no es una medida de seguridad, pero reduce el ruido del escáner): puerto 2222 en sshd_config + ufw allow 2222/tcp.
- Limite el acceso SFTP (chroot) para el grupo.
- Active la 2FA para SSH: libpam-google-authenticator + configuración de /etc/pam.d/sshd y sshd_config (AuthenticationMethods publickey,keyboard-interactive).
- Limite los intentos de Sudo: passwd -l root, sudo visudo con timestamp_timeout=5.
Lista de control de seguridad
- La conexión por clave funciona, las contraseñas y la conexión root están desactivadas.
- UFW: rechazar las conexiones entrantes/autorizar las conexiones salientes, solo se permiten los puertos necesarios.
- Fail2Ban protege sshd (y opcionalmente nginx/postfix/…); se comprueban los protocolos.
- Se realiza una prueba de bloqueo, se documentan las reglas y los accesos.