A ssh_config trick to rewrite hosts

I have a pretty long and articulated ssh config. It reflects the plethora of hosts I want to have access to, and the fact that I do not want to use the same identity (i.e. the same cryptographic key) for all of them.

This leads to have a lot of Host blocks with wildcard matches with either a HostName or an appropriate entry in /etc/hosts.

Lately, I wanted to add a new way to authenticate, using an ssh key backed by the TPM on my laptop. I use gpg-agent as an ssh-agent but in this case I wanted to use another ssh agent, specific for TPM-backed ssh keys. I wanted to avoid duplicating all the bunches of blocks I had, and so I came up with the following stanza that does the trick of rewriting any host that matches a certain pattern (*.tpm), removing the suffix

Host *.tpm
    ControlPath ~/.ssh/sessions/%r@%h:%p
    ControlPersist 600
    ControlMaster auto
    IdentityAgent /run/user/1000/ssh-tpm-agent.sock
    IdentityFile ~/.ssh/keys/id_ecdsa_tpm.pub
    ProxyCommand nc -F $(echo %h|sed s/\.tpm$//) %p
    ProxyUseFdpass yes

Let us unpack it.

The stanza is applied for any host that ends with .tpm, (i.e. ssh -p 1234 me@myhost.example.com.tpm). The first three lines persist the connection to the host as a socket (in the previous example, ~/.ssh/sessions/me@myhost.example.com.tpm:1234) and keep it alive for 600 seconds. The fourth and fifth line instruct ssh to use the ssh-tpm-agent and a specific key stored in the tpm to authenticate to these hosts. The last two lines do the rewrite trick: ProxyCommand tells ssh to delegate the setup of the tcp connection using netcat and here the host to connect to is rewritten with sed, removing the suffix. The -F switch instructs netcat to return the connection as a file descriptor to ssh and exit (saving the system a not needed process) and ssh is instructed to accept and use that file descriptor with the last line.

Not simple, but working.