Find and Replay Sudo Session Logs with sudoreplay

Someone ran the wrong command as root: sudoreplay can show you exactly what happened, keystroke by keystroke, if I/O logging was already on. This guide builds a repeatable way to find a recorded sudo session, identify its session ID, and replay the output at a useful speed. The examples match sudoreplay 1.9.15p5 from sudo package 1.9.15p5-3ubuntu5.24.04.3.

Allow about fifteen minutes. You need a shell, the sudo package, and a host where sudo I/O logging is already enabled. You may need elevated privileges to read the log directory. This guide does not enable logging, edit sudoers, delete logs or change a service.

1. Check the installed command

Start with read-only checks. They do not need elevated privileges:

$ sudoreplay -V
sudoreplay version 1.9.15p5
$ sudoreplay -h
sudoreplay - replay sudo session logs

The help output is longer than the excerpt above. Confirm it includes list mode, -l, non-interactive mode, -n, maximum wait, -m, speed, -s, and directory, -d. The exact option spelling matters when you are working from an incident note written for another sudo version.

Checkpoint: if command -v sudoreplay finds nothing, stop here. Install the sudo package through your normal operating system process rather than copying a binary from another host.

2. Confirm where the logs should be

Unless you override it with -d, sudoreplay looks under /var/log/sudo-io. A missing directory means there is nothing for this command to list at that path; it does not mean the command is broken:

$ ls -ld /var/log/sudo-io
drwx------ 3 root root 4096 ... /var/log/sudo-io

Your permissions and directory details will differ. Reading the directory may require an administrator account or a narrowly granted privilege. If your account cannot read it, use the approved operational route, for example:

$ sudo -n sudoreplay -l
sudoreplay: unable to open /var/log/sudo-io: Permission denied

The displayed error is an example of a failure, not a result to copy literally: a successful command prints available sessions. Do not make the directory world-readable to solve a permissions problem. Session logs can contain commands, arguments and terminal output that should remain restricted.

3. List sessions with a narrow search

List mode finds session IDs without replaying anything. Start with the user who ran the command:

$ sudoreplay -l user alice

Each matching line is formatted similarly to a sudo log entry and includes the session ID, command and other metadata. The ID is normally a six-character combination of digits and upper-case letters, but a site can also refer to a session by its path. Record the exact ID from your own output.

You can add a command predicate. The following asks for sessions by alice whose command matches the POSIX extended regular expression vi:

$ sudoreplay -l user alice command 'vi'

For a path-shaped match, quote the expression so the shell does not interpret its punctuation:

$ sudoreplay -l user alice command '/bin/[a-z]*sh'

Predicates placed next to one another imply and. You can use explicit and, or, and !. Parentheses normally need shell quoting or escaping:

$ sudoreplay -l '( user alice or user bob )' tty console

Other useful predicates include host, cwd, runas, group, fromdate and todate. A terminal name is written without /dev/, such as tty1. Date expressions can be absolute or relative, but check the result rather than assuming a phrase such as next week means what you intend: the local manual warns that some relative units produce a surprising offset.

4. Replay the selected session

Replace SESSION_ID with the value you recorded. With a terminal attached, sudoreplay normally operates interactively, attempts to match the recorded terminal size, and reproduces pauses:

$ sudoreplay SESSION_ID

Long pauses can make a correct replay look stuck. Cap each pause at two seconds:

$ sudoreplay -m 2 SESSION_ID

Use -s 2 to make the replay twice as fast, or -s .5 to make it twice as slow. These options alter timing only; they do not alter the stored log.

5. Capture output without terminal interaction

For a review record or a pipeline, use non-interactive mode. It writes the session to standard output, does not prompt for keyboard input, and does not try to resize the terminal:

$ sudoreplay -n -m 2 SESSION_ID > session-output.txt
$ test -s session-output.txt && echo "replay output captured"
replay output captured

The redirection creates or replaces session-output.txt. If that file already matters, choose a new name first.

Warning: do not treat the captured file as harmless. It may contain passwords accidentally typed at a prompt, tokens printed by a command, or other sensitive output. Store it with the same care as the original session log and remove it according to your retention policy.

To display only selected streams, use a comma-separated filter. For example, this requests standard output and standard error:

$ sudoreplay -n -f stdout,stderr SESSION_ID

The available names are stdin, stdout, stderr, ttyin and ttyout. By default, sudoreplay displays standard output, standard error and terminal output. An empty standard-input, standard-output or standard-error log can be normal when the sudo command was not used in a pipeline.

6. Replay a session that is still running

If an administrator is investigating a live command, follow mode keeps replaying until the I/O log is complete:

$ sudoreplay -F SESSION_ID

This is similar to following a growing file. It does not stop the original command, send it input or change its terminal. The timing file marks completion by having its write bits cleared. Sudo versions before 1.9.1 did not clear those bits, so follow mode has version-sensitive behaviour on older installations. Confirm the installed version before relying on this for an old host.

7. Diagnose a failed replay

Check the failure in this order:

  1. Run sudoreplay -l against the expected directory. If the directory is missing, logging may not be configured or a different directory may be in use.
  2. Ask the sudo administrator which I/O log directory is configured, then pass that exact path with -d /path/to/sudo-io. Do not guess a directory from a partial backup.
  3. Confirm the session ID exactly. A path can be relative to the selected log directory or an absolute path beginning with /.
  4. Check read permission without changing ownership or mode. Use an approved privileged read if the logs are intentionally restricted.
  5. Retry with -n if terminal sizing or interactive input is the problem, and with -m 0 if long recorded pauses are obscuring output.

Warning: do not edit a timing file, clear write bits by hand, or remove a session directory to make a replay succeed. Those actions can destroy audit evidence. Preserve the original files and escalate a damaged or incomplete log.

Done means