On a server with several admins, you’ll eventually need to answer “who restarted MySQL at 3am?” or “who changed that config?”. sudo already logs every command it runs. You just need to know where to look. With a few settings, it can also record full terminal sessions you can replay later.
Where sudo logs by default
Every sudo invocation is logged through syslog / the journal, with the user, terminal, working directory, target user and full command:
Oct 14 09:12:44 web1 sudo: alice : TTY=pts/1 ; PWD=/home/alice ; USER=root ; COMMAND=/usr/bin/systemctl restart mysql
Find these entries:
sudo journalctl _COMM=sudo --since today
sudo journalctl _COMM=sudo | grep COMMAND
sudo grep 'sudo:' /var/log/auth.log # Debian/Ubuntu with rsyslog
sudo grep 'sudo:' /var/log/secure # RHEL family
Failed attempts appear as user NOT in sudoers or incorrect password attempts. Those are worth alerting on.
A dedicated sudo log file
Add a sudoers drop-in, always with visudo, which checks the syntax:
sudo visudo -f /etc/sudoers.d/logging
Defaults logfile="/var/log/sudo.log"
Defaults log_year, log_host
Each entry is then also written to /var/log/sudo.log, which is easy to grep and ship. Add the file to logrotate:
# /etc/logrotate.d/sudo
/var/log/sudo.log {
monthly
rotate 12
compress
missingok
notifempty
}
See logrotate.
The limit: sudo -i and sudo su
Logs show COMMAND=/bin/bash or COMMAND=/usr/bin/su -, and then nothing about what happened inside that root shell. Two ways to close the gap:
- Policy: discourage root shells. Allow specific commands instead. See least privilege.
- Session recording: record everything typed and shown in sudo sessions (next section), or log commands at the kernel level with auditd. See auditd.
Record full sessions: log_input / log_output
sudo can record the complete terminal input and output of sessions:
# /etc/sudoers.d/logging
Defaults log_output
Defaults log_input
Defaults iolog_dir="/var/log/sudo-io/%{user}"
List and replay sessions:
sudo sudoreplay -l
sudo sudoreplay -l user alice
sudo sudoreplay 00/00/0A # replay a session by its ID, like a video
Notes:
- Privacy and secrets:
log_inputrecords keystrokes, including passwords typed inside the session (database prompts, for example). Protect/var/log/sudo-io(root only) and tell your team it’s enabled. - Disk usage: long sessions with lots of output take space. Monitor it and prune old logs.
- Apply it selectively, for root shells only:
Defaults!/bin/bash, /usr/bin/su log_output
Make logs tamper-resistant
A user who becomes root can edit local logs. Forward them to a log server or service in real time. Logs that have already left the machine can’t be altered. See rsyslog remote logging.
sudo also supports sending I/O logs straight to a central sudo_logsrvd server (sudo 1.9+), so session recordings are stored off the host.
Alert on suspicious sudo activity
Simple, useful alerts:
- failed sudo attempts (“NOT in sudoers”, “incorrect password”);
- sudo from unexpected users;
- root shells (
COMMAND=/bin/bash) outside maintenance windows.
A small script on a timer, Fail2Ban, or rules in your central logging can watch for these patterns. See SSH login alerts, whose PAM hook also works for /etc/pam.d/sudo.
Quick checks
sudo journalctl _COMM=sudo --since "24 hours ago" | grep -c COMMAND # how many sudo commands today
sudo journalctl _COMM=sudo | grep -E 'NOT in sudoers|incorrect password'
sudo journalctl _COMM=sudo | grep -E 'COMMAND=/(usr/)?bin/(bash|sh|su)' # root shells
Quick reference
| Task | Command / setting |
|---|---|
| View sudo log | journalctl _COMM=sudo |
| Classic files | /var/log/auth.log / /var/log/secure |
| Own log file | Defaults logfile="/var/log/sudo.log" |
| Record sessions | Defaults log_input, log_output |
| List / replay | sudoreplay -l / sudoreplay ID |
| Edit safely | visudo -f /etc/sudoers.d/file |
Related: sudo and sudoers and history.