auth.log and secure Forensics: SSH, sudo and su
Read /var/log/auth.log and /var/log/secure in an investigation: SSH brute force and logins, sudo and su root shells, password and account changes, time formats.
TL;DR. auth.log (Debian, Ubuntu) and secure (RHEL family) are where rsyslog writes the auth and authpriv facilities: sshd, sudo, su, PAM, passwd, useradd, cron sessions. Group sshd lines by PID to rebuild each connection, count failures per source address, look for the first success after them, then follow the session into sudo. Identify the timestamp format before converting anything.
Which file, which format
| Distribution | Authentication | Everything else | Timestamp |
|---|---|---|---|
| Ubuntu 24.04, Debian 12+ | /var/log/auth.log | /var/log/syslog | RFC 3339, microseconds, offset |
| Older Debian and Ubuntu | /var/log/auth.log | /var/log/syslog | Traditional, local time, no year |
| RHEL, Rocky, Alma, Fedora | /var/log/secure | /var/log/messages | Traditional, local time, no year |
The two formats side by side:
Sep 14 10:02:11 fin-jump-01 sshd[3071]: Accepted password for svc_backup from 203.0.113.45 port 51544 ssh2
2026-09-14T10:02:11.482113+00:00 fin-jump-01 sshd[3071]: Accepted password for svc_backup from 203.0.113.45 port 51544 ssh2
For the first form (RFC 3164 style), read the zone from /etc/localtime and infer the year from the file's modification time and rotation order. A file that spans New Year contains December lines followed by January lines; the January ones belong to the next year. Around daylight-saving changes, local times can repeat or skip an hour.
Debian 12 and some Fedora installs have no rsyslog at all. An absent auth.log is not proof of deletion; check the systemd journal.
SSH: rebuild each connection by PID
Every connection gets its own sshd process (on OpenSSH 9.8 and later, the per-connection process is sshd-session, so search for both names). All lines of one connection share that PID:
sshd[2381]: pam_unix(sshd:auth): authentication failure; logname= uid=0 euid=0 tty=ssh ruser= rhost=198.51.100.23 user=svc_backup
sshd[2381]: Failed password for svc_backup from 198.51.100.23 port 40135 ssh2
sshd[2381]: Connection closed by authenticating user svc_backup 198.51.100.23 port 40135 [preauth]
Key messages:
| Message | Meaning |
|---|---|
Invalid user admin from IP | Account does not exist on the host |
Failed password for [invalid user] X from IP | Wrong password (or nonexistent user) |
Accepted password for X from IP | Password login succeeded |
Accepted publickey for X from IP ... ED25519 SHA256:... | Key login; the fingerprint identifies the key |
pam_unix(sshd:session): session opened for user X | Session start, same PID as the Accepted line |
pam_unix(sshd:session): session closed for user X | Session end, same PID |
Connection closed by ... [preauth] | Disconnected before authenticating |
The pam_unix lines come from the pam_unix module; systemd-logind: New session 7 of user X follows within milliseconds and gives the session a number that also appears in the journal as session-7.scope.
Password guessing, then a success
The pattern that matters is not "many failures" (every internet-facing SSH server has those) but failures followed by a success:
- Count
Failed passwordandInvalid userlines per source address and list the account names tried. - Look for an
Acceptedline for any of those accounts after the last failure, from the same address or from another one. A different address minutes later is common: the guessing ran from one machine, the login from another. - Check whether the successful method is
passwordfor an account that normally logs in withpublickey. A service account that always used a key and suddenly uses a password is a strong lead. - Compare the source address with the account's history. A login from an address never seen before for that account deserves a question to its owner.
zgrep -hE 'sshd(-session)?\[[0-9]+\]: (Failed password|Invalid user)' auth.log* | grep -oE 'from [0-9a-f.:]+' | sort | uniq -c | sort -rn
zgrep -hE 'sshd(-session)?\[[0-9]+\]: Accepted' auth.log*
Remember that on a host running both rsyslog and journald each line exists twice; counting the journal and auth.log together doubles the numbers. btmp holds a third copy of failed attempts.
sudo and su
sudo writes one line per command:
sudo: svc_backup : TTY=pts/1 ; PWD=/home/svc_backup ; USER=root ; COMMAND=list
sudo: svc_backup : TTY=pts/1 ; PWD=/home/svc_backup ; USER=root ; COMMAND=/bin/bash
sudo: pam_unix(sudo-i:session): session opened for user root(uid=0) by svc_backup(uid=1001)
COMMAND=listissudo -l: the user checking which rights they have. Often the first thing an intruder runs.COMMAND=/bin/bashwith thesudo-iPAM service issudo -i, an interactive root shell. From that point, auth.log no longer sees individual commands; only commands run through sudo again are logged. Follow the session through auditd, whereauidkeeps the original user.- Failures:
user NOT in sudoers,command not allowed,N incorrect password attempts, andpam_unix(sudo:auth): authentication failure. sulogspam_unix(su:session): session opened for user root by X(orsu-lforsu -) andFAILED SUstyle messages on failure, depending on the distribution.
Spaces in sudo arguments are logged as-is, which makes some command lines ambiguous (/srv/finance/Q3 close is one argument or two?). The audit USER_CMD record hex-encodes such values and settles it.
Accounts and passwords
useradd[PID]: new user: name=...,groupadd,usermodandgpasswdlines for account changes.passwd[PID]: pam_unix(passwd:chauthtok): password changed for Xwhen a password is changed. An intruder changing the password of the account they came in with locks out the owner and keeps access.chpasswdandchagefor bulk and expiry changes.
Cron
CRON[PID]: pam_unix(cron:session): session opened for user X appears in auth.log for each job run; the command itself is in syslog (CRON[PID]: (X) CMD (...)), and a crontab edit shows as crontab[PID]: (root) REPLACE (X). A new user crontab installed during an interactive session is a persistence lead.
Doing it faster
Linux Log Parser reads auth.log, secure, syslog and messages in all three formats, including rotated and .gz files, rebuilds sessions from the sshd PID pairs and logind, marks lines that also exist in the journal, and reports password guessing followed by a success, logins from a new address, root SSH logins, sudo and su root shells, failed sudo and account changes. The investigation walkthrough shows these findings on a sample.
Reference tables: auth.log and syslog, sudo logs and SSH artifacts on linuxforensics.app.