Resolving SSH Connection Timeout (Client Keepalive Configuration) on Ubuntu 22.04 LTS
Fix persistent SSH connection timeouts on Ubuntu 22.04 by configuring client-side keepalives. Diagnose network and server-side factors effectively.
Fix persistent SSH connection timeouts on Ubuntu 22.04 by configuring client-side keepalives. Diagnose network and server-side factors effectively.
SSH connection timeouts can be a significant productivity hindrance for system administrators and developers. This guide focuses on diagnosing and resolving persistent SSH connection drops or initial "Connection timed out" errors specifically related to client-side keepalive configurations on an Ubuntu 22.04 LTS system. Understanding how network devices and SSH protocols manage idle connections is key to establishing stable, long-running SSH sessions.
Symptom & Error Signature
Users typically experience one of the following symptoms:
- Initial Connection Failure: The SSH command fails immediately or after a prolonged wait.
ssh: connect to host your_server_ip port 22: Connection timed out - Session Freezing/Dropping: An established SSH session freezes after a period of inactivity, often followed by a disconnect message or the terminal becoming unresponsive.
orWrite failed: Broken pipe
or the terminal simply stops responding to input.Read from remote host your_server_ip: Connection reset by peer
Root Cause Analysis
The "SSH connection timeout" error, particularly when relating to keepalives and client configuration, often stems from how network infrastructure and SSH itself handle idle connections.
- Network Inactivity (NAT/Firewall Timeouts): This is the most prevalent cause. Intermediate network devices like routers, firewalls, or NAT gateways often maintain a state table for active connections. If no traffic passes through a TCP connection for a certain period (e.g., 5 minutes, 10 minutes), these devices might prematurely prune the connection state from their tables. When the client or server later tries to send data, the other end, having its connection state reset by an intermediate device, doesn't respond, leading to a "Connection reset by peer" or a perceived timeout.
- Client-Side SSH Keepalive Configuration:
ServerAliveInterval: Configured on the client, this parameter specifies the time in seconds after which, if no data has been received from the server, the client will send a NULL packet to the server. This "keepalive" packet prevents network devices from timing out the session due to inactivity.ServerAliveCountMax: Also configured on the client, this specifies the number ofServerAliveIntervalmessages (see above) which may be sent withoutssh(1)receiving any messages back from the server. If this threshold is reached, SSH will disconnect the session. Insufficient or absent client-side keepalives allow network devices to drop the connection.
- Server-Side SSH Configuration (
ClientAliveInterval): While the problem description emphasizes client configuration, it's crucial to acknowledge the server's role. The server-side equivalent,ClientAliveIntervalin/etc/ssh/sshd_config, dictates how often the server sends keepalive messages to the client. If the server is aggressively configured to disconnect idle clients, it can override weak client-side settings. - Firewall or Security Group Issues: Though more commonly associated with initial connection failures, overly aggressive or misconfigured stateful firewalls (e.g., UFW on Ubuntu, cloud provider security groups) can drop connections that appear idle, leading to timeouts.
- Network Latency and Packet Loss: High latency or intermittent packet loss on the network path can cause packets, including SSH keepalives, to be dropped or delayed significantly, leading to the SSH client or server believing the connection has died.
Step-by-Step Resolution
Follow these steps to diagnose and resolve SSH connection timeouts on Ubuntu 22.04 LTS, prioritizing client-side configuration.
1. Confirm Basic Network Reachability
Before modifying SSH configurations, ensure the server is generally reachable on the network and port 22.
Ping the Server:
ping -c 5 your_server_ip_or_hostnameThis checks basic IP connectivity. If you see 100% packet loss, there's a fundamental network issue or firewall blocking ICMP.
Test Port 22 Accessibility: Use
nc(netcat) ortelnetto check if port 22 on the server is open and listening.# Using netcat (recommended) nc -vz your_server_ip_or_hostname 22 # Expected successful output: # Connection to your_server_ip_or_hostname 22 port [tcp/ssh] succeeded! # Using telnet (install if not present: sudo apt install telnet) telnet your_server_ip_or_hostname 22 # Expected successful output: # Trying your_server_ip_or_hostname... # Connected to your_server_ip_or_hostname. # Escape character is '^]'. # SSH-2.0-OpenSSH_9.0p1 Ubuntu-1ubuntu7.2 (or similar) # Press Ctrl+] then type 'quit' and Enter to exit.If these fail, the issue is likely a firewall on the server, a network routing problem, or the SSH daemon (
sshd) not running on the server.
2. Configure Client-Side SSH Keepalives
This is the primary solution for client-side timeout issues. You can configure keepalives per-session, per-host, or globally.
Per-Session Configuration (Temporary): For a quick test without altering configuration files, add the
ServerAliveIntervalandServerAliveCountMaxoptions directly to yoursshcommand.ssh -o ServerAliveInterval=60 -o ServerAliveCountMax=3 user@your_server_ip_or_hostnameThis tells the client to send a keepalive packet every 60 seconds if no data is received, and to disconnect after 3 unanswered packets (total 180 seconds of no server response). Adjust
60based on your network's typical idle timeout. A common value is 30 or 60 seconds.Per-Host Configuration (Recommended): For specific servers you connect to regularly, modify your personal SSH configuration file
~/.ssh/config. If it doesn't exist, create it.nano ~/.ssh/configAdd an entry for your server, or modify an existing one:
Host my_remote_server # Use an alias for easier access, e.g., 'prod-web-01' HostName your_server_ip_or_hostname User your_username Port 22 # Optional, defaults to 22 ServerAliveInterval 60 ServerAliveCountMax 3 # Add other common options like IdentityFile if needed # IdentityFile ~/.ssh/id_rsaSave and close the file. Now, you can connect using the alias:
ssh my_remote_server.Ensure
~/.ssh/confighas appropriate permissions:chmod 600 ~/.ssh/config. Incorrect permissions might cause SSH to ignore the file.Global Configuration (Affects all Client Connections): If you want to apply keepalives to all SSH connections made from your Ubuntu client, modify the global SSH client configuration file
/etc/ssh/ssh_config.sudo nano /etc/ssh/ssh_configFind or add the following lines, typically under a
Host *block:Host * SendEnv LANG LC_* HashKnownHosts yes GSSAPIAuthentication yes # Add/uncomment these lines: ServerAliveInterval 60 ServerAliveCountMax 3Save and close the file.
Modifying
/etc/ssh/ssh_configaffects all SSH connections originating from this client system. It's generally safer and more flexible to use~/.ssh/configfor specific hosts or users unless a system-wide policy is required.
3. Diagnose Server-Side SSH Configuration
If client-side keepalives don't fully resolve the issue, the server's SSH daemon (sshd) might be configured to aggressively terminate idle client connections. You'll need to connect to the server (perhaps temporarily using the per-session client config from Step 2.1 or via another access method like a cloud console) to check its configuration.
Check Server's
sshd_config: On the remote server, open the SSH daemon configuration file:sudo nano /etc/ssh/sshd_configLook for ClientAlive directives: Search for
ClientAliveIntervalandClientAliveCountMax. If they are uncommented and set to low values (e.g.,ClientAliveInterval 0or very small numbers, which disables server-side keepalives or makes them too aggressive), this could be the problem.# Uncomment and/or adjust these lines if present and restrictive # ClientAliveInterval 60 # ClientAliveCountMax 3ClientAliveInterval: The server will send a null packet to the client if no data has been received from the client for this many seconds.ClientAliveCountMax: The number of client alive messages (see above) which may be sent withoutsshd(8)receiving any messages back from the client. If this threshold is reached,sshdwill disconnect the client.
Modify and Restart SSH Daemon: If you make changes, save the file and restart the
sshdservice:sudo systemctl restart sshdAlways test SSH access from another terminal before closing your current administrative SSH session after modifying
/etc/ssh/sshd_config. Incorrect configurations can lock you out of the server. Have a backup access method ready (e.g., cloud provider console, KVM).
4. Review Firewall and Security Group Rules
Ensure that no firewall or security group is prematurely dropping established connections or blocking port 22.
Client-Side Firewall (UFW): On your Ubuntu client, check UFW status. By default, UFW allows all outbound connections, but custom rules might exist.
sudo ufw status verboseEnsure nothing is explicitly blocking outbound traffic on port 22 or for SSH.
Server-Side Firewall (UFW & Cloud Security Groups):
- UFW on the server:
Confirm that port 22 is open for inbound connections from your client's IP address or a sufficiently broad range (sudo ufw status verboseAnywhere). Example:To Action From -- ------ ---- 22/tcp ALLOW Anywhere - Cloud Provider Security Groups/Firewall Rules: If your server is hosted on AWS, Azure, GCP, or similar, check its associated security groups or network firewall rules. Ensure inbound TCP port 22 is permitted from your client's public IP address or the necessary IP range. These rules operate at the network edge and can override OS-level firewalls like UFW.
- UFW on the server:
5. Analyze System Logs for Clues
System logs can provide valuable insights into why connections are being dropped or failing.
Client-Side Logs: Open a new terminal on your client and tail the system journal while attempting an SSH connection or waiting for a timeout.
journalctl -f | grep sshLook for messages indicating connection attempts, failures, or errors from the
sshclient.Server-Side Logs: On the remote server, check the
sshdservice logs.journalctl -u sshd -for, for older systems or specific configurations:
grep sshd /var/log/auth.logLook for messages related to accepted connections, disconnections, authentication failures, or specific error messages from
sshdthat might explain why a session was terminated.
By systematically applying these troubleshooting steps, especially focusing on the client-side ServerAliveInterval and ServerAliveCountMax configurations, you should be able to establish and maintain stable SSH connections on your Ubuntu 22.04 LTS system.