2026-08-12
alias, tag et match
Imaginons le scénario suivant:
- je dois me connecter à 3 domaines: foo.fr, bar.org et baz.com
- chaque domaine est divisé en 2 sous-domaines: .dev et .prod
- je dois me connecter avec mon login actuel, un login spécifique (“pouet”) et en “root” (pas la peine de gnagna root gnagna pabien: je sais)
- le nommage des machines sur lesquelles je dois me connecter est identique: ‘vm’ + ‘-’ + service (où service est dans la liste http, cache, db)
Un extrait des connexions possibles:
$ ssh vm-http.dev.foo.fr
$ ssh pouet@vm-cache.prod.bar.org
$ ssh root@vm-db.dev.baz.com
La complétion
On peut se simplifier la vie en créant des fichiers correspondant aux connexions:
$ mkdir .ssh/completion/ && cd .ssh/completion
$ touch vm-http.dev.foo.fr pouet@vm-cache.prod.bar.org root@vm-db.dev.baz.com ...
et compléter la commande ssh avec la liste de ces fichiers. Inconvénient: la touche Tab va passer un sale quart d’heure.
Mon idéal
Il faudrait avoir une “commande” par domaine: foo pour se connecter à foo.fr, bar pour bar.org et baz pour baz.com . En rajoutant une lettre (minuscule et/ou majuscule ?) pour le sous-domaine, on aurait Pfoo pour se connecter à .prod.foo.fr et dbaz pour .dev.baz.com .
Pour les logins et les machines, il ne faudrait préciser que le service et utiliser une lettre pour le login: Rdb pour root@vm-db, pcache pour pouet@vm-cache, http pour vm-http .
En assemblant le tout, l’extrait des connexions possibles deviendrait:
$ dfoo http
$ Pbar pcache
$ dbaz Rdb
Le mixte minuscule/majuscule n’est là que pour illustrer le propos et pourrait ici se traduire par “si c’est important/risqué/dangereux alors c’est en majuscule”.
Match
Une de mes utilisations de cette directive de mon .ssh/config est de définir des “raccourcis”:
Match originalhost owrt
HostName openwrt.mon.domaine.que.j.ai
mais si je veux pouvoir préciser un éventuel login, je dois être un peu plus générique:
Match originalhost *db
HostName vm-db
qu’on traduira par “si le nom de machine de la commande ssh se termine par db alors le nom de machine à utiliser est vm-db”. J’utilise la même chose pour les logins:
Match originalhost p*
User pouet
Match originalhost R*
User root
À noter que le “p” passerait en majuscule (pour bien le distinguer du nom de machine) dans le cas où un service commencerait par “p” (proxy, pgsql …).
Tag
C’est avec cette fonctionnalité que je vais résoudre en partie la simplification domaine / sous-domaine. Il est possible de passer un “tag” à une connexion à l’aide du paramètre -P tag et de définir des valeurs par “tag”:
Match tagged old
KexAlgorithms diffie-hellman-group1-sha1
Pour vérifier si la directive est prise en compte:
$ ssh -P old -G pouet | grep ^kexalgorithms
kexalgorithms diffie-hellman-group1-sha1
Chaque domaine / sous-domaine va correspondre à un “tag” qui va définir le nom de domaine:
Match tagged devfoo
CanonicalDomains .dev.foo.fr
...
Match tagged prodbaz
CanonicalDomains .prod.baz.com
Je dois aussi forcer les machines commençant par “vm-” à utiliser un nom de domaine:
Match host vm-*
CanonicalizeHostname yes
Je vérifie mes combinaisons “tag” / “host”:
$ ssh -G -P devfoo Rdb | grep -e '^user ' -e '^hostname '
user root
hostname vm-db.dev.foo.fr
Attention, une connexion ne peut avoir qu’un seul “tag” et l’ordre des directives est important !
Alias
Je n’ai plus qu’à définir les alias:
alias dfoo ssh -P devfoo
alias Pfoo ssh -P prodfoo
...
alias Pbaz ssh -P prodbaz
et attendre que mes doigts mémorisent tout ça.
Un petit pour la route
Parce que la vie n’est qu’une longue suite d’exceptions, imaginons qu’une machine d’un sous-domaine ne respecte pas la convention de nommage:
# putain de vs-database de mes couilles
Match tagged devbar originalhost *db
HostName vs-database
Match originalhost *db
HostName vm-db
Tiré d’un exemple @TAF (et oui, le commentaire est d’origine).
Commentaires: https://github.com/bsdsx/blog_posts/issues/24