If your SSH session “works” but takes 10–60 seconds to get a prompt, you don’t have an SSH problem. You have a name-resolution problem wearing an SSH costume.
This shows up most often right after a Debian upgrade, a network redesign, or a “small” change to DNS. The server isn’t broken; it’s waiting. And SSH—being polite to a fault—will wait for DNS and GSSAPI/Kerberos to finish their little social rituals before letting you in.
What “slow SSH login” really means (symptoms that matter)
“SSH is slow” is imprecise. You need to know which stage is slow, because different stages implicate different culprits. SSH is a pipeline: TCP connect → key exchange → authentication → session setup. DNS and GSSAPI can block different parts of that pipeline, and they have very distinct fingerprints.
Common slow-login fingerprints
- Delay before the password prompt (or before any auth method is offered): often reverse DNS lookup (server tries to resolve client IP to a hostname) or GSSAPI auth negotiation.
- Delay after successful authentication (password accepted, but prompt arrives late): PAM modules, home directory/automount, shell startup scripts, or DNS during PAM session setup.
- Delay only from certain networks (office VPN bad, home fine): split-horizon DNS, firewall blocking UDP/TCP 53, or Kerberos realm reachability from one side.
- Delay only when using a hostname (IP is fast): client-side DNS resolution or search-domain madness.
- Delay only in first connection (subsequent are fast): negative DNS caching, resolver warm-up, or GSSAPI retry behavior.
We’re focusing on Debian 13 with OpenSSH, and the two fastest “instant win” fixes when the slowness is before you get a shell: reverse DNS (UseDNS) and GSSAPI (Kerberos) negotiation.
Joke #1: SSH is like a bouncer who insists on checking your ID against a database that’s “temporarily unavailable.” You’re not denied—just stuck outside.
Fast diagnosis playbook (first/second/third checks)
This is the “I’m on-call, it’s 02:00, and executives are waiting” flow. It’s designed to find the bottleneck in minutes, not to satisfy your curiosity.
First: locate the delay (client view)
- Run SSH with timing clues and verbose output and see which line pauses.
- If it pauses around GSSAPI lines, suspect Kerberos/GSSAPI. If it pauses around “Authentications that can continue” or before banner, suspect server-side reverse DNS.
Second: verify DNS behavior (server view)
- Test forward and reverse lookups for the client IP from the server using the system resolver.
- Look for timeouts, long search-domain walks, or PTR records pointing to nonsense.
Third: confirm sshd is waiting on these (logs and sshd debug)
- Temporarily increase sshd logging for a single test window or run a debug sshd on an alternate port.
- Correlate timestamps: if sshd logs show gaps around “reverse mapping checking” or GSSAPI, you have your answer.
After that, you decide: do you disable UseDNS (usually yes), disable GSSAPIAuthentication (often yes unless you use Kerberos), or fix the underlying DNS/Kerberos path (best long-term).
Why DNS and GSSAPI stall SSH on Debian 13
OpenSSH is conservative: it tries to collect information about the connecting client and it tries authentication methods in an order that is useful for enterprise environments. Two things matter:
- Reverse DNS lookups are used for logging and (sometimes) access control logic. The server may try to map the client IP to a hostname (PTR record), and sometimes validate that hostname maps back to the same IP (a forward-confirmed reverse DNS, or FCrDNS check).
- GSSAPIAuthentication allows Kerberos-based single sign-on. If enabled and the client offers it (or the server prioritizes it), sshd may attempt to negotiate it. If Kerberos is misconfigured, unreachable, blocked by firewall, or slow, SSH waits.
On Debian 13, you’ll see the same fundamental behavior as other modern Debian releases: OpenSSH is built with sane defaults for general compatibility, and the resolver stack may include systemd-resolved or classic glibc resolver behavior depending on your setup. The pain usually comes from environments where DNS isn’t consistently fast and correct.
Reverse DNS: the classic silent killer
Reverse DNS (PTR records) is easy to neglect because most applications don’t care. SSH does. Not always, and not in every configuration, but enough that it becomes a common root cause of “SSH is slow.”
The worst cases are:
- Client IP has no PTR record and your resolver retries multiple servers with long timeouts.
- PTR exists but points to a hostname that doesn’t resolve back (FCrDNS check fails, more lookups happen).
- DNS servers are reachable but slow, or only reachable via a VPN path with packet loss.
- Your resolver has aggressive search domains and tries several suffixes before failing.
GSSAPI: excellent when it works, sticky when it doesn’t
Kerberos is great when you run it properly. When you don’t, it fails in ways that look like “SSH is stuck.” If GSSAPIAuthentication is enabled in sshd and the client tries it, both sides may attempt to find realms, contact KDCs, and validate tickets. If any of that requires DNS (it does), you can get a double-whammy: GSSAPI waits on DNS which waits on a broken network.
Joke #2: GSSAPI is like that colleague who “just needs five minutes” to join a call, but first has to install an update.
A reliability quote (paraphrased)
Paraphrased idea: “Hope is not a strategy.”
— attributed in SRE circles to General Gordon R. Sullivan. Operationally, it means you measure and verify, not wish.
Interesting facts and history (so the weirdness makes sense)
- Fact 1: OpenSSH became the de-facto SSH implementation after the original SSH had licensing restrictions; OpenSSH prioritized secure defaults, even if they were sometimes chatty.
- Fact 2: Reverse DNS (PTR records) lives in a special DNS zone under
in-addr.arpa(IPv4) andip6.arpa(IPv6). Many orgs treat it as optional—until logging and access controls depend on it. - Fact 3: The “forward-confirmed reverse DNS” concept grew out of anti-spoofing hygiene: it’s not strong identity, but it reduces casual mislabeling.
- Fact 4: Kerberos relies heavily on DNS in many deployments (SRV records, realm mapping), so “Kerberos is slow” often means “DNS is slow, twice.”
- Fact 5: SSH’s host key verification is about server identity, not client identity; reverse DNS lookups are mostly about names for logs and policy checks.
- Fact 6: systemd-resolved introduced new caching and stub-resolver behaviors in many Linux environments; it fixed some issues and also created new “it depends” debugging paths.
- Fact 7: IPv6 can magnify DNS issues: clients may prefer AAAA records, and reverse IPv6 lookups are longer and can trigger more resolver timeouts if misconfigured.
- Fact 8: NSS (Name Service Switch) can cause surprising delays if it consults sources like LDAP/SSSD for host lookups; DNS isn’t always the only name service in play.
Practical tasks: commands, outputs, and decisions (12+)
These are field-tested checks. Every task includes: a command, realistic output, what it means, and what you do next. Run them on Debian 13 unless noted otherwise. Replace IPs/hostnames with your own.
Task 1: Identify where SSH pauses (client-side verbose)
cr0x@server:~$ ssh -vvv admin@db-01
OpenSSH_9.8p1 Debian-1, OpenSSL 3.3.2 3 Sep 2024
debug1: Connecting to db-01 [10.20.30.41] port 22.
debug1: Connection established.
debug1: identity file /home/admin/.ssh/id_ed25519 type 3
debug1: Local version string SSH-2.0-OpenSSH_9.8p1 Debian-1
debug1: Remote protocol version 2.0, remote software version OpenSSH_9.8p1 Debian-1
debug1: Authenticating to db-01:22 as 'admin'
debug1: Authentications that can continue: gssapi-with-mic,publickey,password
debug1: Next authentication method: gssapi-with-mic
debug1: Unspecified GSS failure. Minor code may provide more information
debug1: No Kerberos credentials available (default cache: KEYRING:persistent:1000)
debug1: Next authentication method: publickey
debug1: Server accepts key: /home/admin/.ssh/id_ed25519
Authenticated to db-01 ([10.20.30.41]:22) using "publickey".
debug1: Entering interactive session.
Meaning: The client tried GSSAPI first. If you see a multi-second pause between “Next authentication method: gssapi-with-mic” and the failure, GSSAPI negotiation is costing you.
Decision: If you don’t use Kerberos SSH SSO, disable GSSAPI on client and/or server. If you do use it, verify KDC reachability and DNS for SRV/realm mapping.
Task 2: Time the SSH connection precisely
cr0x@server:~$ /usr/bin/time -p ssh -o PreferredAuthentications=publickey -o GSSAPIAuthentication=no admin@10.20.30.41 true
real 0.32
user 0.06
sys 0.03
Meaning: With GSSAPI off and a direct IP, it’s fast. That strongly implicates GSSAPI and/or DNS when using hostnames.
Decision: If this is fast but normal SSH is slow, you have a configuration/path issue rather than CPU, crypto, or network baseline.
Task 3: Compare hostname vs IP performance
cr0x@server:~$ /usr/bin/time -p ssh admin@db-01 true
real 8.74
user 0.07
sys 0.03
Meaning: Name-based connection is slow; this often means client-side DNS (search domains, IPv6 preference, or broken resolver).
Decision: Investigate DNS resolution on the client: getent hosts, resolver config, and whether AAAA lookups time out.
Task 4: Watch DNS resolution through glibc/NSS (client or server)
cr0x@server:~$ getent hosts db-01
10.20.30.41 db-01.corp.example db-01
Meaning: getent uses NSS (not just raw DNS). If it’s slow, SSH using hostnames will be slow too.
Decision: If getent pauses, inspect /etc/nsswitch.conf and name services (DNS, files, ldap, mdns). You may be stuck on LDAP or a dead resolver.
Task 5: Verify reverse DNS lookup speed for a client IP (server-side)
cr0x@server:~$ getent hosts 10.20.99.17
10.20.99.17 laptop-17.vpn.example
Meaning: This is the same lookup sshd might do for logging and policy. If it takes seconds or times out, sshd will wait.
Decision: If slow or empty, either fix PTR records and resolver reachability, or disable UseDNS in sshd to stop waiting on reverse DNS.
Task 6: Confirm forward-confirmation (PTR maps back)
cr0x@server:~$ getent hosts laptop-17.vpn.example
10.20.99.17 laptop-17.vpn.example
Meaning: Forward lookup returns the original IP. That’s a clean mapping and reduces weird sshd behavior when it attempts a forward-confirmed check.
Decision: If forward points somewhere else, fix DNS. If you can’t (third-party networks), disable UseDNS and avoid hostname-based access controls.
Task 7: Check resolver configuration quickly
cr0x@server:~$ cat /etc/resolv.conf
nameserver 127.0.0.53
options edns0 trust-ad
search corp.example vpn.example
Meaning: Stub resolver at 127.0.0.53 usually indicates systemd-resolved is in the path. Search domains can cause multiple query attempts.
Decision: If search domains are long or incorrect, trim them. If systemd-resolved is unhealthy, fix it or point resolv.conf at real DNS servers.
Task 8: Inspect systemd-resolved status and upstream servers
cr0x@server:~$ resolvectl status
Global
Protocols: -LLMNR -mDNS -DNSOverTLS DNSSEC=no/unsupported
resolv.conf mode: stub
Current DNS Server: 10.20.1.10
DNS Servers: 10.20.1.10 10.20.1.11
DNS Domain: corp.example
Meaning: Confirms which DNS servers are actually used. If those servers are only reachable from some VLANs, you’ve found why SSH is slow from “that one place.”
Decision: Fix routing/firewall to DNS servers, or configure per-link DNS correctly. Don’t leave clients guessing.
Task 9: Test raw DNS query latency (server-side) with dig
cr0x@server:~$ dig +tries=1 +time=2 -x 10.20.99.17 @10.20.1.10
; <<>> DiG 9.20.0-1-Debian <<>> +tries=1 +time=2 -x 10.20.99.17 @10.20.1.10
;; global options: +cmd
;; Got answer:
;; ->HEADER<- opcode: QUERY, status: NOERROR, id: 11421
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; ANSWER SECTION:
17.99.20.10.in-addr.arpa. 300 IN PTR laptop-17.vpn.example.
;; Query time: 18 msec
;; SERVER: 10.20.1.10#53(10.20.1.10) (UDP)
;; WHEN: Mon Dec 30 10:11:25 UTC 2025
;; MSG SIZE rcvd: 92
Meaning: 18 ms is fine. If you see 2000 ms or timeouts, that’s your SSH delay. SSH is not special; it’s just waiting for DNS.
Decision: If query time is high, fix DNS latency or disable UseDNS. If it times out, check network ACLs and whether TCP/UDP 53 is blocked.
Task 10: Find sshd’s current effective settings
cr0x@server:~$ sudo sshd -T | egrep 'usedns|gssapiauthentication|gssapicleanupcredentials|loglevel'
gssapiauthentication yes
gssapicleanupcredentials yes
usedns yes
loglevel INFO
Meaning: This is the truth, including defaults and included config fragments. If usedns yes and reverse DNS is slow, sshd will likely stall.
Decision: If you don’t require hostname-based access control and you have flaky reverse DNS, set UseDNS no. If you don’t use Kerberos SSO, set GSSAPIAuthentication no.
Task 11: Observe sshd logs for timing gaps
cr0x@server:~$ sudo journalctl -u ssh -S -5m --no-pager
Dec 30 10:12:04 db-01 sshd[28192]: Connection from 10.20.99.17 port 51844 on 10.20.30.41 port 22 rdomain ""
Dec 30 10:12:12 db-01 sshd[28192]: Accepted publickey for admin from 10.20.99.17 port 51844 ssh2: ED25519 SHA256:Qq5pZx...
Dec 30 10:12:12 db-01 sshd[28192]: pam_unix(sshd:session): session opened for user admin(uid=1000) by (uid=0)
Meaning: Eight seconds between “Connection from …” and “Accepted publickey …” often indicates pre-auth delay: DNS reverse lookup or GSSAPI attempt before key auth.
Decision: Correlate with client -vvv output. If the pause is before “Accepted publickey,” adjust UseDNS/GSSAPI; if after, look at PAM and shell init.
Task 12: Run a debug sshd on an alternate port (safe, temporary)
cr0x@server:~$ sudo /usr/sbin/sshd -D -ddd -p 2222
debug3: sshd version OpenSSH_9.8p1 Debian-1
debug1: Bind to port 2222 on 0.0.0.0.
Server listening on 0.0.0.0 port 2222.
debug1: Connection from 10.20.99.17 port 51852 on 10.20.30.41 port 2222 rdomain ""
debug2: fd 4 setting O_NONBLOCK
debug3: mm_getpwnamallow: entering
debug3: mm_answer_pwnamallow: entering
debug1: userauth-request for user admin service ssh-connection method gssapi-with-mic [preauth]
Meaning: -ddd is noisy but it shows what method is being attempted and where it stalls. If output freezes after a reverse lookup or GSSAPI line, you’ve isolated the culprit without touching the production sshd process.
Decision: Use this only briefly and on a protected host. Once confirmed, stop it and apply config changes to the real service.
Task 13: Validate Kerberos basics (only if you actually use it)
cr0x@server:~$ klist
klist: No credentials cache found (filename: /tmp/krb5cc_1000)
Meaning: No ticket exists, so GSSAPI auth will fail and may be slow if realm discovery is slow.
Decision: If you want Kerberos SSO, obtain a ticket (kinit) and fix realm/KDC discovery. If you don’t, disable GSSAPI for SSH to avoid pointless attempts.
Task 14: Check whether ssh is offering GSSAPI (client config)
cr0x@server:~$ ssh -G admin@db-01 | egrep 'gssapiauthentication|preferredauthentications'
gssapiauthentication yes
preferredauthentications gssapi-with-mic,publickey,password
Meaning: Client will try GSSAPI first. Even if the server is fine, the client can waste time attempting it.
Decision: Disable client-side GSSAPI for affected hosts, or globally if you don’t use it anywhere.
Task 15: Confirm SSHD config fragments (Debian includes)
cr0x@server:~$ sudo grep -R --line-number -E 'UseDNS|GSSAPIAuthentication|Include' /etc/ssh/sshd_config /etc/ssh/sshd_config.d/*.conf
/etc/ssh/sshd_config:5:Include /etc/ssh/sshd_config.d/*.conf
/etc/ssh/sshd_config.d/50-cloud-init.conf:2:UseDNS yes
/etc/ssh/sshd_config.d/50-cloud-init.conf:3:GSSAPIAuthentication yes
Meaning: Your “real” settings might be coming from a drop-in. People edit /etc/ssh/sshd_config, restart ssh, and wonder why nothing changed.
Decision: Change the right file (prefer a new drop-in with higher precedence, e.g., 99-local.conf), then verify with sshd -T.
Task 16: Validate SSH configuration before reload
cr0x@server:~$ sudo sshd -t
Meaning: No output means syntax is OK. If there’s an error, sshd prints it and exits non-zero.
Decision: Never restart sshd without sshd -t first on a remote system. You only get to brick your access once before it becomes a personality trait.
Fixes that actually move the needle (UseDNS, GSSAPI, and friends)
Fix 1: Disable reverse DNS lookups in sshd (most common win)
If your organization does not rely on hostname-based SSH access controls (for example, you’re not matching hostnames in AllowUsers/DenyUsers patterns, and you’re not doing host-based auth tied to DNS), disable it.
cr0x@server:~$ sudo tee /etc/ssh/sshd_config.d/99-local.conf >/dev/null <<'EOF'
UseDNS no
EOF
What it does: Prevents sshd from doing reverse DNS lookups of the client IP during connection handling. Your logs will use IPs more consistently. Your login will stop waiting on PTR timeouts.
Trade-off: You lose automatic hostname resolution in sshd logs (you’ll see IPs). For incident response, IPs are often better anyway because they’re harder to “rename.”
cr0x@server:~$ sudo sshd -t
cr0x@server:~$ sudo systemctl reload ssh
cr0x@server:~$ sudo sshd -T | egrep 'usedns'
usedns no
Decision point: If reload works and sshd -T shows usedns no, retest SSH from the problematic client network. If the slowness disappears, your PTR/DNS path is the root cause. Then fix DNS properly if you want nicer logs; you’re no longer blocked.
Fix 2: Disable GSSAPIAuthentication in sshd (when you don’t use Kerberos SSH)
Many environments don’t use Kerberos SSH, but they still inherit configurations that enable it. That’s wasted time and extra failure modes. Disable it unless you can say, out loud, why it must be enabled.
cr0x@server:~$ sudo tee /etc/ssh/sshd_config.d/99-local.conf >/dev/null <<'EOF'
UseDNS no
GSSAPIAuthentication no
EOF
cr0x@server:~$ sudo sshd -t
cr0x@server:~$ sudo systemctl reload ssh
cr0x@server:~$ sudo sshd -T | egrep 'gssapiauthentication|usedns'
gssapiauthentication no
usedns no
Decision point: If you rely on Kerberos for SSH SSO, don’t do this globally. Instead, use Match blocks or per-host client config to keep it where it’s needed and disable it where it’s not.
Fix 3: Disable GSSAPI on the client side (fast containment)
If you can’t change the server (managed appliance, political friction, or change freeze), turn off GSSAPI on the client. This is especially useful for jump hosts and operator laptops.
cr0x@server:~$ tee -a ~/.ssh/config >/dev/null <<'EOF'
Host *.corp.example
GSSAPIAuthentication no
PreferredAuthentications publickey,password
EOF
Meaning: You stop attempting GSSAPI first, and you don’t pay the negotiation cost.
Decision: Roll this out to affected user groups. If you have centralized dotfile management, keep it targeted; don’t break the one team that actually uses Kerberos.
Fix 4: Make DNS fast and boring (the real fix)
Disabling UseDNS is a valid mitigation. Fixing DNS is the cure. In production systems, you want both: stop the bleeding now, then remove the underlying risk.
Concrete DNS improvements that matter for SSH latency:
- Ensure all client subnets that reach servers also have working reverse zones (PTR records) or at least non-timeouting responses.
- Ensure DNS servers are reachable from every network path where SSH originates (VPN, bastions, office Wi-Fi, CI runners).
- Reduce resolver timeouts and retries only if you understand the blast radius. Over-tuning resolver timeouts is how you turn intermittent DNS into “everything fails fast.”
- Trim useless search domains. Each extra suffix is extra queries during failure.
Fix 5: Avoid hostname-based access controls if DNS is not trustworthy
If you have AllowUsers *@somehost-style logic based on client hostnames, you’re making DNS part of your security perimeter. That can work, but only if DNS is correct, fast, and controlled. In many networks, it is none of those.
Prefer IP-based controls (firewall rules, security groups) or key-based identity controls (authorized_keys, certificates). Use hostnames for convenience, not enforcement, unless you’re ready to operate DNS like a critical system—because it is.
Fix 6: If slowness is after authentication, don’t scapegoat DNS
This article is about DNS and GSSAPI because they cause “instant” improvements in the most common slow-login case. But if your delay is after successful auth, check:
pam_mkhomedircreating home directories on first login- Networked home directories (NFS/Autofs) waiting on mounts
- SSSD/LDAP delays in PAM account/session
- Slow shell startup scripts (
.bashrc,.profile) calling out to network commands
Different pipeline stage, different fix. Diagnose before you change.
Three corporate mini-stories from the trenches
1) The incident caused by a wrong assumption: “Reverse DNS is optional”
The company was mid-migration to a new VPN vendor. The project plan covered routes, MFA, and client rollout. Reverse DNS didn’t make the list because, historically, nobody “used” it. That assumption was true in the narrow sense that no one had filed a ticket titled “PTR records.”
On day one, engineers started reporting that SSH to production hosts took 20–30 seconds before a password prompt. Some sessions were fine; others weren’t. The common factor turned out to be the new VPN address pool. It lived in a new subnet with no reverse zone delegated, and the DNS servers for that subnet were accessible only from inside the datacenter—not from the segment where sshd was running.
The on-call team initially chased CPU and entropy. They looked at load averages, checked random number generation, and even toggled a few ciphers “just to see.” Nothing stuck. Meanwhile, the helpdesk logged “SSH unreliable” incidents and escalated them as “server performance regressions.”
The fix was boring: either add PTR records (and make DNS reachable from the servers) or stop sshd from waiting on reverse DNS. They chose a two-step approach: immediate mitigation was UseDNS no. Then the network team implemented reverse zones for the VPN pools and validated reachability from every server VLAN that accepted SSH. The second step mattered because other systems—log enrichment and SIEM correlation—also benefited. But SSH got its prompt back in minutes, and that’s what bought them time.
2) The optimization that backfired: “Let’s tighten resolver timeouts”
A different organization got sick of long application hangs during DNS outages. Someone, with good intentions and a little too much confidence, changed resolver behavior broadly: fewer retries, shorter timeouts. It made failures faster, which sounded like a win.
Then they got a new kind of outage: not “DNS is down,” but “DNS is flaky.” Under light packet loss, the old configuration might have recovered on a retry. The new one failed quickly and consistently. SSH was one of the first canaries: login attempts would fail or take strange paths (IPv6 attempts failing, falling back to IPv4, then trying GSSAPI, then timing out).
The operational result was worse than before. Instead of slow-but-eventually-working sessions, engineers got intermittent lockouts from jump hosts. That raised the stakes because now troubleshooting required access that was itself degraded.
The lesson wasn’t “never tune timeouts.” It was: tune them with measurement and scope. They rolled back the global resolver tweaks, then applied narrower policies for specific services with proper retry logic. SSH went back to being boring. In production, boring is a feature.
3) The boring but correct practice that saved the day: “Always keep an out-of-band path and reload, don’t restart”
An infrastructure team planned to disable UseDNS and GSSAPIAuthentication across a fleet of Debian 13 servers after repeated complaints about slow logins from a partner network. They did the right thing: wrote a drop-in file, validated syntax with sshd -t, and used systemctl reload instead of a restart.
During rollout, one host behaved differently. A legacy config fragment had a typo in an unrelated directive. It had never been noticed because sshd was already running and nobody had triggered a full config parse recently. The reload would have failed if they’d used a restart. Worse: a restart might have killed their only remote access path.
Because they used validation and reload, they caught it safely. They fixed the typo, reloaded again, and moved on. No heroics, no emergency console access, no panicked “can someone in the datacenter plug in a monitor.”
They also had a second access path via a bastion with a different auth mechanism. It never got used, but that’s the point. Redundancy is insurance: expensive right up until it’s cheap.
Common mistakes: symptom → root cause → fix
1) Symptom: 10–30s pause before password prompt
Root cause: sshd waiting on reverse DNS (PTR) for client IP; resolver retries/timeouts.
Fix: Set UseDNS no in sshd, and/or fix PTR records and DNS reachability. Verify with sshd -T and getent hosts <client-ip>.
2) Symptom: pause on “Next authentication method: gssapi-with-mic”
Root cause: GSSAPI/Kerberos negotiation attempted first; realm/KDC discovery slow or failing.
Fix: Disable GSSAPIAuthentication on client/server if unused. If used, fix Kerberos config, KDC reachability, and DNS SRV/realm mapping.
3) Symptom: SSH by IP is instant, by hostname is slow
Root cause: Client-side DNS resolution issues (search domains, IPv6 AAAA timeouts, bad resolver).
Fix: Use getent hosts and resolvectl status to find where resolution stalls. Correct resolver servers and search domains; consider AddressFamily inet as a diagnostic (not a permanent crutch).
4) Symptom: delay after “Authenticated” but before prompt
Root cause: PAM session modules, network home mounts, SSSD/LDAP, or shell startup scripts.
Fix: Check journalctl -u ssh for session timing, then inspect PAM config and user shell initialization. Don’t waste time toggling UseDNS if the delay is post-auth.
5) Symptom: only VPN users see slow logins
Root cause: Reverse DNS zone missing for VPN pool or DNS servers unreachable from the server network path. Sometimes MTU/fragmentation issues make DNS “kind of” work.
Fix: Implement PTR for VPN pools and ensure DNS is reachable; in parallel, disable UseDNS to remove the dependency.
6) Symptom: changing /etc/ssh/sshd_config did nothing
Root cause: Debian config includes drop-ins in /etc/ssh/sshd_config.d/; a fragment overrides your setting.
Fix: Use sshd -T to confirm effective config and search fragments with grep -R. Put your override in 99-local.conf.
Checklists / step-by-step plan (safe rollout)
Step-by-step: speed up logins safely on a single Debian 13 server
- Confirm the bottleneck. From a client, run
ssh -vvvand note where it pauses. - Test reverse DNS from the server. Run
getent hosts <client-ip>; if slow, you have your likely cause. - Check effective sshd settings. Run
sudo sshd -T | egrep 'usedns|gssapiauthentication'. - Create a local drop-in override. Use
/etc/ssh/sshd_config.d/99-local.confso you don’t fight vendor fragments. - Validate config. Run
sudo sshd -t. No output means OK. - Reload, don’t restart.
sudo systemctl reload sshkeeps existing sessions and reduces “oops.” - Verify the new effective config.
sudo sshd -Tagain. - Retest from the affected network. Time it with
/usr/bin/time -p ssh ... true. - Watch logs. Check
journalctl -u ssh -S -5mfor improved timing. - Then fix DNS properly. If UseDNS was masking broken PTR/DNS reachability, schedule DNS remediation. Operational debt accumulates interest.
Change-management checklist: fleet rollout without drama
- Pick 2–3 representative hosts (different subnets, roles, authentication patterns).
- Capture baseline timings (hostname and IP, with and without GSSAPI).
- Implement config via automation (one drop-in file, consistent across hosts).
- Reload sshd in batches; monitor for authentication anomalies.
- Confirm no teams depend on Kerberos SSH before disabling GSSAPI server-wide.
- Ensure you have an alternate access path (bastion, console, out-of-band) before touching SSH at scale.
- After rollout, verify: sshd effective config, login latency, and log clarity.
FAQ
1) Should I always set UseDNS no on servers?
In most environments: yes. If you’re not using hostname-based access controls in sshd, disabling it removes a fragile dependency and speeds logins under DNS trouble.
2) Does disabling UseDNS reduce security?
It can reduce misplaced security. If you were relying on client hostnames for access control, that’s already shaky. Prefer IP-based network controls and key/cert-based identity.
3) We use Kerberos. Can we still fix slow SSH without disabling GSSAPI?
Yes. Fix the underlying Kerberos/DNS path: ensure KDCs are reachable, realm mapping is correct, and DNS SRV records resolve quickly from the server and client networks.
4) Why is SSH slow only from one office or VPN?
Because DNS reachability and reverse zones are often different per network. That office might hit a different resolver, or the VPN pool might lack PTR records.
5) I disabled GSSAPI on the server, but clients are still slow. Why?
Clients can still be slow resolving the server hostname (client-side DNS), or the delay is post-auth (PAM, mounts, shell scripts). Use ssh -vvv plus server logs to locate the stage.
6) What’s the safest way to test sshd changes remotely?
Use sshd -t before applying changes, then systemctl reload ssh. For deeper debugging, run a separate debug sshd on port 2222 temporarily.
7) Can IPv6 cause slow SSH logins even if we “don’t use IPv6”?
Yes. Clients may attempt AAAA lookups and IPv6 connects first. If IPv6 is half-enabled (routes missing, firewalls blocking), you get timeouts. Diagnose with hostname vs IP timing and resolver tests.
8) Will disabling UseDNS break anything else?
It mostly changes how sshd resolves and logs client names. If you have log processing that expects hostnames, adjust it. Operationally, logging IPs is usually fine.
9) My delay is after “session opened” in logs. Is this still DNS/GSSAPI?
Less likely. That points to PAM session work, network home directories, or shell startup. The fix is in PAM, SSSD/LDAP, automounting, or user dotfiles—not sshd’s UseDNS.
10) What’s the difference between fixing DNS and just disabling UseDNS?
Disabling UseDNS stops sshd from waiting on reverse lookups. Fixing DNS improves the whole environment: log enrichment, Kerberos, service discovery, and anything else that does lookups. Do both if you can.
Conclusion: what to do next
If SSH logins on Debian 13 are slow, don’t guess. Locate the pause with ssh -vvv, confirm DNS behavior with getent/dig, and verify effective sshd settings with sshd -T. Then do the practical thing:
- Set
UseDNS nounless you have a specific, tested reason not to. - Set
GSSAPIAuthentication nounless you run Kerberos SSH SSO and can prove it’s healthy. - Reload sshd safely (validate config, reload not restart).
- Fix DNS properly afterward: reverse zones for client subnets, reachable resolvers, and fewer “creative” search domains.
Your reward is immediate: SSH stops feeling like it’s thinking deeply about your request, and starts behaving like a tool again.