sshd Linux auth.log / journal Triage: low

sshd "Invalid user … from … port …": What the Line Means

Published

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.

What it looks like

Oct 18 03:51:11 web1 sshd-session[48211]: Invalid user admin from 203.0.113.7 port 54321

  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

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]: Invalid user admin from 203.0.113.7 port 54321
Oct 18 03:51:12 web1 sshd-session[48213]: Invalid user postgres from 203.0.113.7 port 54337
Oct 18 04:02:44 web1 sshd-session[48502]: Invalid user solana from 198.51.100.22 port 40118

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

Invalid user … from … port …

72,194

lines · about 2,406 a day · 1,455 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.

  • Invalid user %.100s from %.100s port %d message · auth.c:495 (OpenSSH)

What it means

sshd writes this line during user authentication when the name the client asked to log in as is not a valid account on this host. Nothing was checked against a real user: there is no stored password hash and no authorized_keys file behind the name, so the attempt cannot succeed.

To avoid leaking which names exist, sshd does not drop the connection at this point. It carries on the authentication dialogue against a dummy record, so a password attempt against an invalid name takes roughly as long as one against a real account. That is why an Invalid user line is normally followed by one or more Failed password for invalid user … lines from the same PID before the client gives up or is disconnected.

The fields in the message are the requested user name, the client address and the client’s source port. The source port is the detail most people skip and the one that lets you match the line to a firewall, NAT or flow record for the same connection. An account that exists but is refused — not listed in AllowUsers, matched by DenyUsers, locked, or without a valid shell — does not produce this line. sshd logs User … from … not allowed because … instead, and the failures that follow still read Failed password for invalid user …, because sshd treats the refused account as invalid for the rest of the connection. So “invalid user” in a Failed line does not prove the name is missing; an Invalid user line does.

Is it an attack?

Almost always, in the sense that it is unsolicited: hosts with port 22 open to the internet receive a constant stream of these from scanners and botnets working through name lists. On its own one line is background radiation. The shape around it is what matters.

PatternReading
One address, dozens of different names in minutesAccount enumeration / dictionary brute force
Many addresses, the same short name list (root, admin, test, ubuntu)Distributed botnet sweep, untargeted
Names matching your products or staff (deploy, postgres, solana)The host was fingerprinted; the list is tailored
An internal address, one name, on a regular scheduleA cron job, backup agent or CI runner using an account that no longer exists
Invalid user from an address, then an Accepted line from the same addressInvestigate immediately — the attacker eventually used a name that works

Note that root never produces this line: root is a valid account, so failures for it appear differently. A real user name in a failure message without the words “invalid user” is a stronger signal than a hundred invalid ones.

How to investigate

Count sources and names before you judge anything. On Debian/Ubuntu the unit is ssh and the file is /var/log/auth.log; on RHEL/Fedora use -u sshd and /var/log/secure.

# Last 24 hours, straight from the journal (Debian/Ubuntu)
sudo journalctl -u ssh --since "24 hours ago" | grep "Invalid user"

# Busiest source addresses
sudo grep -oP 'Invalid user \S+ from \K\S+' /var/log/auth.log \
  | sort | uniq -c | sort -rn | head -20

# Most-tried user names
sudo grep -oP 'Invalid user \K\S+' /var/log/auth.log \
  | sort | uniq -c | sort -rn | head -20

# Failures against names that DO exist — these matter more
sudo grep "Failed password for" /var/log/auth.log | grep -v "invalid user"

# Did anything from those addresses ever get in?
sudo grep -E "Accepted (password|publickey)" /var/log/auth.log | tail -50

Compare the name list against /etc/passwd. If an internal host is the source, find the job: the user name in the line is usually the account a script was told to use. For bulk analysis of an exported auth.log, the free browser log analyzer groups these lines by source and user name, and the SSH brute-force rule encodes the “one source, many names” pattern as a detection.

How to stop it

You cannot stop strangers from asking; you can make the answer irrelevant and quiet.

  • Turn off password authentication. PasswordAuthentication defaults to yes, so set it explicitly, and set KbdInteractiveAuthentication no as well if PAM is in play — the manual notes that PAM keyboard-interactive authentication usually serves an equivalent role to password authentication.
  • Keep PermitRootLogin at or below the default of prohibit-password, which disables password and keyboard-interactive authentication for root.
  • Restrict who may log in at all with AllowUsers; by default login is allowed for all users, and the directive also accepts USER@HOST patterns with CIDR host criteria.
  • Leave PerSourcePenalties enabled — penalties are on by default, and a client that disconnects after unsuccessful authentication attempts is refused for 5 seconds, accumulating up to a maximum of 10 minutes.
  • Keep LoginGraceTime (default 120 seconds) and MaxAuthTries (default 6) tight so each connection costs the scanner time and gives it few tries.
  • Best of all, do not expose 22 to the whole internet: restrict it at the firewall or put it behind a VPN or bastion. Moving to a non-standard port reduces log volume but not risk.
sudo sshd -t && sudo systemctl reload ssh

Always validate the configuration before reloading, and keep an existing session open until you have proved a new one works.

Lines you will see next to it

  • … 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".
  • check pass; user unknown pam_unix was asked to check a password for a name it has no account record for, so the attempt failed before any password was compared — and the line deliberately leaves out both the name and the source address.
  • 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.
  • Disconnected from … 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.

Detect it

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

Frequently Asked Questions

Does "Invalid user" mean someone guessed a password?
No. The line is written because the requested name is not a valid account on the host, so there was no stored password or key to compare anything against. The attempt could not have succeeded no matter what the client sent, which is why these lines are evidence of name guessing rather than of a credential compromise.
Should I alert on every Invalid user line?
Not on single lines — any host with port 22 reachable from the internet sees them continuously. Alert on shape instead: one source address trying many different names within a few minutes, a name that matches one of your real accounts, or any successful authentication from an address that was producing these lines.
What is the port number at the end of the line?
It is the client's source port for that TCP connection, not a port on your server. It is useful for correlation — it lets you tie the sshd line to the matching firewall, NAT or netflow record, and to group several auth.log lines that belong to the same connection.
Password authentication is disabled here, so can I ignore these?
They cannot succeed, but do not ignore them entirely. The set of names tried tells you what the scanner expects to find — generic names such as admin or test are untargeted, while application or staff names suggest the host was fingerprinted. Also confirm no key-based login succeeded from the same addresses.

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.