When managing multiple identical datacenter environments, maintaining separate SSH config entries for each server behind jumpboxes becomes tedious. The only difference between environments is typically the jumpbox IP or hostname.
SSH's configuration file supports pattern matching in Host declarations, allowing you to extract parts of the hostname as variables. Here's how it works:
Host *-*
HostName %h
User your_username
ProxyCommand ssh -W $(echo %h | cut -d'-' -f2-):%p $(echo %h | cut -d'-' -f1)
Let's implement a full solution for connecting to database servers behind jumpboxes:
# Jumpbox definitions
Host dc1
HostName jumpbox1.example.com
User admin
Host dc2
HostName jumpbox2.example.com
User admin
# Dynamic backend server access
Host *-*
ProxyCommand ssh -q -W $(echo %h | sed 's/^[^-]*-//'):%p $(echo %h | cut -d- -f1)
ServerAliveInterval 60
TCPKeepAlive yes
# Specific server configurations
Host *-db
User dbadmin
Port 5432
Host *-redis
User redisuser
Port 6379
The key components in our solution:
*-*
pattern matches any host with a hyphen$(echo %h | cut -d'-' -f1)
extracts the datacenter prefix$(echo %h | sed 's/^[^-]*-//')
removes the datacenter prefix
For more complex environments with multiple segments:
Host *-*-*
ProxyCommand ssh -W $(echo %h | cut -d'-' -f3-):%p $(echo %h | cut -d'-' -f1)-$(echo %h | cut -d'-' -f2)
This would handle patterns like region1-dc1-mysql
where you need to extract both region and datacenter.
When using this approach:
- Ensure proper permissions on your SSH config file (chmod 600 ~/.ssh/config)
- Use SSH keys with limited permissions for jumpbox access
- Consider adding
IdentitiesOnly yes
to prevent unintended key usage
If connections fail:
- Test with
-v
flag:ssh -v dc1-mysql
- Verify the extracted components with:
echo %h | cut -d'-' -f1
- Check jumpbox connectivity separately
Managing SSH connections across multiple identical datacenter environments often leads to bloated configuration files. When you have dozens of servers behind jump hosts in different locations, maintaining separate entries for each combination becomes tedious and error-prone.
OpenSSH's configuration file supports powerful pattern matching that most administrators underutilize. The %
wildcard can capture parts of hostnames and reuse them in other directives:
Host *-servertype
HostName internal-server
ProxyCommand ssh -W %h:%p $(echo %h | cut -d'-' -f1)
Here's a complete solution for your multi-datacenter scenario:
# Base jumpbox configurations
Host datacenter1
HostName 203.0.113.1
User admin
IdentityFile ~/.ssh/dc1_key
Host datacenter2
HostName 203.0.113.2
User admin
IdentityFile ~/.ssh/dc2_key
# Dynamic backend server access
Host *-*
ProxyCommand ssh -W $(echo %h | awk -F'-' '{print $2}':%p $(echo %h | awk -F'-' '{print $1}')
User appuser
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
# Specific service templates
Host *-db
Port 3306
Host *-redis
Port 6379
For more complex scenarios, you can create wrapper scripts:
Host *-*
ProxyCommand bash -c 'dc=${1%%-*}; target=${1#*-}; ssh -W ${target}:%p $dc' - %h
While this approach is convenient, consider these security measures:
- Use
StrictHostKeyChecking
appropriately - Limit SSH agent forwarding
- Implement jump host authentication separately
With this configuration, you can now connect using intuitive commands:
ssh datacenter1-db # Connects to database via datacenter1 jumpbox
ssh datacenter2-redis # Connects to Redis via datacenter2 jumpbox