sshd Linux auth.log / journal Triage: low

sshd "Disconnected from authenticating/invalid user …": What It Means

Published

The client told sshd which account it wanted and then ended the connection before authentication succeeded, so the line names that account along with the source address and port.

What it looks like

Oct 18 03:51:11 web1 sshd-session[48211]: Disconnected from invalid user admin 203.0.113.7 port 54122 [preauth]

  1. 1Time — When it was logged; this format has no year or time zone
  2. 2Host — The server’s host name
  3. 3Program — sshd-session, one process per connection, and its process ID: a connection’s lines share it
  4. 4User — The account name
  5. 5Source address — The client’s IP address
  6. 6Source port — The client’s source port; with the address it identifies one connection
  7. 7[preauth] — Logged before the user authenticated

Example lines as /var/log/auth.log shows them (/var/log/secure on RHEL and Fedora):

Oct 18 03:51:11 web1 sshd-session[48211]: Disconnected from invalid user admin 203.0.113.7 port 54122 [preauth]
Oct 18 03:51:44 web1 sshd-session[48230]: Disconnected from authenticating user root 198.51.100.22 port 40118 [preauth]
Oct 18 04:07:02 web1 sshd-session[48502]: Disconnected from authenticating user deploy 192.0.2.44 port 51902 [preauth]

On our own server, the 30 days to 25 October 2026

Disconnected from …

26,063

lines · about 869 a day · 1,246 source addresses

Last seen 25 October 2026

LogTriage's production API server (Hetzner, Germany): port 22 open to the internet, key-only since 6 October 2026 (password and keyboard-interactive authentication off); nginx in front of the API on ports 80 and 443. Counted weekly from the sshd journal; no address ever leaves the server. More in the monthly attack report; which free blocklists already list these attackers is measured in the IP blocklist report, and you can check the addresses in your own log.

Where the line comes from

Format strings as written in the source of OpenSSH 10.2p1 — the versions this server runs. Each links to the exact line.

  • Disconnected from %s message · packet.c:2031 (OpenSSH)
  • %.200s%s%s port %d connection id: preamble, address, port · packet.c:2004 (OpenSSH)
  • authctxt->valid ? "authenticating " : "invalid ", user); preamble: authenticating or invalid user · auth2.c:312 (OpenSSH)
  • %suser %s preamble format · auth2.c:311 (OpenSSH)
  • mon_dispatch == mon_dispatch_postauth20 ? "postauth" : "preauth"); the [preauth] tag on lines from the pre-authentication process · monitor.c:481 (OpenSSH)

What it means

Disconnected from … comes from sshd’s connection-terminating error handler in packet.c. Three branches sit next to each other there: one logs Connection closed by %s, one logs Connection reset by %s when a system call fails with errno == ECONNRESET, and this one logs Disconnected from %s for the SSH_ERR_DISCONNECTED case. The handler logs and exits — the connection is finished either way.

The %s is a connection identifier built as %.200s%s%s port %d: an optional logging preamble, the client’s IP address, and the client’s source port for that one TCP connection. The port is what lets you tie this line to the other lines sharing the same PID.

Every line matching this page’s pattern carries the preamble, so every one of them names an account. sshd installs the preamble while handling the client’s first authentication request, writing authenticating user <name> when the account lookup produced a usable record and invalid user <name> when it did not — in that case the code substitutes fake password information, the same decision described on the Invalid user page. That happens before any password or key is evaluated, so the line says only which account the client asked for, never that a credential was tried or accepted.

[preauth] is appended by sshd’s monitor to messages relayed from the pre-authentication process. Its presence means the connection never reached an authenticated session.

Is it an attack?

PatternReading
invalid user <random name>, one or two per sourceScanner working through a stock name list — noise
invalid user …, many different names from one source in minutesName guessing or spraying; correlate with Invalid user lines on the same PIDs
authenticating user <real account>, no password failures nearbyA client that asked for a real account and gave up when its method was refused
authenticating user <real account> right after Failed password linesBrute force against an account that exists — higher priority
Same source producing these and then an Accepted lineStop triaging and investigate the session
One internal host, one account, repeating on a scheduleUsually a misconfigured automation client, not an attack

The line is the ending of a story told by the lines before it on the same PID, so always read the connection as a whole rather than the disconnect alone.

How to investigate

Pivot on the account name, the source address and the PID.

# Last 24 hours from the journal (Debian/Ubuntu unit is ssh; RHEL/Fedora use -u sshd)
sudo journalctl -u ssh --since "24 hours ago" | grep "Disconnected from"

# Which accounts clients named before disconnecting (/var/log/auth.log; RHEL/Fedora /var/log/secure)
sudo grep -oP 'Disconnected from (?:authenticating|invalid) user \K\S+' \
  /var/log/auth.log | sort | uniq -c | sort -rn | head -20

# Busiest source addresses
sudo grep -oP 'Disconnected from (?:authenticating|invalid) user \S+ \K\S+' \
  /var/log/auth.log | sort | uniq -c | sort -rn | head -20

# Only the valid-account ones — these name accounts sshd was willing to try
sudo grep 'Disconnected from authenticating user' /var/log/auth.log | tail -40

# The full story of one connection, by PID
sudo grep 'sshd-session\[48230\]' /var/log/auth.log

# Did any of these sources actually get in?
sudo grep -E 'Accepted (password|publickey)' /var/log/auth.log | tail -50

Check the names from the second command against /etc/passwd: an authenticating user preamble for a real service or staff account is worth more of your time than a thousand invalid user disconnects. For an exported auth.log, the browser log analyzer groups these lines by source, and the SSH brute-force rule encodes the one-source-many-names pattern as a detection.

How to stop it

A remote client can always hang up, so aim for fewer unwanted connections and nothing worth guessing.

  • Keep port 22 off the open internet where you can — firewall it to known ranges, or put it behind a VPN or bastion. Nothing else reduces the volume as much.
  • Leave PerSourcePenalties enabled. The manual says penalties are on by default: a client that disconnects after one or more unsuccessful authentication attempts is refused for 5 seconds by default, accumulating up to a maximum of 10 minutes, with a minimum of 15 seconds accrued before enforcement begins. The noauth penalty (default 1s) covers clients that disconnect without attempting authentication, and the manual warns to use it cautiously as it may penalise legitimate scanning tools such as ssh-keyscan(1).
  • Remove passwords from the equation with PasswordAuthentication no (the default is yes) and, where PAM is enabled, KbdInteractiveAuthentication no — the manual notes PAM keyboard-interactive authentication usually serves an equivalent role to password authentication.
  • Keep MaxAuthTries (default 6) and LoginGraceTime (default 120 seconds) tight, so a connection that guesses or lingers is cut off sooner.
  • Limit who may log in with AllowUsers; by default login is allowed for all users, and patterns may take the USER@HOST form with CIDR host criteria. PermitRootLogin defaults to prohibit-password.
sudo sshd -t && sudo systemctl reload ssh

Validate the configuration before reloading, and keep an existing session open until a new one works.

Lines you will see next to it

  • Invalid user … from … port … sshd rejected the login because the name the client asked for is not a valid account on this host, so no password or key was ever checked against a real user.
  • … for … from … port … ssh2… sshd rejected a password authentication attempt — the line names the account that was tried, the client address and the client's source port, and marks names that are not usable accounts on this host with "invalid user".
  • Connection closed by … The client at the other end of the SSH connection went away — closed it cleanly, or reset it — and sshd logged the address, port and (if the client had already named an account) the user it was trying before it quit.
  • Received disconnect from … port …:…: … The client told the server it was closing the connection — sshd logged the client's address and port, the numeric disconnect reason the client sent and the text that came with it.

Detect it

MITRE ATT&CK: T1110.001T1110.003T1021.004

Frequently Asked Questions

What is the difference between "Disconnected from" and "Connection closed by"?
They are two branches of the same connection-terminating error handler in sshd's packet layer. "Connection closed by" is logged for the SSH_ERR_CONN_CLOSED case, "Connection reset by" when a system call fails with ECONNRESET, and "Disconnected from" for the SSH_ERR_DISCONNECTED case — the disconnect path rather than a bare TCP close. In logs, the "Disconnected from" line usually follows a "Received disconnect from …" line with the same PID, because the client announced it was leaving.
Does "authenticating user deploy" mean the attacker authenticated as deploy?
No. The preamble is set when sshd handles the client's first authentication request, using "authenticating " when the account lookup returned a usable record and "invalid " when it did not. It only tells you the name matched something sshd was prepared to try. The "[preauth]" tag on the same line says the connection ended in the pre-authentication process, so no session was ever established.
Why do I still see these lines after turning password authentication off?
Because the user name preamble is installed as soon as the client asks to authenticate as somebody, before any password is checked. A client that only knows how to send passwords will still name an account, be offered methods it cannot use, and disconnect — producing this line with no "Failed password" line anywhere near it.
Should I alert on these lines?
Not on their own — on an internet-facing host they are ordinary scanner noise. Alert on the shape instead: one source naming many different accounts within minutes, any line with an "authenticating user" preamble for a real staff or service account, and above all an "Accepted" line from a source that had been producing these.

Run your own auth.log through it

Paste or drop /var/log/auth.log (or journalctl -u ssh output) into the free browser analyzer: brute force, password spraying, a successful login after failures and invalid-user sweeps are flagged with the evidence lines. Nothing is uploaded.