sshd Linux auth.log / journal Triage: informational

sshd "Accepted publickey" and "Accepted password": Successful SSH Login

Published

sshd authenticated the named account — the line records a completed SSH login with the method used, the user, the client address and source port, and for public keys the key type and fingerprint that was accepted.

What it looks like

Oct 18 03:51:11 web1 sshd-session[48211]: Accepted publickey for deploy from 203.0.113.7 port 54321 ssh2: ED25519 SHA256:0K3bVn2Q1sYgq7Wd9rHcLm4xPzT6uEa8ZfJiRvNtBoU

  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. 7Protocol — SSH protocol version 2
  8. 8Key type — The type of key that was accepted
  9. 9Key fingerprint — Its SHA256 fingerprint; ssh-keygen -lf ~/.ssh/authorized_keys prints the same form

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]: Accepted publickey for deploy from 203.0.113.7 port 54321 ssh2: ED25519 SHA256:0K3bVn2Q1sYgq7Wd9rHcLm4xPzT6uEa8ZfJiRvNtBoU
Oct 18 04:02:37 web1 sshd-session[48344]: Accepted publickey for backup from 198.51.100.22 port 40118 ssh2: RSA SHA256:9pQrLx2Dm7Yc4Vn1tKb6ZaWgEoJ3sHfUi0QvXdRy5Tk
Oct 16 21:14:02 web1 sshd-session[41190]: Accepted password for alice from 192.0.2.44 port 51902 ssh2

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

… for … from … port … ssh2…

19,863

lines · about 662 a day · 28 source addresses

Last seen 25 October 2026

… for … from … port … ssh2…

0

lines · about 0.00 a day

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.

… for … from … port … ssh2…

  • %s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s message · auth.c:294 (OpenSSH)
  • authmsg = authenticated ? "Accepted" : "Failed"; result word · auth.c:287 (OpenSSH)
  • authctxt->valid ? "" : "invalid user ", added for unknown users · auth.c:298 (OpenSSH)

… for … from … port … ssh2…

  • %s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s message · auth.c:294 (OpenSSH)
  • authmsg = authenticated ? "Accepted" : "Failed"; result word · auth.c:287 (OpenSSH)
  • authctxt->valid ? "" : "invalid user ", added for unknown users · auth.c:298 (OpenSSH)

What it means

Every authentication outcome sshd logs comes from one statement, do_log2() at auth.c:294, with the format %s %s%s%s for %s%.100s from %.200s port %d ssh2%s%s. Reading an Accepted line is reading that format left to right:

  • The result word. auth.c:287 is authmsg = authenticated ? "Accepted" : "Failed";. Accepted means this authentication attempt succeeded. The two branches above it produce Postponed and Partial instead.
  • The method, and a submethod joined by a slash when there is one (submethod != NULL ? "/" : "") — hence publickey, password, or forms such as keyboard-interactive/pam.
  • invalid user , inserted at auth.c:298 when the authentication context is not valid. On Accepted lines it is absent, so the account named is one the host knows.
  • The user name, then the client’s address and the client’s source port for that TCP connection.
  • The trailing text, built from format_method_key() or from auth_method_info. For public keys that is the key type and fingerprint of the key that was accepted; for a password there is nothing to describe, so the line ends at ssh2.

So the line is the moment the credential check passed. It does not say what the session then did, and it does not say the person at the other end is the account’s owner — only that a key or password that the server accepts was presented from that address.

Is it an attack?

PatternReading
Public key, known account, host and key fingerprint you recogniseRoutine login
Accepted from an address that produced a run of Failed password or Invalid user lines minutes earlierTreat as a compromise until proven otherwise
Accepted password on a host you believe is key-onlyConfiguration drift — PasswordAuthentication or KbdInteractiveAuthentication is still on somewhere
Public key whose fingerprint is not in your inventorySomeone may have appended a key to authorized_keys (ATT&CK T1098.004)
Accepted for a service or deploy account from an address that is not the CI runner or bastionStolen key material, or key reuse outside the intended path
Accepted for rootCompare against PermitRootLogin; the manual’s default is prohibit-password, which disables password and keyboard-interactive authentication for root

A single Accepted line is informational — healthy servers write them constantly. What changes its severity is what surrounds it: the failures before it, the account, the fingerprint and the source address.

How to investigate

# Every successful login in the last 24 hours
# (Debian/Ubuntu unit is ssh; on RHEL/Fedora use -u sshd)
sudo journalctl -u ssh --since "24 hours ago" \
  | grep -E 'Accepted (publickey|password|keyboard-interactive)'

# Who got in, with what method, from where (/var/log/auth.log; RHEL/Fedora: /var/log/secure)
sudo grep ' Accepted ' /var/log/auth.log \
  | awk '{for(i=1;i<=NF;i++) if($i=="Accepted") print $(i+1), $(i+3), $(i+5)}' \
  | sort | uniq -c | sort -rn

# Any password logins at all on a host that should be key-only?
sudo grep 'Accepted password' /var/log/auth.log

# Which key let them in? Compare the fingerprint on the line with the account's keys
sudo ssh-keygen -lf /home/deploy/.ssh/authorized_keys

# Did that source fail repeatedly before it succeeded?
sudo grep '203.0.113.7' /var/log/auth.log

# Everything one connection logged, by PID
sudo grep 'sshd-session\[48211\]' /var/log/auth.log

If the fingerprint is unknown, check the modification time and owner of every authorized_keys file before deleting anything, and keep a copy. If the source failed first and succeeded after, that is the brute-force-to-access transition the SSH brute-force rule is built around; an exported auth.log can be grouped by source and account in the browser log analyzer.

How to stop it

You do not stop Accepted lines — you decide who is able to produce one.

  • Turn off passwords. PasswordAuthentication and KbdInteractiveAuthentication both default to yes. Set both to no and Accepted password lines become impossible. The manual notes that because PAM keyboard-interactive authentication “usually serves an equivalent role to password authentication”, you should disable one of the two when UsePAM is enabled.
  • Keep keys as the only way in. PubkeyAuthentication defaults to yes; the keys read come from AuthorizedKeysFile, whose default is .ssh/authorized_keys plus .ssh/authorized_keys2. Monitor both paths for changes.
  • Narrow the account list with AllowUsers; by default login is allowed for all users, and the manual’s USER@HOST form also restricts particular users to particular hosts, with CIDR address matching.
  • Require two methods for sensitive hosts with AuthenticationMethods, for example publickey,keyboard-interactive — successful authentication then requires completing every method in one of the listed sets, and the first step appears as a Partial line.
  • Set PermitRootLogin deliberately rather than relying on the default.
sudo sshd -t && sudo systemctl reload ssh

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

Lines you will see next to it

Detect it

MITRE ATT&CK: T1078T1021.004T1098.004

Frequently Asked Questions

Does the line tell me which key was used?
For public key authentication, yes. The trailing text comes from `format_method_key()`, so the line ends with the key type and the key's SHA256 fingerprint. Run `ssh-keygen -lf` against the account's authorized_keys file and compare fingerprints to find out exactly which entry let the session in — and whether that entry is one you put there.
Why do "Accepted password" lines have nothing after "ssh2"?
The same format string ends with two optional strings that are filled from the key description or from `auth_method_info`. A password authentication has no key to describe, so both are empty and the line stops at `ssh2`. That difference is why the two messages need two different search patterns.
Can an "Accepted" line ever say "invalid user"?
The `invalid user ` text is inserted by the same statement whenever sshd's authentication context is not marked valid, which is why failures for unknown names read "Failed password for invalid user admin". In practice the accounts you see on Accepted lines are real accounts; treat an Accepted line as naming a user that exists on the host.
What does "Partial publickey" mean next to these lines?
It comes from the same log statement, two branches earlier — sshd writes "Partial" when a method succeeded but more are still required, and "Postponed" when the method is not finished. With AuthenticationMethods demanding two methods you see the first step logged as Partial and only the last one as Accepted.

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.