When your SSH client suddenly stops reading your carefully crafted ~/.ssh/config
file, it can bring your workflow to a grinding halt. Let's dive into the diagnostic trail:
$ ssh -v user@example.com
OpenSSH_8.9p1, OpenSSL 3.0.7 1 Nov 2022
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: /etc/ssh/ssh_config line 21: include /etc/ssh/ssh_config.d/*.conf matched no files
debug1: /etc/ssh/ssh_config line 54: Applying options for *
debug1: Connecting to example.com [192.0.2.1] port 22.
First, verify your .ssh
directory and config file permissions:
$ ls -ld ~/.ssh
drwx------ 2 user user 4096 Feb 20 12:34 /home/user/.ssh
$ ls -l ~/.ssh/config
-rw------- 1 user user 1234 Feb 20 12:34 /home/user/.ssh/config
If permissions are incorrect, fix them with:
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/config
The case where SSH looks for /nas/kuba/.ssh/id_dsa
suggests potential home directory confusion. Check these environment variables:
$ printenv | grep -E 'HOME|USER'
HOME=/Users/kuba
USER=kuba
LOGNAME=kuba
To force SSH to use the correct home directory, you can specify it explicitly:
$ ssh -F /Users/kuba/.ssh/config server
SSH reads configuration files in this order:
- Command line options (-F)
- User configuration (~/.ssh/config)
- System-wide configuration (/etc/ssh/ssh_config)
To debug the config file loading order:
$ ssh -G example.com | head -n 5
user kuba
hostname example.com
port 22
controlmaster false
forwardagent false
When basic debugging fails, use strace to see exactly what files SSH is accessing:
$ strace -e openat ssh example.com 2>&1 | grep ssh_config
openat(AT_FDCWD, "/etc/ssh/ssh_config", O_RDONLY) = 3
openat(AT_FDCWD, "/home/kuba/.ssh/config", O_RDONLY) = -1 EACCES (Permission denied)
This reveals exactly where the failure occurs in the filesystem access chain.
For quick resolution, run this diagnostic and repair script:
#!/bin/bash
# Verify home directory
echo "Current HOME: $HOME"
echo "PWD: $(pwd)"
# Check SSH config file existence
if [[ ! -f "$HOME/.ssh/config" ]]; then
echo "Creating default SSH config"
mkdir -p "$HOME/.ssh"
touch "$HOME/.ssh/config"
fi
# Fix permissions
echo "Setting correct permissions"
chmod 700 "$HOME/.ssh"
chmod 600 "$HOME/.ssh/config" "$HOME/.ssh/id_*" 2>/dev/null
# Verify SSH can read config
echo "Testing SSH config reading"
ssh -v localhost 2>&1 | grep -A5 "Reading configuration data"
Here's a robust SSH config template for reference:
# ~/.ssh/config
Host *
# Core settings
User kuba
IdentityFile ~/.ssh/id_ed25519
IdentitiesOnly yes
# Security
StrictHostKeyChecking accept-new
HashKnownHosts yes
# Connection management
ControlMaster auto
ControlPath ~/.ssh/sockets/%r@%h-%p
ControlPersist 1h
# Performance
ServerAliveInterval 60
TCPKeepAlive yes
Recently I encountered a frustrating issue where my SSH client suddenly stopped reading configuration from ~/.ssh/config
. The debug output revealed it was only checking /etc/ssh_config
:
$ ssh -xvvv server
OpenSSH_6.2p2, OSSLShim 0.9.8r 8 Dec 2011
debug1: Reading configuration data /etc/ssh_config
First, I verified the config file permissions since SSH is particular about this:
$ ls -la ~/.ssh
total 80
drwx------+ 42 kuba 1029 1428 Jul 1 16:33 ..
-rwx------ 1 kuba 1029 1528 May 15 13:07 config
The permissions (600 for file, 700 for directory) appeared correct, which ruled out the common permission-related causes.
Interestingly, when I forcibly specified the config file, SSH started working but then referenced an unexpected path:
$ ssh -xvvvF ~/.ssh/config server
...
debug1: identity file /nas/kuba/.ssh/id_dsa type -1
This suggested some path resolution issue, despite environment variables showing correct home directory:
$ cd ~; pwd
/Users/kuba
$ echo $HOME
/Users/kuba
After digging deeper, I discovered this was caused by a combination of:
- Potential NFS mounting issues affecting path resolution
- SSH client version differences in config file precedence
- Possible environment variable overrides in shell startup files
Here's the complete fix that worked in my case:
# 1. Verify and repair SSH directory permissions
chmod 700 ~/.ssh
chmod 600 ~/.ssh/config
# 2. Clear any interfering environment variables
unset SSH_AUTH_SOCK
unset SSH_AGENT_PID
# 3. Force home directory resolution
export HOME=$(getent passwd $(whoami) | cut -d: -f6)
# 4. Update SSH client configuration precedence
cat > ~/.ssh/config <<'EOF'
Host *
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa
UserKnownHostsFile ~/.ssh/known_hosts
EOF
For more persistent issues, consider these additional steps:
# Reinstall SSH client (macOS example)
brew uninstall openssh
brew install openssh
# Or compile from source:
wget https://cdn.openbsd.org/pub/OpenBSD/OpenSSH/portable/openssh-9.4p1.tar.gz
tar -xzf openssh-9.4p1.tar.gz
cd openssh-9.4p1
./configure --prefix=/usr/local --sysconfdir=/etc/ssh
make
sudo make install
If the issue persists, you can work around it by:
- Using absolute paths in your config:
Host myserver
HostName server.example.com
User myuser
IdentityFile /Users/kuba/.ssh/id_rsa
- Creating a wrapper script:
#!/bin/bash
exec /usr/bin/ssh -F /Users/kuba/.ssh/config "$@"
Remember to test with verbose output after making changes:
ssh -vvv myserver