Resolving Slow SSH Logins: DNS Reverse Lookup Delays on CentOS Stream / Rocky Linux

Fix sluggish SSH login times on CentOS Stream or Rocky Linux caused by DNS reverse lookup delays. Optimize your sshd_config for faster, more efficient access.


Fix sluggish SSH login times on CentOS Stream or Rocky Linux caused by DNS reverse lookup delays. Optimize your sshd_config for faster, more efficient access.

Introduction

Experiencing frustratingly slow SSH login times on your CentOS Stream or Rocky Linux server? Does your connection hang for 10-30 seconds before finally presenting you with the prompt? This common issue, often mistaken for network latency or authentication problems, is typically caused by the SSH daemon (sshd) attempting a reverse DNS lookup on the connecting client's IP address. When this lookup fails, is misconfigured, or encounters a slow DNS server, sshd will wait for a timeout before proceeding, leading to significant delays.

This guide will walk you through diagnosing and resolving SSH login delays stemming from DNS reverse lookup issues, focusing on sshd configuration best practices for CentOS Stream and Rocky Linux environments.

### Symptom & Error Signature

The most noticeable symptom is a significant pause after initiating an SSH connection but before being prompted for a password or receiving the shell.

Client-Side (using ssh -v for verbose output):

$ ssh -v user@your_server_ip
OpenSSH_8.7p1, OpenSSL 1.1.1n  xx XXX XXXX
debug1: Reading configuration data /home/user/.ssh/config
debug1: Reading configuration data /etc/ssh/ssh_config
debug1: Connecting to your_server_ip [your_server_ip] port 22.
debug1: Connection established.
debug1: identity file /home/user/.ssh/id_rsa type 0
debug1: identity file /home/user/.ssh/id_rsa-cert type -1
debug1: Local version string SSH-2.0-OpenSSH_8.7
debug1: Remote protocol version 2.0, remote software version OpenSSH_8.7
debug1: compat_init: sshd version OpenSSH_8.7
debug1: subset of Ciphers, MACs, KexAlgorithms, HostKeyAlgorithms that are acceptable: ssh-ed25519,ssh-rsa,ecdsa-sha2-nistp256,ssh-dss
debug1: SSH2_MSG_KEXINIT sent
debug1: SSH2_MSG_KEXINIT received
# --- A significant delay (e.g., 10-30 seconds) occurs here ---
debug1: kex: algorithm: [email protected]
debug1: kex: host key algorithm: ssh-ed25519
debug1: kex: server->client cipher: [email protected] MAC: <implicit> compression: none
debug1: kex: client->server cipher: [email protected] MAC: <implicit> compression: none
debug1: expecting SSH2_MSG_KEX_ECDH_REPLY
debug1: SSH2_MSG_NEWKEYS sent
debug1: SSH2_MSG_NEWKEYS received
debug1: Will attempt key: /home/user/.ssh/id_rsa RSA SHA256:... agent
debug1: Will attempt key: /home/user/.ssh/id_dsa
debug1: Will attempt key: /home/user/.ssh/id_ecdsa
debug1: Will attempt key: /home/user/.ssh/id_ed25519 ED25519 SHA256:... agent
debug1: Will attempt key: /home/user/.ssh/id_xmss
debug1: SSH2_MSG_EXT_INFO received
debug1: SSH2_MSG_SERVICE_REQUEST sent
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: publickey
debug1: Offering publickey authentication: /home/user/.ssh/id_ed25519
debug1: Server accepts key: /home/user/.ssh/id_ed25519
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Trying private key: /home/user/.ssh/id_rsa
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: No more authentication methods to try.
user@your_server_ip's password:

The tell-tale sign is the long delay after SSH2_MSG_KEXINIT received and before subsequent key exchange or authentication messages.

Server-Side (/var/log/secure or journalctl -u sshd):

The server logs may not explicitly show an error related to DNS, but a significant time gap between connection attempts and successful authentication (or failed attempts) can be observed.

# Example from journalctl -u sshd
Jul 21 09:30:00 your_server sshd[12345]: Connection from 203.0.113.1 port 54321 on 192.0.2.1 port 22
# --- 10-30 second delay in logs ---
Jul 21 09:30:25 your_server sshd[12345]: Accepted publickey for user from 203.0.113.1 port 54321 ssh2: ED25519 SHA256:...
Jul 21 09:30:25 your_server sshd[12345]: pam_unix(sshd:session): session opened for user user by (uid=0)

### Root Cause Analysis

The root cause of these SSH login delays is almost always tied to sshd attempting to perform network lookups that are either slow or fail to resolve within a reasonable timeframe. The primary culprits are:

  1. UseDNS yes in sshd_config: By default, sshd performs a reverse DNS lookup on the connecting client's IP address. This is done to associate a hostname with the client's IP for logging purposes and potentially for AllowUsers, DenyUsers directives that use hostnames. If the configured DNS resolvers on the server are slow, unreachable, or if there's no corresponding PTR record for the client's IP address, sshd will wait for a DNS timeout (which can be several seconds) before proceeding.
  2. GSSAPIAuthentication yes and GSSAPIDelegateCredentials yes: GSSAPI (Generic Security Service Application Programming Interface) is primarily used for Kerberos authentication. If enabled and the server is not part of a functioning Kerberos realm, or if the Kerberos KDC (Key Distribution Center) is unreachable or slow, these checks can introduce significant delays as sshd attempts to contact non-existent or misconfigured GSSAPI services. This often involves additional network lookups beyond standard DNS.
  3. Misconfigured /etc/resolv.conf: The server's own DNS resolver configuration (/etc/resolv.conf) might point to unreachable or extremely slow DNS servers. This impacts all DNS lookups initiated by the server, including those performed by sshd.
  4. Firewall issues: Outgoing DNS queries (port 53 UDP/TCP) from the server might be blocked by local firewall rules (e.g., firewalld, nftables) or network firewalls, preventing the server from reaching its configured DNS resolvers.

### Step-by-Step Resolution

Follow these steps to diagnose and resolve slow SSH login times due to DNS reverse lookup delays.

1. Verify the Symptom and Current Configuration

First, confirm the issue is indeed a DNS-related delay and check your current sshd settings.

  1. Initiate a verbose SSH connection from your client:

    ssh -v user@your_server_ip
    

    Observe the output for the delay point as described in the "Symptom & Error Signature" section.

  2. Check sshd logs on the server:

    sudo journalctl -u sshd | tail -n 50
    

    Look for time gaps between connection establishment and authentication attempts.

  3. Inspect relevant sshd_config directives:

    sudo grep -E "UseDNS|GSSAPIAuthentication|GSSAPIDelegateCredentials" /etc/ssh/sshd_config
    

    Note down their current states. If they are commented out, sshd uses its default behavior (often yes for UseDNS and GSSAPIAuthentication on CentOS/Rocky).

2. Test DNS Resolution on the Server

Ensure your server's DNS configuration is healthy.

  1. Check your server's configured DNS resolvers:

    cat /etc/resolv.conf
    

    This file lists the nameserver IPs your server uses.

  2. Test forward DNS resolution from the server:

    dig google.com
    

    This should resolve quickly. If it's slow or fails, your resolv.conf or network path to DNS servers is problematic.

  3. Test reverse DNS resolution from the server for your client IP:

    dig -x <YOUR_CLIENT_IP>
    

    Replace <YOUR_CLIENT_IP> with the public IP address you are connecting from. If this command is slow or returns "NXDOMAIN" (non-existent domain) for an IP that should have a PTR record, or simply takes a long time, this strongly indicates a reverse DNS issue. If your client IP does not have a PTR record configured, this command will naturally be slow or fail. This is precisely the scenario sshd struggles with if UseDNS is enabled.

3. Disable UseDNS in sshd_config (Primary Fix)

The most common and effective solution is to disable sshd's reverse DNS lookup feature.

Before making any changes, always back up your SSH configuration file. This allows for easy rollback in case of issues. Keep your current SSH session open while testing changes in a new terminal to prevent being locked out.

  1. Backup the sshd_config file:

    sudo cp /etc/ssh/sshd_config /etc/ssh/sshd_config.bak
    
  2. Edit the sshd_config file:

    sudo vi /etc/ssh/sshd_config
    

    Locate the line UseDNS (it might be commented out with a #). Change it to no, or add the line if it's entirely missing.

    # /etc/ssh/sshd_config
    
    # ... other configurations ...
    
    # Speed up SSH logins by disabling reverse DNS lookups
    UseDNS no
    
    # ... other configurations ...
    

    Disabling UseDNS means that sshd will log connecting clients by their IP address rather than their resolved hostname. For most production environments, logging IP addresses is sufficient and often preferred for security analysis.

4. Disable GSSAPIAuthentication (Secondary Fix)

If disabling UseDNS doesn't fully resolve the delay, or if you are not using Kerberos/GSSAPI for authentication, disabling GSSAPI can further improve login speed.

  1. Edit the sshd_config file again:

    sudo vi /etc/ssh/sshd_config
    

    Locate GSSAPIAuthentication and GSSAPIDelegateCredentials. Change yes to no, or add/uncomment these lines as follows:

    # /etc/ssh/sshd_config
    
    # ... other configurations ...
    
    # Disable GSSAPI to prevent potential delays if not using Kerberos
    GSSAPIAuthentication no
    GSSAPIDelegateCredentials no
    
    # ... other configurations ...
    

5. Restart sshd Service

After modifying sshd_config, you must restart the sshd service for the changes to take effect.

Always perform this step from a new terminal session, ensuring your current SSH session remains active. If the configuration changes introduce an error, your existing session will remain connected, allowing you to revert the changes.

  1. Restart the sshd service:

    sudo systemctl restart sshd
    
  2. Verify the service status:

    sudo systemctl status sshd
    

    Ensure it's active (running).

6. Verify the Fix

From a new client terminal (not the one you used to restart the service), attempt to SSH into your server.

  1. Test login speed:

    time ssh user@your_server_ip exit
    

    The time command will report the duration. You should see a significant reduction in connection time, often dropping from 10-30 seconds to under 1-2 seconds.

  2. Check sshd logs again:

    sudo journalctl -u sshd | tail -n 50
    

    Confirm that new connection entries appear without the previous delays and log client IPs instead of hostnames (if UseDNS no was applied).

7. (Optional) Configure Local Caching DNS Server or /etc/hosts

If for some specific security or auditing reasons you must have UseDNS yes enabled (which is rare for most general-purpose hosting environments), you can implement a local caching DNS server (like unbound or dnsmasq) or populate /etc/hosts on your server.

  1. Local Caching DNS Server (e.g., unbound): Install and configure unbound on your server to act as a local resolver. Point your /etc/resolv.conf to 127.0.0.1. This can significantly speed up all DNS queries from the server, including sshd's reverse lookups, by caching results.

    sudo dnf install unbound -y
    sudo systemctl enable --now unbound
    # Edit /etc/unbound/unbound.conf and /etc/resolv.conf as necessary
    
  2. Populate /etc/hosts: For a small number of known client IPs that frequently connect, you can add entries directly to /etc/hosts on your server. This bypasses DNS lookups entirely for those specific IPs.

    sudo vi /etc/hosts
    

    Add lines like:

    # /etc/hosts
    # ...
    192.168.1.10    myclient.example.com
    203.0.113.5     anotherclient.example.net
    

    Remember to update this file as client IPs change.

By systematically applying these solutions, you can effectively eliminate SSH login delays caused by DNS reverse lookup issues on your CentOS Stream or Rocky Linux servers, ensuring a swift and efficient administrative experience.