Dimarts, novembre 18, 2025
LINUX

Com configurar un servidor SSH segur

SSH és una d’aquestes coses que tot administrador dona per fetes. S’instal·la, s’obre el port 22 i es dona per acabada la feina. Però quan algú accedeix amb claus robades, quan el sistema s’omple d’intents de força bruta, o quan un desenvolupador puja una clau privada al repositori per error, tot aquest “ja està” es converteix en hores perdudes. Aquí no es tracta de seguir una checklist, sinó d’entendre quines coses funcionen bé en producció i quins detalls convé no deixar a l’atzar.

Lo primer: no confiïs en la configuració per defecte

OpenSSH és sòlid, però la configuració per defecte està pensada per a un entorn genèric. No està malament, però tampoc és bona idea deixar-la sense revisar. Gairebé sempre hi ha coses habilitades que no necessites i d’altres que convé ajustar des del primer moment.

Arxiu clau: /etc/ssh/sshd_config

Fes un backup de l’original abans de tocar res:

cp /etc/ssh/sshd_config /etc/ssh/sshd_config.original

Què canviar sempre (o gairebé sempre)

1. Desactiva l’accés per contrasenya

Si estàs administrant un entorn seriós, l’accés per contrasenya sobra. No importa si la contrasenya és forta. Algú l’escriurà en un post-it, o entrarà des d’un client compromès. El que et protegeix de veritat són les claus públiques.

A sshd_config:

PasswordAuthentication no
ChallengeResponseAuthentication no

Quan no fer-ho encara: si no tens un sistema de distribució de claus ben muntat (Ansible, scripts, LDAP, etc.) o estàs en la fase inicial de desplegament, desactivar això prematurament et deixarà fora. Millor fer-ho com a pas final, després d’assegurar-te que tot l’equip pot accedir amb claus correctament.

2. Fes servir AllowUsers o AllowGroups

Això és una xarxa de seguretat que ha salvat més d’un ensurt. Tot i que creguis que només tu pots accedir, si sshd permet que qualsevol ho intenti, el risc segueix aquí. Pots restringir per usuari o grup:

AllowUsers admin@192.168.1.*
AllowGroups sshusers

Fer servir grups dona més flexibilitat, sobretot en entorns amb més de dues persones. Però l’important és tenir el filtre.

Compte: No bloquegis tots els accessos sense provar abans que el teu continuï funcionant.

3. Canvia el port, però sense enganyar-te

Moure SSH a un altre port (ex. 2222) no et protegeix realment, però redueix el soroll. Si tens logs plens d’intents automàtics i el teu WAF no filtra bé, canviar el port pot donar-te un respir.

A sshd_config:

Port 2222

Si tens polítiques corporatives que ho impedeixen, almenys assegura’t que el port 22 només està obert en els rangs d’IP interns o a través de VPN.

Quins xifrats i algoritmes deixar actius

Això és un d’aquests temes on molts scripts i tutorials fan copy-paste sense context. Elimina algoritmes antics, sí. Però no tots els entorns tenen clients moderns. Si tens dispositius embeguts, appliances antics o scripts que fan servir PuTTY en versions desactualitzades, eliminar suport per a rsa o diffie-hellman pot donar problemes.

Configuració recomanada per a un entorn modern:

HostKey /etc/ssh/ssh_host_ed25519_key
HostKey /etc/ssh/ssh_host_rsa_key

KexAlgorithms curve25519-sha256@libssh.org
Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com
MACs hmac-sha2-512,hmac-sha2-256

Evita: diffie-hellman-group1-sha1, cbc i qualsevol hmac-md5. Si no estàs segur, logueja les connexions amb LogLevel DEBUG temporalment i revisa què fan servir els clients reals.

Temps de vida de sessió i reintents

Aquí hi ha diversos ajustos petits que eviten abusos i també t’estalvien recursos.

LoginGraceTime 20
MaxAuthTries 3
MaxSessions 2
  1. LoginGraceTime evita que una connexió sense autenticar-se es quedi oberta més del necessari.
  2. MaxAuthTries limita intents per connexió. No fa miracles, però ajuda.
  3. MaxSessions controla connexions multiplexades, per si fas servir ControlMaster o hi ha algun script mal dissenyat.

Fes servir Fail2Ban encara que tinguis altres capes

Molts ho consideren redundant si ja tens firewall, WAF o SIEM. Però la realitat és que fail2ban et protegeix ràpid, reacciona al patró de logs reals i no depèn d’infraestructura externa. Quan tens un node aïllat o un entorn de proves exposat, és el que pot evitar que algú l’enfonsi per força bruta.

Instal·lació típica a Debian/Ubuntu:

apt install fail2ban

Després activa i ajusta la presó de SSH a /etc/fail2ban/jail.local:

[sshd]
enabled = true
port    = ssh
filter  = sshd
logpath = /var/log/auth.log
maxretry = 3
bantime = 600

He vist entorns amb firewalls complexos que tot i així tenien SSH spamejat per bots. Fail2ban talla això abans que arribi al log d’alertes.

No oblidis el .ssh/authorized_keys i els seus permisos

Aquest és un punt bàsic, però on es continuen cometent errors tontos. El directori .ssh ha de ser 700, l’arxiu authorized_keys ha de ser 600. El propietari, sense excepció, ha de ser l’ usuari corresponent.

chmod 700 ~/.ssh
chmod 600 ~/.ssh/authorized_keys
chown -R usuario:usuario ~/.ssh

He tingut casos en què una clau no funcionava, tot semblava correcte, i va resultar que algú havia copiat l’arxiu com a root.

Logging que et serveixi de veritat

Canviar el nivell de log en sshd_config a VERBOSE o DEBUG pot ajudar en entorns de proves, però no hauries de deixar-ho així en producció. Augmenta el volum i pot generar problemes si no estàs rotant logs correctament. Però sí que convé assegurar-se que el sistema estigui recollint /var/log/auth.log i que les teves eines de monitoratge el llegeixin.

En molts entorns, els incidents es detecten per logs d’Apache, però els accessos sospitosos per SSH no es revisen fins que ja hi ha alguna cosa rara. Una política que apliquem en diversos entorns crítics és alertar en el SIEM si hi ha més de 5 accessos fallits des d’una mateixa IP en menys d’1 minut.

Accés extern: VPN o doble capa

Permetre accés SSH des de fora de la xarxa interna és un risc que convé justificar. Si la màquina està al núvol, l’ accés extern pot ser inevitable. Però si està dins d’un entorn corporatiu, exposar el port SSH directament a internet és la forma més ràpida d’atraure escaneig i atacs automatitzats.

Opcions més comunes i el que solen implicar:

  1. VPN + SSH només accessible des de la VPN: Aquesta és l’opció més segura i menys propensa a sorolls. WireGuard o OpenVPN funcionen bé, tot i que WireGuard és més lleuger i senzill de desplegar si només necessites accés administratiu.
  2. Jump host (bastion): Accedeixes a una única màquina (auditada) des de fora, i des d’aquí a la resta. Funciona, però has de tractar aquesta màquina com a punt de fallada única. També implica polítiques més cuidades amb AgentForwarding i registres d’activitat.
  3. Port knocking o firewall dinàmic: Tècnicament viable, però en producció acaba sent emprenyador, especialment si hi ha automatismes o múltiples administradors. No l’utilitzo, excepte en desplegaments experimentals o entorns on només jo administro.

Si no pots evitar exposar SSH a internet, almenys limita per IP sempre que sigui possible amb iptables, nftables o firewalld.

Validació de claus públiques: no assumeixes que tot està bé

Una clau pública pot estar mal copiada, tenir caràcters corruptes, o estar incompleta. Si algú et diu que “ja va posar la seva clau a authorized_keys i no funciona”, no perdis una hora comparant configuracions. Fes el següent primer:

ssh-keygen -lf ~/.ssh/authorized_keys

Això et dona el fingerprint. Si no el mostra o dona error, la clau està mal formada. També pots fer servir:

ssh -v usuario@servidor

Per veure si està fent servir la clau correcta. De vegades el client ni tan sols la intenta perquè no està ben carregada en ssh-agent.

Una altra opció útil:

sshd -T | grep authorizedkeysfile

Assegura que sshd està llegint l’arxiu correcte. En sistemes amb Match en sshd_config, aquest detall pot canviar segons l’usuari o l’origen.

Compte amb PermitRootLogin

Aquí no hi ha una única regla que serveixi per a tothom. Desactivar-lo totalment (PermitRootLogin no) és bona pràctica si fas servir usuaris amb sudo. Però en alguns entorns (servidors efímers, scripts automatitzats, contenidors amb accés restringit) permetre-ho amb clau pública (without-password o prohibit-password en versions anteriors) pot ser acceptable.

Si decideixes mantenir-lo actiu:

  1. Que sigui només amb clau pública.
  2. Requereix controls d’ accés estrictes.
  3. Monitoritza cada connexió de root (idealment, integra amb un SIEM o almenys logueja-ho amb un tag especial per a root).

Certificats SSH: útil en equips grans, però amb condicions

Els certificats SSH signats amb una CA interna (ssh-keygen -s) no es fan servir tant com hauria de ser. Són útils quan tens molts usuaris o servidors, i vols evitar distribuir claus individuals manualment.

Avantatges reals:

  1. Pots revocar certificats sense tocar cada màquina.
  2. Un sol punt d’autoritat per validar qui es pot connectar.
  3. Redueixes la gestió de authorized_keys.

Inconvenients i errors comuns:

  1. Requereix mantenir una CA segura, amb política d’ emissió i expiració ben definida.
  2. Molts administradors no estan familiaritzats amb com configurar-ho, i si algú trenca un certificat sense avisar, es perd l’accés sense saber per què.
  3. Documentar-ho bé és clau. Si es fa servir, que tots a l’ equip sàpiguen signar, verificar i revocar.

No ho recomano per a equips petits o on el coneixement no està distribuït. Però en entorns amb rotació freqüent o múltiples rols, estalvia molt de temps.

SFTP: desactíva’l si no el necessites

SSH porta suport per a SFTP per defecte. Si ningú al teu entorn necessita transferències per aquest mitjà, desactiva’l. Un accés limitat sempre és millor que un d’ ampli:

Subsistema sftp /bin/false

Si el necessites, restringeix al mínim possible. Un Match en sshd_config per grup o usuari ajuda a no donar més permisos dels necessaris:

Match Group sftpusers
    ChrootDirectory /sftp/%u
    ForceCommand internal-sftp
    AllowTcpForwarding no
    X11Forwarding no

Forwarding i túnels: controla el que realment es fa servir

SSH pot reenviar ports (-L, -R, -D), obrir sessions gràfiques (X11Forwarding), reenviar el ssh-agent, i més. Tot això està habilitat per defecte, i rara vegada es necessita tot.

Desactiva o restringeix el que no es fa servir:

AllowTcpForwarding no
X11Forwarding no
PermitTunnel no
AllowAgentForwarding no

Si algú necessita això, ho pot demanar amb justificació. Deixar-ho tot obert només dona més superfície a revisar en un incident.

Errors freqüents que convé evitar

Encara que portis anys muntant servidors SSH, hi ha coses que continuen apareixent en producció:

  1. Canviar el port sense afegir-lo a firewalld o ufw: Molts creuen que canviar el port “és segur” i obliden permetre’l al firewall. Després perden accés.
  2. Editar sshd_config sense provar-ho: Abans de fer canvis dràstics, llença una sessió alternativa i no tanquis l’actual. Així pots tornar enrere si et quedes fora.
  3. No reiniciar sshd després de canviar la configuració: Alguns ajustos requereixen systemctl restart sshd, no només reload. He vist canvis en ports o algoritmes ignorats perquè no es va reiniciar.
  4. Bloquejar-te tu mateix amb AllowUsers mal escrit: Un espai, una IP mal posada, o un nom curt quan el sistema fa servir FQDN, i et quedes fora.
  5. No tenir una consola fora de banda accessible (KVM, iLO, IPMI): Si bloqueges SSH i no hi ha forma d’accedir físicament o per consola, només queda el desplaçament físic o el tiquet de suport.

Scripts i automatització

Quan ja tens una configuració estàndard que funciona, no perdis temps repetint-la a mà. Un playbook d’Ansible o almenys un script que:

  1. Instal·li els paquets necessaris
  2. Puja el sshd_config
  3. Reiniciï el servei
  4. Configura fail2ban
  5. Afegeixi les claus públiques necessàries

T’estalviarà errors manuals i mantenir la coherència. Aquest pot ser un exenple:

#!/bin/bash

set -euo pipefail

# Configuració
SSH_PORT=2222
ADMIN_USER="admin"
PUBKEY_PATH="/tmp/admin_id_rsa.pub"

# Verificacions previes
if [[ ! -f "$PUBKEY_PATH" ]]; then
  echo "Error: no s’ha trobat la clau pública a $PUBKEY_PATH"
  exit 1
fi

# Instal·lació de paquets
echo "[+] Instal·lant openssh-server i fail2ban..."
apt-get update -qq
apt-get install -y openssh-server fail2ban


# Crear usuari d’ administració si no existeix
if ! id "$ADMIN_USER" &>/dev/null; then
  echo "[+] Creant usuari $ADMIN_USER..."
  adduser --disabled-password --gecos "" "$ADMIN_USER"
fi

echo "[+] Configurant clau SSH per $ADMIN_USER..."
install -d -m 700 "/home/$ADMIN_USER/.ssh"
install -m 600 "$PUBKEY_PATH" "/home/$ADMIN_USER/.ssh/authorized_keys"
chown -R "$ADMIN_USER:$ADMIN_USER" "/home/$ADMIN_USER/.ssh"

# Configurar SSH
SSHD_CONFIG="/etc/ssh/sshd_config"
BACKUP="/etc/ssh/sshd_config.bak.$(date +%s)"

echo "[+] Fent còpia de seguretat de $SSHD_CONFIG -> $BACKUP"
cp "$SSHD_CONFIG" "$BACKUP"

echo "[+] Aplicant configuració segura a sshd_config..."

cat > "$SSHD_CONFIG" <<EO
Port $SSH_PORT
Protocol 2
PermitRootLogin no
PasswordAuthentication no
ChallengeResponseAuthentication no
UsePAM yes
X11Forwarding no
AllowTcpForwarding no
AllowAgentForwarding no
PermitTunnel no
ClientAliveInterval 300
ClientAliveCountMax 2
LoginGraceTime 20
MaxAuthTries 3
AllowUsers $ADMIN_USER
AuthorizedKeysFile .ssh/authorized_keys
Subsystem sftp /bin/false
EOF

echo "[+] Reiniciant SSH al port $SSH_PORT..."
systemctl restart ssh

# Configurar fail2ban bàsic
JAIL_LOCAL="/etc/fail2ban/jail.local"

echo "[+] Configurant fail2ban per SSH..."
cat > "$JAIL_LOCAL" <<EOF
[sshd]
enabled = true
port = $SSH_PORT
filter = sshd
logpath = /var/log/auth.log
maxretry = 4
bantime = 1h
EOF

systemctl restart fail2ban
systemctl enable fail2ban

echo "[+] Configuració complerta."
echo "=> Asegura’t de permetre el port $SSH_PORT al firewall si aplica.

Com fer-lo servir

  1. Assegura’t de tenir una clau pública llesta. Per exemple:
ssh-keygen -t ed25519 -f ~/.ssh/id_ed25519
cp ~/.ssh/id_ed25519.pub /tmp/admin_id_rsa.pub
  • Puja l’script i la clau pública al servidor.
  • Executa l’script com a root o amb sudo.
chmod +x setup-secure-ssh.sh
sudo ./setup-secure-ssh.sh
  • Abans de tancar la sessió SSH actual, obre una altra fent servir el nou port i usuari per comprovar que tot funciona:
ssh -p 2222 admin@servidor

Ajustaments habituals

  1. Si la teva xarxa requereix accés des d’un rang IP, pots afegir regles amb ufw o iptables.
  2. Pots posar la configuració a Ansible o Terraform si treballes amb infraestructura declarativa.
  3. Si la teva distro fa servir firewalld o nftables, inclou la regla per al nou port al mateix script.
  4. Si treballes a Red Hat, canvia els paths de auth.log i tingues en compte els noms de servei (sshd continua sent igual, però els logs poden anar a secure).

Deixa un comentari

L'adreça electrònica no es publicarà. Els camps necessaris estan marcats amb *