Who records: you, a tool, or the server
SSH itself keeps no copy of what happens in a session. sshd logs the login, as shown in how to check SSH login attempts, and nothing after it. To keep the session you need a recorder, and where it runs decides what it can do.
| Tool | Runs on | Records | Good for |
|---|---|---|---|
script | Your computer or the server | Output, optionally input, with timing | Quick personal record, already installed |
asciinema | Your computer or the server | Output with timing, one file | Demos, sharing a replay |
tlog | The server | Every session of chosen users | Recording sessions you do not control |
sudo I/O log | The server | Only commands run with sudo | Admin actions |
A recorder on your side captures what you see, on every server, without touching them. A recorder on the server captures everyone who logs in, and the user cannot simply skip it.
Record with script
script from util-linux is on almost every Linux system. Start it, then connect from the shell it opens:
script --log-io session.log --log-timing session.tm
ssh deploy@server
Work as usual. When you are done, log out of the server and type exit to stop the recording. To record one connection and stop when it ends:
script -q --log-io session.log --log-timing session.tm -c "ssh deploy@server"
Play it back in your terminal. Space pauses, the up and down arrows change the speed, and --divisor 4 plays at four times the speed:
scriptreplay --log-io session.log --log-timing session.tm
scriptreplay --log-io session.log --log-timing session.tm --divisor 4
--log-io saves what you type as well as the output. Use --log-out instead to keep the output only. scriptreplay --summary shows when the session started, the shell and the command.
On macOS, script is the BSD version with different flags. -r records with timing and -p plays back:
script -r session.rec ssh deploy@server
script -p session.rec
Record with asciinema
asciinema saves the session as a single .cast file, plain JSON lines with a time for each chunk of output. Install it from your package manager (apt install asciinema, dnf install asciinema, brew install asciinema), then:
asciinema rec -i 2 -c "ssh deploy@server" session.cast
asciinema play session.cast
asciinema play -s 4 session.cast
-i 2 shortens pauses longer than two seconds, which makes a replay pleasant to watch. Always give a file name: the file then stays on your disk and nothing is uploaded. Keystrokes are not saved unless you add --stdin.
Record every session on the server with tlog
When the sessions to record are other people's, the recorder has to run on the server. tlog is packaged on RHEL, Rocky, AlmaLinux and Fedora. The simplest setup makes it the login shell of the users to record:
sudo dnf install tlog
sudo usermod -s /usr/bin/tlog-rec-session deploy
tlog-rec-session starts the real shell (bash by default, set in /etc/tlog/tlog-rec-session.conf) and writes the session to the systemd journal. On a system with SSSD you can choose users and groups in one place instead:
[session_recording]
scope = some
users = deploy
groups = admins
Put those lines in /etc/sssd/conf.d/sssd-session-recording.conf, set the file to mode 600 and restart sssd. To play a session back, find its recording ID in the journal and pass it to tlog-play:
journalctl -o verbose | grep -m5 TLOG_REC=
tlog-play -r journal -M TLOG_REC=1a2b3c4d5e6f7a8b9c0d1e2f3a4b5c6d-2f1-4d2e1
By default tlog leaves keystrokes out (log.input is false), so passwords typed at a prompt are not kept. Turn input logging on only if you really need it.
Record only sudo commands
If what matters is what admins run as root, sudo can record the output of every command it runs. Add a file with sudo visudo -f /etc/sudoers.d/io-log:
Defaults log_output
Defaults!/usr/bin/sudoreplay !log_output
The second line stops sudo from recording its own replays. Then list and play the sessions:
sudo sudoreplay -l
sudo sudoreplay 000001
Recordings go to /var/log/sudo-io. It is a small setup that pairs well with using sudo over SSH safely, but it sees nothing done without sudo.
Keep secrets out of recordings
A recording holds whatever crossed the screen: an API token printed by env, a private key shown with cat, a database password passed on the command line. Some habits help:
- Record output only unless you need the keystrokes. Passwords typed at a hidden prompt then never reach the file.
- Do not print secrets you do not need to see. Read them from a file or a variable instead of pasting them into commands.
- Store recordings like credentials:
chmod 600, on an encrypted disk, deleted when no longer needed. - Recordings made on a server can be changed by root on that server. If they must hold up later, send them to another machine as they are written.
SSH session recording that stays encrypted on your device helps when the recordings live on a laptop that could be lost.
Which one to use
- A record of your own work, on any server:
script, or the recorder in your SSH client. - A replay to show someone:
asciinema. - Every session of certain users, whatever client they use:
tlogon the server. - Only privileged commands: sudo I/O logs.
If the goal is to keep work alive after a disconnect rather than to review it, you need tmux instead, see keep SSH sessions alive with tmux.
Questions
Can I record an SSH session that is already running?
Not with these tools. script, asciinema and tlog all start before the shell does. Inside tmux you can save what is still in the scrollback with tmux capture-pane -p -S -, but that is text without timing.
Does SSH record sessions by itself?
No. sshd logs who connected, when and with which key, but not what was typed or shown. For that you need a recorder on the client or on the server.
Are passwords saved in a recording?
Passwords typed at a prompt that hides them do not appear in the output, but script --log-io and tlog with input logging also save keystrokes, so those passwords are in the input log. Anything printed on screen, such as a token or a key, is always in the recording.
Is it legal to record other people's sessions?
It depends on where you work. Many places require telling users first, and a login banner is the usual way to do it.
Sources
- script(1), util-linux
- scriptreplay(1), util-linux
- asciinema documentation
- tlog, terminal I/O logger
- Recording sessions, Red Hat Enterprise Linux 9
- sudoers(5), I/O logging