When working with SSH connections in a networked environment, you might encounter a puzzling scenario where host
or nslookup
successfully resolves a hostname while SSH fails with:
$ ssh storage
ssh: Could not resolve hostname storage: Name or service not known
$ host storage
storage has address 192.168.20.103
This discrepancy occurs because different tools use different resolution methods:
- SSH: Uses the system's resolver libraries (getaddrinfo()) which check multiple sources
- host/nslookup: Directly query the configured DNS servers
1. Missing Search Domain Configuration
Check your /etc/resolv.conf
:
$ cat /etc/resolv.conf
search example.com
nameserver 8.8.8.8
If the search domain is missing, try:
$ ssh storage.example.com
2. Improper /etc/hosts Configuration
Verify your local hosts file:
$ cat /etc/hosts
127.0.0.1 localhost
192.168.20.103 storage
If the entry exists but SSH still fails, check for:
$ getent hosts storage
3. IPv6 vs IPv4 Preference
Modern systems prefer IPv6. Force IPv4 with:
$ ssh -4 storage
Or disable IPv6 in SSH config:
AddressFamily inet
Using strace to Trace System Calls
Run SSH with strace to see resolution attempts:
$ strace -e trace=network ssh storage
Checking nsswitch.conf
Inspect the name service switch configuration:
$ cat /etc/nsswitch.conf
hosts: files dns
The order matters - 'files' before 'dns' means /etc/hosts is checked first.
Option 1: Update SSH Config
Add to ~/.ssh/config:
Host storage
HostName 192.168.20.103
User yourusername
Option 2: System-wide DNS Configuration
For systemd-resolved systems:
$ sudo systemd-resolve --interface=eth0 --set-dns=192.168.1.1
$ sudo systemd-resolve --set-search=example.com
Verify resolution works with:
$ getent hosts storage
$ ping -c 1 storage
$ ssh -v storage
I recently encountered a puzzling scenario where basic DNS tools (host
, dig
, nslookup
) could resolve a hostname perfectly, while SSH stubbornly refused to cooperate:
$ ssh storage
ssh: Could not resolve hostname storage: Name or service not known
$ host storage
storage has address 192.168.20.103
This discrepancy occurs because different tools use different resolution methods:
# Traditional tools use /etc/nsswitch.conf order (usually files -> dns):
host/nslookup -> Pure DNS query
ssh -> System resolver (glibc) following nsswitch.conf
- Missing search domain: Check
/etc/resolv.conf
for missing search directives - nsswitch misconfiguration: Verify
/etc/nsswitch.conf
has "dns" in hosts line - SSH config overrides: Look for
VerifyHostKeyDNS
orCanonicalizeHostname
in~/.ssh/config
To pinpoint the issue:
# Check system resolver behavior
$ getent hosts storage
# Verify nsswitch configuration
$ grep hosts /etc/nsswitch.conf
# Test with full qualification
$ ssh storage.example.com
# Check SSH debug output
$ ssh -v storage
Quick fix: Add to /etc/hosts
:
192.168.20.103 storage
Permanent solution (for Debian/Ubuntu):
# Edit nsswitch.conf
$ sudo sed -i 's/^hosts:.*/hosts: files dns/' /etc/nsswitch.conf
# Ensure resolv.conf has search domain
$ echo "search example.com" | sudo tee -a /etc/resolv.conf
For complex environments using systemd-resolved:
# Check resolved status
$ systemd-resolve --status
# Add DNS-override
$ sudo resolvectl dns eth0 192.168.1.1
$ sudo resolvectl domain eth0 "example.com"