Description
When the read-only TMOUT variable is set, bash and dash close an interactive shell that
waited that many seconds for input. Setting it in /etc/profile.d/ applies it to the login
shells of every user, and readonly stops users from removing it.
Rationale
Open terminals left on a console, in a jump host session or in a forgotten SSH connection are an easy way to reuse someone's access, sometimes with root privileges.
Impact
Idle interactive shells exit after {{ tmout }} seconds. Long-running commands are not
affected, but a shell waiting at the prompt is closed: use tmux or screen for sessions
that must stay open.
Setting
| Location | /etc/profile.d/60-cirsec-tmout.sh |
| Default | Not set |
| Recommended | TMOUT={{ tmout }}, readonly |
Parameters
| Parameter | Core | Server | Server hardened | Desktop | Desktop hardened | Bounds |
|---|---|---|---|---|---|---|
tmoutinteger, seconds. Idle time before an interactive shell exits. | 900 | 900 | 600 | 900 | 600 | 60 to 3600 |
The value used is your override (tailoring file), else the profile's, else the one of the profile it extends, else the default. Bounds limit what an override may set.
Audit
Run su -s /bin/sh -l nobody -c 'echo $TMOUT'. It must print a value between 1 and {{ tmout }}.
Automated: every check must pass. Scanners report each check by its id.
login-shell
TMOUT in a login shell.
script: |
t=$(su -s /bin/sh -l nobody -c 'printf %s "${TMOUT:-}"' 2>/dev/null) || exit 3
echo "TMOUT=${t:-unset}"
[ -n "$t" ] && [ "$t" -ge 1 ] && [ "$t" -le "$CB_TMOUT" ]
Remediation
Create /etc/profile.d/60-cirsec-tmout.sh:
TMOUT={{ tmout }}
readonly TMOUT
export TMOUT
| Restart | users must log in again |
| Disruption | low |
Rollback
Delete /etc/profile.d/60-cirsec-tmout.sh.
profile
f=/etc/profile.d/60-cirsec-tmout.sh
cb_backup "$f"
printf '%s\n' '# Written by CIRSEC Baselines CB-DEB-AUTH-020' "TMOUT=$CB_TMOUT" 'readonly TMOUT' 'export TMOUT' >"$f"
chmod 644 "$f"
Handwritten code reads parameters from CB_<NAME> environment variables. Each release turns these fixes into remediate.sh and an Ansible role per profile: dry run by default, a fix runs only when its check fails.
References
- bash(1), Debian manual pages (TMOUT) Debian, vendor-doc, accessed 2026-10-18
- ANSSI-BP-028 v2.0 - Recommandations de configuration d'un système GNU/Linux (R32) ANSSI, guide, accessed 2026-10-18
Mappings
| Framework | ID | Relation |
|---|---|---|
| ANSSI-BP-028 - Recommandations de configuration d'un système GNU/Linux2.0 | R32 | equivalent |
| NIST SP 800-53 Rev. 55.1.1 | AC-12 | equivalent |
How this control relates to the other framework's: equivalent, stricter, looser, partial or related.
Threats mitigated
| Taxonomy | ID |
|---|---|
| MITRE ATT&CK | T1078 |
People and lifecycle
| Authors |
|
| Verified | 2026-10-18 by Sn0wAlice on 12, Proxmox VM, Debian 12 genericcloud image, kernel 6.1.0-54-cloud-amd64. Generated check, fix and check again for profiles core and server-hardened; state kept after reboot. |
| Verified | 2026-10-18 by Sn0wAlice on 13, Proxmox VM, Debian 13 genericcloud image, kernel 6.12.113+deb13-cloud-amd64. Generated check, fix and check again for profiles core and server-hardened; state kept after reboot. |
| Introduced in | v0.1.0 |
| Created, updated | 2026-10-18, 2026-10-18 |
| Translations | fr |