Every SSH login attempt on a Linux server — successful or not — is written down somewhere. Here are the commands to read those records, from a quick look to finding the IPs and usernames attackers try most. Examples are for Ubuntu and Debian; the differences on RHEL, Rocky, AlmaLinux and Amazon Linux are noted at the end.
Who is logged in right now
w
w lists current sessions: user, where they connected from, and what they're running. who gives a shorter version.
Recent successful logins
last -n 20
last reads /var/log/wtmp: who logged in, from which IP, when, and for how long. Check that every entry is you or someone you expect.
Recent failed logins
sudo lastb -n 20
lastb reads /var/log/btmp, the record of failed attempts. On an internet-facing server it's usually long — that's bots guessing passwords.
The full story: the auth log
SSH writes every attempt to /var/log/auth.log in plain text. The lines that matter:
Failed password for root from 198.51.100.12— a wrong password for an account that exists.Invalid user oracle from 203.0.113.9— someone tried an account that doesn't exist on your server.Accepted publickey for ubuntu from 192.0.2.10— a successful login. These are the ones to check.
How many failed attempts are in the current log:
sudo grep -c "Failed password" /var/log/auth.log
The IP addresses trying hardest:
sudo grep "Failed password" /var/log/auth.log \ | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c | sort -rn | head
The usernames they try that don't exist — a good view of what bots are hunting for:
sudo grep -oP 'Invalid user \K\S+' /var/log/auth.log | sort | uniq -c | sort -rn | head
And every successful login, so you can spot one you don't recognise:
sudo grep "Accepted" /var/log/auth.log
auth.log is rotated weekly; older weeks are in auth.log.1 and compressed auth.log.*.gz files — use zgrep instead of grep to search those.
Using journalctl instead
On systems that keep logs in the systemd journal, ask for the SSH service directly. On Ubuntu and Debian the service is called ssh:
sudo journalctl -u ssh --since today | grep -E "Failed|Invalid" sudo journalctl -u ssh -f # follow new attempts live
On RHEL, Rocky, AlmaLinux and Amazon Linux
The log file is /var/log/secure rather than auth.log, and the service is sshd. The same commands work with those names:
sudo grep -c "Failed password" /var/log/secure sudo journalctl -u sshd --since today | grep -E "Failed|Invalid"
What to do with what you find
- Lots of failures from many IPs is normal internet background noise. The fix is to make guessing pointless: SSH keys only, no password logins — step-by-step guide here.
- An "Accepted" line you don't recognise is serious. Check that user's
~/.ssh/authorized_keys, change passwords, and look at what ran during that session. - Watching this across several servers by hand gets old fast. ThreatGuard collects the same lines from all your servers into one live dashboard — attacking IPs with their country and network, the usernames tried, and successful logins from IPs that also failed — and blocks attackers automatically.