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:

  1. Policy: discourage root shells. Allow specific commands instead. See least privilege.
  2. 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_input records 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.

  • Security
  • Linux
  • Logging