Linux SSH Session Recording in 2026: Teleport vs tlog vs Sudo I/O Logs Compared

Which Linux SSH session recorder fits your threat model? Compare Teleport, tlog, and sudo I/O logs with working configs and compliance mapping.

SSH Session Recording: Teleport vs tlog 2026

Updated: September 14, 2026

Linux SSH session recording is the practice of capturing every keystroke, command, and terminal output from interactive shells on your servers so that a human auditor (or an automated pipeline) can replay exactly what a privileged user did, when, and from where. In 2026 there are three serious ways to do it on Linux: tlog (a PAM-hooked recorder shipped by Red Hat), Teleport (a bastion-host proxy that records at the session layer), and sudo I/O logging (the option that has quietly shipped in every distro for a decade). Which one fits depends on your blast radius, not your feature checklist.

  • tlog integrates with SSSD and PAM to record any interactive shell on RHEL/Fedora/CentOS Stream with SELinux enforcement, and stores JSON to journald or a file.
  • Teleport 17 records at a proxy layer, gives you a searchable web UI, structured audit events, and per-session BPF command tracking, but adds a bastion you must operate.
  • Sudo I/O logging (log_input/log_output) works out of the box on every distro and is the fastest way to record privileged commands, but it only covers what runs under sudo.
  • Auditd's execve rules give you kernel-level command capture but no terminal replay. Pair it with a recorder, don't replace one.
  • Every recorder shares the same blast radius: a root user on the recorded host can tamper with local logs before they leave. Ship recordings off-box in near-real-time or accept the gap.
  • PCI DSS 10.2, HIPAA 164.312(b), and SOC 2 CC7.2 all accept session recording as an auditable control when the recordings are integrity-protected and retained.

What Linux SSH session recording actually captures

So, let's start with a boring but important thing: session recording on Linux isn't a single technology. It's a family of overlapping mechanisms that intercept the terminal or the syscall layer to persist a replayable transcript of an interactive session. In my experience deploying this at scale, most confusion starts because people conflate three very different things: command logging, I/O recording, and session replay. A raw history file is command logging and forensically useless. A stream of execve audit events is command logging with parents and arguments but no terminal output. Session replay captures the byte stream that the pty saw. Timing, output, escape sequences, everything.

The three main recorders I compare here sit at different layers. tlog wraps the user's shell as their PAM-declared login shell, so it records anything that runs under that shell. Teleport is a proxy: it terminates the SSH connection itself and re-establishes it to the target, recording the bytes in the middle. Sudo I/O logging hooks the pty that sudo allocates, so it records only what runs through sudo. None of them see what the kernel sees for background daemons or non-interactive users. For that you need auditd.

Threat model: why record interactive sessions at all?

Before you pick a tool, write down the threat model. I've watched teams deploy session recording because "SOC 2 asked for it" and end up with a system that satisfies neither the auditor nor a real incident. Honestly, the valuable properties are only two: attribution (knowing which human ran which command under which shared account) and forensic replay (being able to reconstruct blast radius after a compromise). Everything else is a nice-to-have.

The threats that session recording actually mitigates are: insider abuse by a named administrator, credential compromise where an attacker uses a legitimate SSO identity, and shared-account confusion where multiple humans use one account. It does not mitigate an attacker who wins root and rewrites logs before they leave the host, and it does not mitigate an attacker who bypasses your recorded path (for example, authenticating via a non-recorded IPMI/BMC console or exploiting a service account). If your SSH hardening posture still allows password authentication or shared keys, recording is theatre.

Write the threat model as: who are the actors, what identities can they assume, which recording covers which entry paths, and what is the maximum lag before a record leaves the host. If the lag exceeds the time it takes an attacker to sudo -i && rm, the control is broken.

Teleport vs tlog vs sudo I/O logs at a glance

This table summarises the properties that matter when you compare the three approaches. I intentionally left out marketing bullets. The rows are the questions I get asked when I present the architecture to a security review board.

Dimensiontlog (Red Hat)Teleport 17sudo I/O logs
LicenseGPLv2+ (upstream)AGPLv3 (Community); Enterprise commercialBSD-ish (built-in)
What it recordsFull pty I/O for the user's login shellFull pty I/O + structured events + BPF execOnly what runs under sudo
Recording layerPAM-wrapped shell on the target hostSSH proxy (bastion) or reverse-tunnel agentKernel-facing pty via sudo
Off-host shippingjournald, syslog forwarding (rsyslog, syslog-ng, Vector)Native to S3, GCS, Azure Blob; DynamoDB eventsRequires manual forwarding of iolog_dir
Integrity modelFile permissions + SELinux confinementSigned session chunks + optional S3 Object LockFile permissions only
Replay toolingtlog-play CLIWeb UI with search, sharing, timestampssudoreplay CLI
Bastion requiredNoYes (or agent per host)No
Typical footprint<5 MB per hostbastion + agents; RAM: 100–300 MBnegligible

tlog: SSSD, PAM, and SELinux-aware recording

tlog is the option I reach for on RHEL-family fleets where I already run SSSD and want session recording without introducing a new control-plane service. It works by declaring /usr/bin/tlog-rec-session as the login shell for recorded users (via SSSD's session_recording stanza or a static passwd entry), which spawns the user's real shell inside a pty that tlog owns. The transcript is streamed as JSON messages to journald by default, and SELinux keeps the tlog process confined so a compromised user shell cannot rewrite its own recordings on disk.

Here's a minimal RHEL 9/10 setup that records every member of the ops group and forwards the transcript to a remote SIEM via rsyslog. I run authselect first because on modern RHEL that's the sanctioned way to activate the with-tlog feature.

sudo dnf install -y tlog rsyslog

sudo authselect select sssd with-tlog --force

sudo tee /etc/sssd/conf.d/session-recording.conf >/dev/null <<'EOF'
[session_recording]
scope = some
groups = ops
EOF
sudo chmod 600 /etc/sssd/conf.d/session-recording.conf
sudo systemctl restart sssd

sudo tee /etc/tlog/tlog-rec-session.conf >/dev/null <<'EOF'
{
  "shell": "/bin/bash",
  "notice": "\n Your session is being recorded per policy.\n",
  "latency": 5,
  "payload": 2048,
  "log": { "input": true, "output": true, "window": true },
  "writer": "journal",
  "journal": { "priority": "info", "augment": true }
}
EOF

sudo tee /etc/rsyslog.d/60-tlog.conf >/dev/null <<'EOF'
module(load="imjournal" StateFile="imjournal.state")
if $programname == "tlog-rec-session" then {
    action(type="omfwd" target="siem.internal" port="6514"
           protocol="tcp" streamdriver="gtls"
           streamdriver.mode="1"
           streamdriver.authmode="x509/name"
           streamdriverpermittedpeers="siem.internal")
    stop
}
EOF
sudo systemctl restart rsyslog

Replay works with tlog-play pointing at the journal cursor or a file. In practice I always ship recordings to a central store because a local root can still shred the journal. SELinux slows a shell attacker down, but the moment they escape confinement (which is the whole point of recording them) journald is theirs. The upstream tlog repository documents the JSON schema if you want to parse it in downstream tooling.

Teleport: bastion-mediated recording with replay UI

Teleport takes the opposite architectural position. Instead of asking every host to record its own shells, it terminates SSH at a proxy, authenticates the user against an OIDC or SAML provider, mints a short-lived certificate, and records the byte stream as it flows through the proxy. This gives you three properties that host-side recorders cannot: the recording is generated on a machine the target host cannot see or write to, the audit event stream is structured (JSON with session, host, user, source IP), and replay is a web UI a compliance officer can actually use.

Teleport 17 (the current release line as of mid-2026) added enhanced session recording powered by eBPF. Instead of only capturing the pty stream (which an attacker can obfuscate with echo $'\eE' tricks), it also traces execve, open, and network syscalls in the recorded session's cgroup, so the audit log names every binary invoked, not just what the terminal displayed. That's a meaningful upgrade in evidentiary value.

# /etc/teleport.yaml on a Teleport auth+proxy node
version: v3
teleport:
  nodename: bastion-01
  data_dir: /var/lib/teleport
  log:
    output: stderr
    severity: INFO
auth_service:
  enabled: yes
  cluster_name: prod.example.com
  session_recording: proxy-sync   # off-host, near-real-time to S3
  proxy_checks_host_keys: yes
  authentication:
    type: local
    second_factor: webauthn
    webauthn:
      rp_id: teleport.example.com
proxy_service:
  enabled: yes
  public_addr: teleport.example.com:443
  https_keypairs:
    - key_file: /etc/teleport/tls.key
      cert_file: /etc/teleport/tls.crt
ssh_service:
  enabled: no
# On each recorded Linux host, run:
# teleport start --roles=node --token=... --auth-server=teleport.example.com:443

The session_recording: proxy-sync mode uploads each session chunk to object storage while it's being recorded, which shrinks the tamper window to the network round-trip. Combined with S3 Object Lock in Compliance mode, a recording becomes as immutable as your KMS root key. See the Teleport configuration reference for backend-specific storage tuning.

Sudo I/O logs: the built-in nobody remembers

Sudo has recorded terminal I/O since 2011 and almost nobody enables it. If your compliance requirement is "record all privileged commands" and your users always cross the privilege boundary through sudo, this is a one-line change that costs you nothing. It does not, however, record what a user does with their unprivileged shell. Cat'ing a database dump they can already read as their own UID will not appear anywhere.

To turn it on globally, drop a snippet into /etc/sudoers.d/ and let sudo's own binary handle rotation and storage. The default location is /var/log/sudo-io with one directory per session. Replay is a single command.

sudo tee /etc/sudoers.d/90-iolog >/dev/null <<'EOF'
Defaults log_input, log_output
Defaults iolog_dir="/var/log/sudo-io/%{user}/%Y%m%d"
Defaults iolog_file="%{command}-%{seq}"
Defaults iolog_mode=0640
Defaults iolog_group=secops
Defaults iolog_flush
# Optional: send to a remote sudo_logsrvd instead of writing local files
# Defaults log_servers = logsrv1.internal:30344, logsrv2.internal:30344
# Defaults log_server_cabundle = /etc/pki/tls/certs/sudo-ca.pem
EOF
sudo visudo -cf /etc/sudoers.d/90-iolog

# Replay the most recent session for user alice:
sudo sudoreplay -d /var/log/sudo-io -l user alice
sudo sudoreplay -d /var/log/sudo-io <session-id>

The 2024+ sudo_logsrvd daemon is the piece most people miss. It gives you a real-time TLS log target with client-cert auth, so your hosts stream I/O logs to a hardened collector before an attacker with local root can touch them. If you already run a centralized auditd pipeline, add sudo I/O logs to the same collector node. The schema is different but the operational model is identical.

Auditd execve rules as command capture

Auditd is not a session recorder. It cannot replay a terminal. What it can do (and what nothing else on this list does as reliably) is prove that every process on the host was seen by the kernel, including background jobs and non-interactive automation. Pair it with any recorder above, and you close the gap where a user escapes the recorded shell (nohup, at, disown, cron, systemd-run) but keeps running commands.

The minimum useful rule set for command capture is a single execve rule per architecture, augmented with tty capture on 6.x kernels which now expose tty and ses fields natively. Keep the ruleset tight. A naive -a always,exit -F arch=b64 -S execve on a busy build host generates several thousand events per second and swamps your SIEM.

# /etc/audit/rules.d/90-execve.rules
-a always,exit -F arch=b64 -S execve -F auid>=1000 -F auid!=unset -F key=user-exec
-a always,exit -F arch=b32 -S execve -F auid>=1000 -F auid!=unset -F key=user-exec
# Root exec too, but drop noisy service-unit spawns from systemd
-a always,exit -F arch=b64 -S execve -F uid=0 -F auid!=unset -F exe!=/usr/lib/systemd/systemd -F key=root-exec
sudo augenrules --load
sudo systemctl restart auditd

Because execve events are keyed by the login UID (auid), you get attribution back to a real human even when they sudo -i. The auid stays stable across privilege boundaries. That's why I always run auditd alongside a session recorder and never in place of one.

Storage, integrity, and off-host shipping

Session recording is only as trustworthy as the storage under it. The single most common architectural mistake I see is a recorder that writes to a local directory with retention set by logrotate and no off-host replication. That control fails the moment an attacker becomes root, and if you would not need session recording without a root-capable adversary in your threat model, you would not be doing it at all.

The properties you want, in order: (1) records leave the host in near-real-time, (2) the receiving store is append-only from the sender's perspective, (3) records are hash-chained or signed so a truncated stream is detectable, and (4) retention is enforced by the store, not by a config file on the sender. Teleport with S3 Object Lock and KMS meets all four. tlog plus rsyslog-TLS to a Vector collector that writes to Loki with immutable retention meets three of four (no chain). sudo I/O logs via sudo_logsrvd meets two of four unless you build the chaining yourself.

If you already run osquery for fleet visibility, treat session-recording integrity as a separate signal and alert when a host stops shipping recordings for longer than the P99 gap. Silence is the interesting event.

PCI DSS, HIPAA, and SOC 2 mapping

Compliance frameworks don't mandate a specific tool, but they do specify what has to be captured, and every auditor I've worked with treats session recording as a strong control when the retention and integrity story is clean. Here's how the three recorders map to the requirements I get asked about most:

  • PCI DSS 4.0 Req 10.2.1.5: "log all elevation of privileges" and 10.2.1.7, "log all creation and deletion of system-level objects." Sudo I/O logs satisfy 10.2.1.5 directly; tlog and Teleport satisfy both when combined with auditd execve.
  • HIPAA 164.312(b): audit controls that "record and examine activity in information systems that contain or use electronic protected health information." Any of the three, plus retention appropriate to your business associate agreement.
  • SOC 2 CC7.2: "the entity monitors system components." Auditors want to see who did what, from where, when. Session replay is unusually persuasive evidence.
  • NIST 800-53 AU-14: "session audit." This control was written for session recording. Teleport and tlog both cite AU-14 in their compliance docs.

Retention is where most teams get bitten. PCI wants one year with three months immediately available. HIPAA is six years. If you deploy Teleport without configuring S3 lifecycle policies you'll discover this the hard way during an audit. The NIST SP 800-53 revision 5 catalog is the authoritative reference for the AU control family.

What breaks first in each design

"What breaks first?" is my default question when I review a security control, and session recording is a rich source of failure modes. tlog breaks first at journald. If journald fills up or crashes, the shell keeps working but the record vanishes; monitor journalctl --disk-usage and set SystemMaxUse aggressively with off-box forwarding. Teleport breaks first at the proxy. If the bastion is down, users can't log in at all (which is a feature, not a bug, but you need to test the failover story on a normal Tuesday, not during an incident). Sudo I/O logs break first at storage exhaustion. I've seen a busy build host fill /var in under an hour recording find output.

The two failure modes that hit all three are the same ones that hit any security control: a bypass path you didn't enumerate, and a monitoring gap that lets the tool fail silently. Enumerate every way a shell can be reached (direct SSH, Teleport, IPMI, VM console, container exec, kubectl exec, remote systemd unit invocation) and confirm which recorder covers which path. Wire the recorder's own health into your existing intrusion-detection alerts alongside your runtime security telemetry. When a recorder stops recording, that's an incident, not a ticket.

Frequently Asked Questions

Is Teleport free for SSH session recording?

Yes. Teleport Community Edition is AGPLv3 and includes SSH session recording, replay, and audit event export. Enhanced eBPF session recording is also in Community. Teleport Enterprise adds features like device trust, hardware key attestation, and access requests, but those are governance features, not recording features.

Can you record SSH sessions on Linux without a bastion host?

Yes. tlog runs entirely on the target host with SSSD/PAM integration and requires no bastion. Sudo I/O logging also runs locally on the target. A bastion (like Teleport) gives you off-host recording by default, but it isn't the only path. Host-local recording is a valid pattern when combined with real-time off-host shipping via rsyslog-TLS or sudo_logsrvd.

What is tlog used for on Linux?

tlog is a terminal I/O logger that wraps a user's login shell inside a pty it controls, then streams a JSON transcript of every input and output byte to journald, a file, or a syslog destination. It's the sanctioned session recording tool on RHEL, Fedora, and CentOS Stream, and integrates natively with SSSD for group-based scoping and with SELinux for confinement.

How is sudo I/O logging different from auditd?

Sudo I/O logging captures the terminal byte stream (input, output, window sizes) for commands invoked through sudo, and is replayable via sudoreplay. Auditd captures kernel syscall events like execve, including arguments and metadata, but not terminal output and not with replay. Use auditd for command attribution and sudo I/O logging for replay of privileged sessions. They're complementary, not overlapping.

How long should you keep Linux SSH session recordings?

Retention is driven by your compliance regime. PCI DSS 4.0 requires one year with three months immediately available. HIPAA requires six years. SOC 2 doesn't specify a number but auditors typically expect at least one year. If no framework applies, ninety days is a reasonable default for incident forensics; longer than that and you should be enforcing retention at the storage layer (S3 Object Lock, WORM appliances) rather than in the recorder's config.

Aisha Okonkwo
About the Author Aisha Okonkwo

Infrastructure security architect at a hyperscaler. Spends her days on Zero Trust, secrets management, and yelling at unencrypted backups.