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. 1.DNS resolution slow - Server trying to resolve client IP
  2. 2.GSSAPI authentication - Slow GSSAPI lookup
  3. 3.IPv6 delay - Trying IPv6 before IPv4
  4. 4.Network latency - Slow network connection
  5. 5.Server overload - Server under heavy load
  6. 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

CheckCommandExpected
Network latencyping serverUnder 50ms
DNS resolutiondig serverFast
UseDNSsshd_configno
GSSAPIsshd_configno
IPv6test with -4Not causing delay
Server loaduptimeNormal

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 ```

  • [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)