Linux Security·7 min read·

Detecting Brute-Force and Suspicious SSH Logins

Read auth logs like a security analyst, spot brute-force bursts and compromised accounts, and act on suspicious SSH login signals before they become a breach.

NB

Netbay Cloud Team

Netbay Engineering

On this page

Every SSH-facing server accumulates a log of everything that tried to get in. The question is whether you can read it. The auth log — /var/log/auth.log on Debian, /var/log/secure on RHEL — records every login attempt, failure, and success, and it is the first place to look when a server starts behaving oddly. This guide shows how to turn those logs from noise into signal: recognizing brute-force patterns, spotting a compromised account, checking login records for the clues that something is off, and acting before a curiosity becomes a breach.

From raw auth log to verdict RAW LOG attempts + sessions PATTERNS bursts, repeats odd users SESSIONS who logged in from where VERDICT block / chase act fast Signals: burst, repetition, geography, timing, odd usernames

Where the Records Live

First, know your log path. Debian and Ubuntu write authentication events to /var/log/auth.log; RHEL and Rocky write them to /var/log/secure. Both are root-readable, so you will be using sudo for the useful queries. When you grep the file, look for the key markers: "Failed password" records the attempts, "Accepted password" or "Accepted publickey" records successful logins, and "session opened" marks an interactive session start. The moment you learn to filter for those three signals, the log turns from an endless wall into a structured record of what touched the port.

Find the Brute-Force Burst

Random scanners hammer every public server; the tell is volume and repetition. When an attacker runs a dictionary, you see a tight cluster of "Failed password" lines from a single source over a short window, usually against root or a handful of guessable usernames. Count failures grouped by source IP and by username to identify the pattern immediately.

bash
sudo grep "Failed password" /var/log/auth.log | awk '{print $(NF-3)}' | sort | uniq -c | sort -rn | head
sudo grep "Failed password" /var/log/auth.log | grep -oP "from K[0-9.]+" | sort | uniq -c | sort -rn | head

The first pipeline tallies failed attempts per username, so you see whether an attacker is targeting root or a manufactured list of names. The second tallies per source IP, exposing the single address responsible for hundreds of tries. If you see an IP with far more failures than a human could generate, that is the brute-force burst signature — and the answer is a block on that source plus a fail2ban policy that handles repeats.

Read Successful Logins for the Tale-Tell

Brute force is the loud attack; the quiet one is an attacker who got in. Successful logins are rarer and far more important, so every accepted session deserves a look. The questions to answer: who logged in, from what IP, with what method, and at what time. A successful login that does not look like you — an odd timezone hour, an unfamiliar IP, a service account that never logs in — is the signal worth chasing.

bash
sudo grep "Accepted" /var/log/auth.log | tail -n 20
sudo last -a
sudo lastlog

last -a lists recent sessions with their host addresses, and lastlog shows the last login of every account. The patterns to distrust: an account that has never logged in before, a login at 3 a.m. from a geography your team does not use, or a service account appearing in the interactive session log at all. When one of those shows up, treat it as an active incident rather than a curiosity and check for what the account did next.

Spot the Compromise in the Aftermath

A login that should not have happened usually has an aftermath: a shell command that reads as a payload, an SSH banner change, a config modification. Cross-reference the session time against the auth log to reconstruct exactly what the intruder ran. The combination of an unexpected accepted login plus a suspicious command is the strongest signal you will get that a host is owned.

bash
sudo journalctl -u ssh --since "2026-08-01 02:00"
sudo ausearch -ts recent -m USER_CMD 2>/dev/null
sudo lsof -p $(pgrep -u suspicioususer | head -1) 2>/dev/null

The goal is a timeline: what process, started by whom, connecting where. If you lack the audit layer, the shell history and process list become the reconstruction. The priority once you confirm a compromise is containment — cut the account, kill the suspicious process, rotate any secret that account could have reached — before you investigate how far it went.

Turn Detection Into a Habit

Reactive log-reading after an incident is necessary but not sufficient. Make detection continuous: tail the auth log for new failures, schedule a daily summary of accepted logins, and blacklist repeat offenders automatically. The tools are already on the box — grep, awk, tail — and a five-line script on a timer catches days of attempts in one glance.

bash
sudo watch -n 30 "grep 'Failed password' /var/log/auth.log | tail -n 5"
sudo grep -E "Accepted (password|publickey)" /var/log/auth.log | tail -n 10

watch refreshes the recent failures every thirty seconds so a live burst is visible as it happens. The accepted-login tail is the daily habit: read it each morning, and yesterday's suspicious session is caught within a day rather than a month. Combined with fail2ban handling the automatic block, you get detection and response in a loop that does not depend on any particular human being awake.

Takeaway

The auth log is a complete record of who tried and who succeeded, and reading it well — bursts for brute force, accepted sessions for compromise, aftermath for severity — turns a public SSH port into a defensible, observable boundary. Make the accepted-login review a routine and the failure burst a trigger you act on automatically. Netbay's Ubuntu and Rocky VPS plans send their auth logs to /var/log/auth.log or /var/log/secure from first boot, so your detection loop can start immediately — netbayhosts.in.

Keep reading

Follow along on a real VPS

Deploy Linux in under 60 seconds

These guides are written against Ubuntu, Debian, and RHEL-family images — the same ones on NetBay.

Deploy an instance