When troubleshooting SSH connections, understanding the actual configuration in effect is crucial. The configuration system follows this strict order:
1. Command-line options (-o key=value)
2. ~/.ssh/config (user-specific)
3. /etc/ssh/ssh_config (system-wide)
Surprisingly, OpenSSH doesn't include a built-in "--print-config" flag. Here are practical workarounds:
ssh -vvv -G your_hostname | grep -i "config"
Example output showing merged configuration:
debug2: resolving "example.com" port 22
debug1: /etc/ssh/ssh_config line 52: Applying options for example.com*
user knownhosts file: /home/user/.ssh/known_hosts
port 22, cipher aes256-ctr, hostkeyalgorithms ssh-ed25519-cert-v01@openssh.com
This shows the effective configuration without connecting:
ssh -G your_hostname
Sample output structure:
host your_hostname
hostname 192.168.1.100
port 22
addressfamily any
batchmode no
canonicalizefallback yes
Create this bash script to compare different configuration layers:
#!/bin/bash
echo "=== System-wide config ==="
grep -v "^#" /etc/ssh/ssh_config
echo "\n=== User config ==="
grep -v "^#" ~/.ssh/config
echo "\n=== Effective config ==="
ssh -G $1
For parameters like AddressFamily with no documented default, check the source:
# Clone OpenSSH source
git clone https://github.com/openssh/openssh-portable
grep -r "AddressFamily" ./
This Python script generates a visual configuration hierarchy:
import paramiko
config = paramiko.SSHConfig()
config.parse(open('/etc/ssh/ssh_config'))
config.parse(open(os.path.expanduser('~/.ssh/config')))
print(json.dumps(config.lookup('hostname'), indent=4))
When troubleshooting SSH connections, it's crucial to understand how configurations are applied:
1. Command-line options (-o key=value)
2. ~/.ssh/config (user-specific)
3. /etc/ssh/ssh_config (system-wide)
4. Compiled-in defaults
The core problem is that SSH doesn't provide a built-in way to:
- View all active settings including defaults
- Trace which configuration source applied each setting
- See undocumented default values (like AddressFamily)
Here are several approaches to inspect your active SSH configuration:
1. Using ssh -G for Dummy Mode
For OpenSSH 7.0+ (released 2015), use the -G
flag:
ssh -G your_host | grep -i addressfamily
# Example output:
# addressfamily any
# port 22
# user your_username
This shows the effective configuration without actually connecting.
2. Verbose Mode with -v
While not a complete solution, verbose mode reveals some configs:
ssh -vvv your_host 2>&1 | grep -i "config"
# Look for lines like:
# debug1: /etc/ssh/ssh_config line 45: Applying options for *
3. Custom Debug Script
Create a script to parse configuration layers:
#!/bin/bash
HOST=$1
echo "=== Compiled Defaults ==="
strings which ssh | grep -A1 "AddressFamily"
echo "\n=== System Config ==="
grep -A5 "AddressFamily" /etc/ssh/ssh_config || echo "Not set in system config"
echo "\n=== User Config ==="
grep -A5 "AddressFamily" ~/.ssh/config || echo "Not set in user config"
echo "\n=== Effective Config ==="
ssh -G $HOST | grep -i "AddressFamily"
For parameters like AddressFamily with no documented defaults:
- Check the source code (look for DEFAULT_ADDRESS_FAMILY)
- Use strace to monitor system calls:
strace -e trace=open ssh your_host 2>&1 | grep ssh_config
- Search OpenSSH mailing list archives
Consider these specialized tools for deeper inspection:
sshd -T
- For server-side configuration testing- Wireshark - Analyze actual protocol behavior
- LD_PRELOAD hooks - Intercept configuration loading
Remember that some settings may be compiled into your SSH client, making them invisible to standard inspection methods.