sudo auditing (Level 1)¶
This layer answers:
- Who used
sudo? - What top-level command did they invoke?
- Did
sudoauthenticate, or fail? - (With
log_input,log_outputenabled) what did they actually type once they got a root shell?
What sudo logs by default¶
Every sudo invocation writes a syslog event with at least:
- The invoking user (
USER=...) - The target user (
TARGET=..., usuallyroot) - The TTY
- The CWD at time of invocation
- The command line that was passed to
sudo - Whether authentication succeeded or failed
Where it lands depends on the distro:
| Distro | Sink | Query |
|---|---|---|
| Debian / Ubuntu (systemd) | journal + /var/log/auth.log |
sudo journalctl _COMM=sudo or sudo grep sudo /var/log/auth.log |
| RHEL / CentOS / Rocky / Alma | journal + /var/log/secure |
sudo journalctl _COMM=sudo or sudo grep sudo /var/log/secure |
| macOS | unified log | log show --predicate 'process == "sudo"' --last 1d |
The "sudo bash" problem¶
This is the load-bearing limitation:
sudo vim /etc/ssh/sshd_config # <- logged: full command line
sudo bash # <- logged: "bash"
sudo su - # <- logged: "su -"
sudo -i # <- logged: "-i"
Once the user has a root shell, everything they type inside that shell
is invisible to the sudo log. The shell's own history file might catch
it, but root's ~/.bash_history is editable by root, so it's not
trustworthy as evidence.
To close this gap you need either:
sudoreplay— see below. Captures keystroke + output of the root session.- auditd execve rules — see auditd framework. Captures
every
execve()syscall including those inside the root shell. - Disallow shell escalation — restrict the sudoers policy so users
can only run a curated whitelist (
Cmnd_Alias), nobash/su/ editor escape hatches. Aggressive but bulletproof.
sudoreplay (when it works)¶
sudoreplay records the terminal session (stdin + stdout + timing)
of every sudo invocation that matches a log_input / log_output
sudoers rule. To enable globally:
# /etc/sudoers.d/00-logging (use `sudo visudo -f`)
Defaults log_input, log_output
Defaults iolog_dir=/var/log/sudo-io
After enabling, sudo writes to /var/log/sudo-io/<user>/<seq>/. List
sessions:
Replay one:
Caveats:
- Captures everything, including passwords typed at TTY if the user
ran
passwd,mysql -p, etc. You're now storing those in/var/log/sudo-io/. Restrict access (default mode0700is good) and consider whether you really want this on a host that handles secrets at the keyboard. - Disk usage grows fast for interactive root sessions.
- Does not survive
sudo bash→su otheruser(the second hop bypasses sudo entirely). For full coverage you still need auditd.
Common queries¶
# All sudo events today (systemd)
sudo journalctl _COMM=sudo --since today
# Sudo events by user, last 7 days
sudo journalctl _COMM=sudo --since '7 days ago' | grep ' alice : '
# Failed sudo attempts (auth failure or NOT in sudoers)
sudo journalctl _COMM=sudo | grep -E 'FAILED|NOT in sudoers'
# Same on non-systemd Debian
sudo grep sudo /var/log/auth.log /var/log/auth.log.1
# Same on RHEL
sudo grep sudo /var/log/secure /var/log/secure-*
# List replayable sessions (only if log_input enabled)
sudo sudoreplay -l
How this repo helps¶
- Shell helper:
audit-sudo [user]— wraps the journal / auth.log / secure query and auto-detects the right sink. Defined indot_config/shell/45_audit.sh.tmpl. - Television channel:
tv sudo-history(Linux only) — fuzzy-browse sudo events. Source cycles include journalctl, plainauth.log/securegrep, andsudoreplay -lrows when available. Preview of a sudoreplay row shows the session metadata;Enterinvokessudoreplay <id>. - Both helpers elevate via
sudo -vwhen the underlying sink is root-only. The TTY prompt is a one-time per-shell prompt; subsequent helper invocations within the sudo cache window run silently.
See also¶
- Process accounting — alternative coarse exec
log that does see commands inside
sudo bash(but with no full argv) - auditd framework — the only general-purpose answer to "what did the root shell run?"