Troubleshooting SSH Timeout Variations Between LAN and Remote Connections


3 views

When working with SSH connections across different network environments, you may encounter inconsistent timeout behaviors. Here's a deep dive into why this happens and how to fix it.

The fundamental issue stems from how TCP connections are maintained across network boundaries:

# Server-side TCP keepalive settings (in /etc/ssh/sshd_config)
TCPKeepAlive yes
ClientAliveInterval 60
ClientAliveCountMax 3

Corporate networks typically have different firewall/NAT configurations than residential networks:

  • Office LAN: Direct connections with no intermediate NAT timeouts
  • Home networks: Multiple NAT layers with aggressive connection timeouts (typically 5-15 minutes)

For Mac OSX Terminal users, these client-side configurations work best:

# ~/.ssh/config
Host *
  ServerAliveInterval 30
  ServerAliveCountMax 3
  TCPKeepAlive no

If the above doesn't resolve your issue, consider these additional measures:

# For persistent connections
ssh -o ServerAliveInterval=30 -o ServerAliveCountMax=3 user@host

# For tunneling scenarios
autossh -M 0 -o "ServerAliveInterval 30" -o "ServerAliveCountMax 3" -N -L ...

Use these commands to troubleshoot timeouts:

# Check TCP connection states
netstat -tn | grep ssh

# Monitor packets
tcpdump -i any port 22 -n

# Test keepalive packets
sudo tcpdump -i en0 'tcp port 22 and (((ip[2:2] - ((ip[0]&0xf)<<2)) - ((tcp[12]&0xf0)>>2)) != 0)'

Network middleboxes (NATs, firewalls, stateful packet inspectors) behave differently based on connection origin. When you SSH from within the LAN, your traffic bypasses most network security appliances. Remote connections traverse multiple state-tracking systems that aggressively prune idle TCP connections.

The timeout discrepancy stems from three layers:

  • Transport Layer: Home routers/NATs typically enforce 300-600 second TCP state timeouts
  • SSH Protocol: Default ClientAliveInterval (0) and ServerAliveInterval (0) settings
  • System Level: Different TCP keepalive configurations between macOS and Linux

Create or modify ~/.ssh/config with these parameters:

Host *
    ServerAliveInterval 60
    ServerAliveCountMax 3
    TCPKeepAlive no

For Fedora servers, edit /etc/ssh/sshd_config:

ClientAliveInterval 30
ClientAliveCountMax 5
UseDNS no

After changes, restart sshd: sudo systemctl restart sshd

For environments where you can't modify configurations:

  1. Use tmux or screen to maintain session state
  2. Implement SSH connection hopping through a bastion host
  3. Consider Mosh (Mobile Shell) for unstable connections

To diagnose exactly where connections drop:

# On macOS:
sudo tcpdump -i en0 -vvv 'port 22'

# On Linux server:
journalctl -u sshd --follow
sudo ss -t -a | grep ssh

For corporate environments, these additional measures help:

  • Implement SSH certificates instead of key pairs
  • Configure global keepalive settings in /etc/ssh/ssh_config.d/
  • Use VPN tunneling for all remote access