El archivo de configuración de SSH, con ejemplos

~/.ssh/config guarda ajustes por host, de modo que ssh web puede sustituir un comando largo. ssh lee el archivo de arriba abajo, y para cada opción gana el primer valor que encuentra, así que pon primero los hosts concretos y los valores por defecto de Host * al final. Ejecuta ssh -G web para ver los ajustes finales sin conectar.

Actualizada el . Cada ejemplo se ejecutó con ssh -G en OpenSSH 10.0 sobre Debian 13, usando un ~/.ssh/config real en un contenedor de pruebas.

Un ejemplo que funciona

Include ~/.ssh/config.d/*

Host web
  HostName 203.0.113.10
  User deploy
  Port 2222
  IdentityFile ~/.ssh/id_ed25519_work
  IdentitiesOnly yes

Host *.example.com
  User admin

Host *
  ServerAliveInterval 60
  User user

Ahora ssh web significa ssh -p 2222 -i ~/.ssh/id_ed25519_work deploy@203.0.113.10, y además envía un keepalive cada 60 segundos. Los mismos nombres funcionan con scp, sftp y rsync.

El archivo es ~/.ssh/config. No debe poder escribirlo nadie más, o ssh se detiene con Bad owner or permissions. Ejecuta chmod 600 ~/.ssh/config. Los ajustes de todo el sistema se leen después, desde /etc/ssh/ssh_config.

Con decenas de hosts, el archivo es solo una parte de la respuesta. Consulta cómo gestionar muchos servidores SSH para mantener en orden nombres, grupos y claves.

Gana el primer valor

Esta es la regla que sorprende a la gente. Se aplican todos los bloques Host que coinciden, no solo el primero. Para cada opción, ssh se queda con el primer valor que lee e ignora los posteriores. En el ejemplo:

  • ssh web recibe User deploy, porque su bloque va antes de Host *.
  • ssh db.example.com recibe User admin.
  • ssh other recibe User user, y los tres reciben ServerAliveInterval 60.

Así que pon los hosts concretos arriba y los valores por defecto al final. Si mueves Host * arriba, su User gana en todas partes. Las opciones de la línea de comandos van antes que todo, así que ssh -l other web, ssh other@web y ssh -p 3000 web anulan el archivo.

Hay una excepción que conviene conocer. IdentityFile se acumula: un valor en Host web-* y otro en Host * se prueban ambos, en orden. Añade IdentitiesOnly yes si quieres evitar las claves del agente, y deja IdentityFile fuera de Host * si quieres una clave por host.

Patrones de Host

PatrónCoincide con
Host web dbCualquiera de los dos nombres.
Host *.example.comCualquier nombre que termine en .example.com.
Host web-?web- y un carácter.
Host web-* !web-oldTodos los nombres web- salvo web-old. Una negación sola no coincide con nada: solo excluye de una coincidencia positiva.

El patrón se compara con lo que escribes, no con la dirección a la que se resuelve. %h representa ese nombre, lo que permite nombres cortos:

Host web-*
  HostName %h.example.com

ssh web-1 ahora se conecta a web-1.example.com.

Include

Include ~/.ssh/config.d/*

Esto lee otros archivos como si estuvieran pegados en ese lugar, lo que permite tener un archivo por proyecto. Las rutas relativas parten de ~/.ssh. Necesita OpenSSH 7.3 o posterior.

Ponlo al principio del archivo. Un bloque Host continúa hasta el siguiente, y un Include colocado después forma parte de ese bloque. Lo probamos: con Include debajo de un bloque Host a, los ajustes del archivo incluido no hicieron nada para ningún otro host. Puedes usarlo a propósito, para incluir un archivo solo para algunos hosts.

Match

Match es una forma más potente de Host, con condiciones:

Match host "*.internal" user deploy
  Port 2200

Match exec "test -f /tmp/at-office"
  ProxyJump bastion

El primero se aplica solo cuando se cumplen las dos condiciones. El segundo ejecuta un comando de shell y se aplica si termina con 0, que es como cambias ajustes según la red o el lugar. Ten en cuenta que este comando se ejecuta cada vez que se lee la configuración, incluso con ssh -G.

Las condiciones útiles son host, originalhost, user, localuser, exec, tagged, final y all. host comprueba el nombre después de aplicar HostName, y originalhost comprueba lo que escribiste. final hace que ssh lea la configuración una segunda vez, lo que permite a un bloque ver el resultado de la primera pasada:

Host *.corp
  HostName %h.example.com

Match final host *.example.com
  User admin

En OpenSSH 9.4 y posteriores, también puedes etiquetar hosts y seleccionarlos con Match tagged o ssh -P:

Host web
  Tag prod

Match tagged prod
  User deploy

ProxyJump tiene su propia página: cómo usar ProxyJump y un host de salto en SSH.

Ver el resultado con ssh -G

ssh -G web

Esto imprime todos los ajustes que ssh usaría para ese host, con todos los archivos y reglas aplicados, y termina sin conectar. Es la forma más rápida de responder a "¿por qué usa ese usuario?":

ssh -G web | grep -E '^(hostname|user|port|identityfile) '

Para saber si tu configuración es la causa de un problema, ignórala en un comando. -F none omite tanto el archivo del usuario como el del sistema:

ssh -F none user@203.0.113.10

Para la propia conexión, ssh -v web imprime qué líneas de la configuración se aplicaron.

Errores comunes

  • Un Host * al principio que anula todo lo que hay debajo.
  • Una opción global al final del archivo. Las opciones fuera de un bloque deben ir antes del primer Host. Al final, pertenecen al último bloque.
  • Una errata en una opción. ssh se detiene con Bad configuration option y no conecta con nada, en ningún host. Para una opción que solo conocen algunas versiones, pon IgnoreUnknown y el nombre de la opción encima.
  • Secretos en el archivo. Contiene rutas a claves, no claves, y no tiene opción de contraseña. Así es como debe seguir.

Preguntas

¿Dónde está el archivo de configuración de SSH?

En Linux y macOS es ~/.ssh/config en tu carpeta personal. En Windows es C:\Users\nombre\.ssh\config. No existe hasta que lo creas. Los ajustes del sistema en /etc/ssh/ssh_config se leen después.

¿Por qué ssh ignora un ajuste de mi config?

Otro bloque que coincide definió la misma opción antes, y gana el primer valor. Ejecuta ssh -G seguido del nombre del host para ver el valor que usará ssh, y pon los hosts concretos encima de Host *.

¿El archivo de configuración de SSH sirve para scp, sftp y rsync?

Sí. Usan ssh para conectarse, así que los nombres de host y las opciones de ~/.ssh/config también se aplican, por ejemplo scp archivo.txt web:/tmp/.

Fuentes

Más en Configuración y muchos servidores

Todas las guías