What's Actually Happening
SSH connection takes a long time to establish. Login prompt appears after significant delay.
The Error You'll See
```bash $ ssh user@server
# Long pause before password prompt (10-30 seconds) user@server's password: ```
Connection delay:
```bash $ time ssh user@server 'echo test'
real 0m15.123s user 0m0.010s sys 0m0.005s # Should be under 1-2 seconds ```
Debug shows delays:
```bash $ ssh -v user@server
# Shows long pause at: # debug1: Connecting to server [ip] port 22. # debug1: Waiting for server response... ```
Why This Happens
- 1.DNS resolution slow - Server trying to resolve client IP
- 2.GSSAPI authentication - Slow GSSAPI lookup
- 3.IPv6 delay - Trying IPv6 before IPv4
- 4.Network latency - Slow network connection
- 5.Server overload - Server under heavy load
- 6.Firewall rules - Packet inspection causing delay
Step 1: Diagnose the Delay
```bash # Enable verbose SSH: ssh -vvv user@server
# Time the connection: time ssh user@server 'echo test'
# Check which step is slow: ssh -o ConnectTimeout=5 -o StrictHostKeyChecking=no user@server
# Debug specific phases: ssh -o GSSAPIAuthentication=no user@server # Test without GSSAPI ssh -o UseDNS=no user@server # Test without DNS
# Check network latency: ping -c 5 server traceroute server
# Check DNS: dig server nslookup server ```
Step 2: Fix DNS Resolution on Server
```bash # On SSH server, edit sshd_config: sudo vim /etc/ssh/sshd_config
# Disable DNS lookups: UseDNS no
# Restart SSH: sudo systemctl restart sshd
# Check if DNS causing delay: # Time before: time ssh user@server 'hostname'
# Time after change: # Should be significantly faster
# Or disable per session: ssh -o UseDNS=no user@server ```
Step 3: Disable GSSAPI Authentication
```bash # On server sshd_config: sudo vim /etc/ssh/sshd_config
# Disable GSSAPI: GSSAPIAuthentication no GSSAPICleanupCredentials yes
# On client ssh_config: sudo vim /etc/ssh/ssh_config
# Or in ~/.ssh/config: Host * GSSAPIAuthentication no
# Test connection: ssh -o GSSAPIAuthentication=no user@server
# If this fixes delay, add to config permanently ```
Step 4: Fix IPv6 Delay
```bash # Force IPv4: ssh -4 user@server
# Or in ~/.ssh/config: Host server AddressFamily inet
# Or disable IPv6 in sshd_config: AddressFamily inet
# Check IPv6 availability: ping6 -c 1 server
# If IPv6 doesn't work, disable it: # On server /etc/ssh/sshd_config: AddressFamily inet # IPv4 only # AddressFamily inet6 # IPv6 only # AddressFamily any # Both (default)
# Test: time ssh -4 user@server 'hostname' ```
Step 5: Optimize Client SSH Config
```bash # Edit ~/.ssh/config: Host * # Disable slow lookups UseDNS no GSSAPIAuthentication no
# Connection settings ConnectTimeout 10 ServerAliveInterval 60 ServerAliveCountMax 3
# Skip known hosts check for speed StrictHostKeyChecking no UserKnownHostsFile /dev/null
# Control master for reuse ControlMaster auto ControlPath ~/.ssh/sockets/%r@%h-%p ControlPersist 600
# Create socket directory: mkdir -p ~/.ssh/sockets
# Test: time ssh user@server 'hostname' ```
Step 6: Optimize Server SSH Config
```bash # On server, edit /etc/ssh/sshd_config:
# Disable slow features: UseDNS no GSSAPIAuthentication no
# Faster authentication: PasswordAuthentication yes PubkeyAuthentication yes AuthorizedKeysFile .ssh/authorized_keys
# Faster key exchange: KexAlgorithms diffie-hellman-group14-sha1,diffie-hellman-group1-sha1
# Faster ciphers (balance with security): Ciphers aes128-ctr,aes192-ctr,aes256-ctr
# Restart: sudo systemctl restart sshd
# Verify: sudo sshd -t # Test config ```
Step 7: Check Network Issues
```bash # Test network latency: ping -c 10 server
# Check for packet loss: ping -c 100 server | grep "packet loss"
# Traceroute: traceroute server
# Check MTU: ping -s 1472 -M do server
# Check if firewall causing delay: # Temporarily disable firewall: sudo ufw disable # Test SSH sudo ufw enable
# Check iptables: sudo iptables -L -n
# Test different port: ssh -p 2222 user@server ```
Step 8: Use SSH Multiplexing
```bash # Enable control master in ~/.ssh/config: Host server HostName server.example.com User user ControlMaster auto ControlPath ~/.ssh/sockets/%r@%h-%p ControlPersist 600
# Create socket directory: mkdir -p ~/.ssh/sockets chmod 700 ~/.ssh/sockets
# First connection: ssh user@server 'hostname' # Normal speed
# Subsequent connections: ssh user@server 'hostname' # Much faster (reuses connection)
# Check active connections: ssh -O check user@server
# Close master connection: ssh -O exit user@server
# This bypasses full authentication on subsequent connections ```
Step 9: Check Server Load
```bash # On server, check load: uptime
# Check CPU: top -b -n 1 | head -20
# Check memory: free -h
# Check SSH process: ps aux | grep sshd
# Check system logs: sudo tail -f /var/log/auth.log sudo journalctl -u sshd -f
# Check disk I/O: iostat -x 1 5
# If server overloaded, SSH will be slow # Address the underlying resource issue ```
Step 10: SSH Connection Verification Script
```bash # Create verification script: cat << 'EOF' > /usr/local/bin/check-ssh-speed.sh #!/bin/bash
SERVER=$1 USER=${2:-$USER}
if [ -z "$SERVER" ]; then echo "Usage: $0 server [user]" exit 1 fi
echo "=== Network Test ===" ping -c 3 $SERVER
echo "" echo "=== DNS Resolution ===" time dig $SERVER
echo "" echo "=== Standard SSH ===" time ssh -o BatchMode=yes -o ConnectTimeout=30 $USER@$SERVER 'hostname' 2>&1
echo "" echo "=== SSH without DNS ===" time ssh -o BatchMode=yes -o UseDNS=no $USER@$SERVER 'hostname' 2>&1
echo "" echo "=== SSH without GSSAPI ===" time ssh -o BatchMode=yes -o GSSAPIAuthentication=no $USER@$SERVER 'hostname' 2>&1
echo "" echo "=== SSH IPv4 only ===" time ssh -4 -o BatchMode=yes $USER@$SERVER 'hostname' 2>&1
echo "" echo "=== SSH with all optimizations ===" time ssh -4 -o BatchMode=yes -o UseDNS=no -o GSSAPIAuthentication=no $USER@$SERVER 'hostname' 2>&1
echo "" echo "=== Recommendations ===" echo "Add to ~/.ssh/config:" echo "" echo "Host $SERVER" echo " UseDNS no" echo " GSSAPIAuthentication no" echo " AddressFamily inet" echo " ControlMaster auto" echo " ControlPath ~/.ssh/sockets/%r@%h-%p" echo " ControlPersist 600" EOF
chmod +x /usr/local/bin/check-ssh-speed.sh
# Usage: /usr/local/bin/check-ssh-speed.sh server user
# Quick test: alias ssh-time='time ssh -o BatchMode=yes' ```
SSH Connection Checklist
| Check | Command | Expected |
|---|---|---|
| Network latency | ping server | Under 50ms |
| DNS resolution | dig server | Fast |
| UseDNS | sshd_config | no |
| GSSAPI | sshd_config | no |
| IPv6 | test with -4 | Not causing delay |
| Server load | uptime | Normal |
Verify the Fix
```bash # After optimizing SSH
# 1. Test connection time time ssh user@server 'hostname' // Under 2 seconds
# 2. Check verbose output ssh -vvv user@server // No long pauses
# 3. Test from different locations // Consistently fast
# 4. Check server config grep -E "UseDNS|GSSAPI" /etc/ssh/sshd_config // Both set to no
# 5. Monitor connections # Multiple SSH sessions // All connect quickly
# 6. Check multiplexing ssh -O check user@server // Master running ```
Related Issues
- [Fix SSH Connection Refused](/articles/fix-ssh-connection-refused)
- [Fix SSH Key Permission Denied](/articles/fix-ssh-key-permission-denied)
- [Fix SSH Timeout](/articles/fix-ssh-timeout)