Using SSH Config `Match exec` to Route Hostnames Dynamically
Why bother with a fancy Match block?
When you SSH into a fleet of servers that share a naming scheme, you usually end up copying-pasting the same options over and over. A Match block that tests the host name and then tweaks the connection parameters lets you:
- Keep a single config file that works for every member of the group.
- Automate proxying or port-translation without having to write a wrapper script.
The example below demonstrates the trick.
The sample configuration
# ~/.ssh/config
Match exec "echo %h | grep -q '^srv[0-9]$'"
ProxyCommand nc $(echo %h | sed 's/srv\([0-9]\)/192.168.0.2\1/') %p
User user1
IdentityFile ~/.ssh/id_rsa
Port 22
| Line | What it does |
|---|---|
Match exec "…" | Runs the command inside double quotes for each connection attempt. If it exits 0 the block is applied; otherwise it is ignored. |
| `echo %h | grep -q ‘^srv[0-9]$'` |
ProxyCommand nc $(… ) %p | Uses nc (netcat) as a forwarder. The command inside $(… ) transforms the hostname into an IP address, while %p injects the target port. |
User user1 | Connect as user user1 on the remote machine. |
IdentityFile ~/.ssh/id_rsa | Use this private key. |
Port 22 | Explicitly set the SSH port (redundant here but useful when combined with proxying). |
How the hostname transformation works
echo %h | sed 's/srv\([0-9]\)/192.168.0.2\1/'
srv[0-9]→srv1,srv2, …sedcaptures the digit with\([0-9]\)and substitutes it after the prefix192.168.0.2.- Result:
srv1→192.168.0.21srv2→192.168.0.22- etc.
A quick test
Copy the block into
~/.ssh/config.Connect:
ssh srv1You’ll be forwarded via
ncto192.168.0.21:22as useruser1with keyid_rsa.
Things to watch out for
| Issue | Fix |
|---|---|
nc may not be installed | Install netcat (e.g: dnf install netcat). |
exec is run for every connection attempt | If the command is heavy, performance suffers. Keep the exec lightweight. |
%h contains a domain (e.g. srv1.example.com) | Adjust the regex to ^srv[0-9]$ or use %l (local hostname). |
TL;DR
- Use
Match execto test the hostname against a regex. - In the block, override
ProxyCommand,User,IdentityFile,Port. - Dynamically build the destination IP with
sed(or any shell logic). - Benefit: One slim config file.
Happy hacking!
Comments
Talk about this post on Mastodon or Bluesky with #m1ch20251120SshConfig.
To comment here, reply to the post on Mastodon or on Bluesky.
Loading comments contacts graz.social or mastodon.social (wherever the post is) and Bluesky, see the privacy policy.