How to View Active SSH Configuration: Defaults, Merged Settings, and Command-Line Overrides


2 views

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:

  1. Check the source code (look for DEFAULT_ADDRESS_FAMILY)
  2. Use strace to monitor system calls:
    strace -e trace=open ssh your_host 2>&1 | grep ssh_config
  3. 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.