Linux authentication logs: parsing SSH events and detecting attacks

Find auth.log, secure, or journal events; parse SSH and sudo context; validate authentication alerts; and apply access controls without losing administrative access.

Best practices
Illustration of logs flowing through a collection pipeline

Linux authentication logs help explain who attempted to access a host, from which address, by which method, and with what result. SSH, sudo, user switching, and PAM can contribute events, but the exact coverage depends on the services and logging configuration. No single file is guaranteed to contain every authentication action.

On many Debian and Ubuntu installations, authentication messages appear in /var/log/auth.log; on many RHEL-family installations, they appear in /var/log/secure. Systems may instead retain them in the systemd journal, or forward them elsewhere. Find the actual source before configuring collection, then verify events from known login and privilege-escalation attempts.

Recognize the important events

For file-based logging, follow the relevant file:

# Debian/Ubuntu, when this file is configured.
sudo tail -f /var/log/auth.log

# RHEL-family systems, when this file is configured.
sudo tail -f /var/log/secure

For systemd installations, the SSH unit is commonly ssh.service on Debian/Ubuntu and sshd.service on RHEL-family systems. Use the installed unit name:

sudo journalctl -u ssh.service -f
# Or, on a host whose unit is named sshd.service:
sudo journalctl -u sshd.service -f

Those journal commands select SSH service events, not every PAM or sudo event on the host. Collection needs to cover the other sources separately when they are in scope.

A typical OpenSSH failure message looks like this; the address is reserved for documentation:

Feb 10 15:45:14 ubuntu-lts sshd[47343]: Failed password for root from 192.0.2.143 port 33990 ssh2

The authentication method is password. The trailing ssh2 identifies the SSH protocol, not the authentication method. The line also provides a username, source address and port, process ID, and local timestamp. This traditional timestamp lacks a year and time zone; supply the correct host context when parsing it.

Message pattern Meaning Investigation question
Failed password for root from ... A password attempt for root failed Is this isolated user error or part of repeated probing?
Invalid user ... from ... An attempt used an account name unknown to that host Which names and hosts are being targeted?
Accepted publickey/password for ... SSH authentication succeeded Is the account, source, and method expected?
sudo: ... COMMAND=... A command was authorized through sudo, depending on policy/logging Who invoked it, as which target user, and why?
PAM authentication failure A PAM authentication step failed Which service, account, and related messages explain it?

One failed password is not proof of a brute-force attack. Likewise, one Accepted message proves authentication succeeded, not that the resulting activity was legitimate.

Parse event fields before building detections

Text search is useful for an initial investigation. Structured fields make repeated queries, grouping, and detections more reliable. Define fields such as event_name, username, src_ip, auth_method, and host, and preserve the original message for inspection.

For Guance, configure the actual file path using the DataKit log collector, then test a Pipeline rule against real samples. This is a Guance Pipeline expression, not Python:

grok(_, "Failed password for (invalid user )?%{NOTSPACE:username} from %{IP:src_ip} port %{NUMBER:port}")

The pattern targets one OpenSSH message shape and extracts its fields. It is not a parser for accepted logins, every PAM module, or every SSH version. Test both existing and invalid usernames, IPv4 and IPv6, and the full message as delivered by your collector. Convert port to a numeric type if a downstream query requires it.

After a successful pattern match, assign a specific event name such as failed_login and the method password. Parse successful authentication and sudo events through separate rules. You may map failed authentication to log severity error and successful authentication to info under your policy, but keep event outcome and severity distinct. A generic search for the word failure is too broad to classify every message correctly.

Map the event timestamp to Guance's time with the correct zone and year. Normalize severity into status, retaining separate security-event fields. Check the collector's defaults rather than assuming that a missing severity field always renders in one particular way.

Build views that support an investigation

In the Guance log explorer, inspect the time distribution of failed and successful authentication. Group failures by source address and username, and include host identity so that one heavily targeted server does not hide the rest of the fleet.

Clustering can help group repetitive message patterns and expose new ones. It complements exact field-based queries: a cluster is not itself a confirmed attack. Useful dashboard views include the top source addresses by failure count, usernames receiving repeated failures, and successful logins with their host, method, and source. Use the explorer's available chart/dashboard workflow to save those views after verifying the underlying fields.

Turn verified queries into alerts

Use Guance's log detection monitor to evaluate queries over the collected events. Configure the following as detection logic in the monitor's query interface; they are not literal copy-and-paste query syntax:

  1. Successful root authentication: match event_name = successful_login and username = root; trigger when at least one matching event appears in the evaluation window.
  2. Repeated authentication failures: match event_name = failed_login and your configured authentication source; group by src_ip and alert on more than 20 failures in five minutes as an initial example threshold. Add host grouping when the response is host-specific.
  3. Successful access from an unexpected source: match successful authentication whose source address is outside the approved access policy. Account for VPNs, bastions, NAT, IPv6, and changing legitimate addresses.

Tune thresholds to the host's exposure and normal use. An address alone is not a person: many users may share one address, and an attacker may spread attempts across many addresses. Supplement a per-IP rule with per-account and fleet-wide views.

Route alerts through configured alert policies and notification targets. Guance supports integrations such as DingTalk, WeCom, and Lark where configured; verify the target used by your team. Inspect the resulting event and notification using a controlled test. Confirm evaluation frequency, ingestion delay, repeat-notification behavior, and the host/source details responders receive.

Other useful detections include password authentication where policy requires keys, unexpected users invoking sudo as root, and one source trying many usernames. Failed attempts across many accounts are evidence of enumeration or password spraying; logs alone do not prove that the attacker used stolen credentials.

Use findings to improve access controls

Before changing SSH access, confirm a working alternative login path and keep an existing administrative session open. Validate the configuration, inspect effective settings including Include and Match rules, apply the change through the host's service-management procedure, and test a fresh connection before closing the original session.

Prioritize these controls:

  • Disable direct root login with PermitRootLogin no when it fits your access model; use attributable user accounts and controlled privilege escalation.
  • Require the intended authentication methods. PasswordAuthentication no disables the SSH password method, but keyboard-interactive/PAM may still permit password-based challenges. Set KbdInteractiveAuthentication and AuthenticationMethods consistently with your policy; do not disable an MFA method you intend to keep.
  • Restrict reachability with firewalls, security groups, bastions, or private access. Fail2Ban can add temporary source blocking where its log parsing and ban rules are correctly configured.
  • Use MFA where appropriate and grant only the account and sudo privileges required.
  • Changing the default port may reduce routine scan noise, but it does not replace strong authentication or network restrictions.

Useful OpenSSH checks include:

sudo sshd -t
sudo sshd -T

Use the actual sshd binary path if it is outside your shell's search path. -t checks configuration validity; -T reports effective settings. For connection-specific Match rules, use the documented -C connection parameters as well. These checks do not prove that a new login will work.

A root-login event after a policy change deserves prompt investigation. First verify the event's timestamp, host, active daemon, and effective configuration. Delayed collection, a different host, or an unapplied configuration change can also explain it; the event alone does not establish tampering.

Frequently asked questions

Is it normal to see thousands of failed passwords on a public server?

Automated probing is common on exposed SSH services, but “common” is not a reason to ignore it. Check whether real accounts are targeted, whether failures lead to successful authentication, and whether the service should be publicly reachable at all. Baseline the rate and validate detections rather than relying on manual watching.

Should we monitor sudo commands too?

Yes. Sudo events help attribute administrative access. Review policy-sensitive actions such as account creation, sudo configuration changes, and modifications under /etc. A command string is not a complete audit of everything a root shell subsequently does; use additional auditing when that detail is required.

Do authentication logs contain plaintext passwords?

Normal OpenSSH authentication logging is not intended to record submitted passwords. That does not guarantee every PAM module, custom script, command argument, or debugging configuration is safe. OpenSSH warns that debug-level logging can expose user privacy. Use the required INFO or VERBOSE detail, protect access to the logs, and inspect actual samples rather than enabling DEBUG3 routinely.

Can one monitor cover multiple hosts?

Yes, if the query covers the intended sources and each host is collecting correctly. Preserve host identity and meaningful service/source values, group detections to match the response workflow, and test an event from every relevant host class. Separately monitor collection gaps so that a silent host is not mistaken for a secure one.

References and related reading

Configuration details come from the OpenSSH server configuration manual, sshd command reference, and journalctl reference. Validate Pipeline behavior with the Guance Pipeline quick start.

Continue with SSH logging. The guide to keeping sensitive data out of logs is currently in Chinese.

Get a tailored plan

Contact us

Join the community

Scan with WeChat
to join the community

Try Guance

Start online and pay only for what you use.

Get started

Choose a Guance plan

Code hosting