Automatic shell timeout configuration scripts for POSIX shells (bash/zsh) and C shells (csh/tcsh).
These scripts automatically set shell timeout values based on User ID (UID) or Group ID (GID) membership (including secondary groups). When a matching user logs in, their shell will automatically terminate after a configured period of inactivity.
NOTE: Not all shells implement this feature.
- UID and/or GID-based timeout configuration
- Additive and subtractive list management
- Validation of timeout values (positive integers only)
- Can set timeout to readonly (bash/zsh)
shell-timeout.sh- POSIX shell (bash/zsh) compatible versionshell-timeout.csh- C shell (csh/tcsh) compatible versionshell-timeout- Config file
-
Create the configuration directory:
sudo mkdir -p /etc/default/shell-timeout.d
-
Create the main configuration file:
sudo touch /etc/default/shell-timeout
- Copy the script to the profile directory:
sudo cp shell-timeout.sh /etc/profile.d/shell-timeout.sh sudo chmod 644 /etc/profile.d/shell-timeout.sh
- Copy the script to the appropriate location:
sudo cp shell-timeout.csh /etc/profile.d/shell-timeout.csh sudo chmod 644 /etc/profile.d/shell-timeout.csh
Configuration files use a shell-neutral KEY=VALUE format that works with both POSIX and C shells. This means you can use the same configuration files for all shell types.
Edit /etc/default/shell-timeout:
# Timeout in seconds (POSIX shells) or converted to minutes (csh)
TMOUT_SECONDS=900
# Space-separated list of UIDs to apply timeout
TMOUT_UIDS=1000 1001 1002
# Space-separated list of GIDs to apply timeout
TMOUT_GIDS=100 200
# Make timeout readonly (prevents users from changing it)
# Only works in POSIX shells - ignored in csh/tcsh
TMOUT_READONLY=yesImportant formatting rules:
- Use
KEY=VALUEformat (no spaces around=) - Values can be quoted or unquoted
- Multiple values separated by spaces
- Comments start with
# - Empty lines are ignored
Additional configurations can be placed in /etc/default/shell-timeout.d/*.conf:
Example /etc/default/shell-timeout.d/developers.conf:
# Add developer group to timeout list
TMOUT_GIDS=500
# Remove specific user from timeout
TMOUT_UIDS_NOCHECK=1000Note: Later configuration files extend earlier ones. Drop-in files are processed in alphabetical order.
If we used both examples listed here TMOUT_UIDS=1001 1002 and TMOUT_GIDS=100 200 500
| Variable | Description |
|---|---|
TMOUT_SECONDS |
Timeout duration in seconds (must be positive integer) |
TMOUT_READONLY |
Set to yes/true/1 to make timeout readonly - POSIX shells only |
TMOUT_UIDS |
Base list of UIDs to apply timeout, all values are merged together |
TMOUT_GIDS |
Base list of GIDs to apply timeout, all values are merged together |
TMOUT_UIDS_NOCHECK |
UIDs to remove from the final list of explicitly added IDs, all values are merged together |
TMOUT_GIDS_NOCHECK |
GIDs to remove from the final list of explicitly added IDs, all values are merged together |
- Scripts load configuration from
/etc/default/shell-timeout - Drop-in configs from
/etc/default/shell-timeout.d/*.confare sourced - UID/GID lists are merged (base + add - remove)
TMOUT_SECONDSis validated (must be positive integer)- Current user's UID and GID (including secondary groups) are checked against configured lists
- If match found, timeout is set:
- POSIX shells: Sets
TMOUTenvironment variable (in seconds) - C shells: Sets
autologoutvariable (converted to minutes, minimum 1)
- POSIX shells: Sets
The TMOUT_UIDS and TMOUT_GIDS look for exact matches from their list of IDs.
The _NOCHECK keys remove elements from those lists, but do not prevent other
attributes from matching. The listed items are not checked - not vetoed.
If you have groups of 0, 100, 1000, each of the following configs would match your account.
TMOUT_GIDS=0TMOUT_GIDS=0 100TMOUT_GIDS=0 100
TMOUT_GIDS_NOCHECK=1000TMOUT_GIDS=0 100 1000
TMOUT_GIDS_NOCHECK=1000The final three cases are functionally equivalent.
- Uses
TMOUTvariable (seconds) - Exact timeout granularity
- Supports readonly enforcement via
readonly TMOUT
- Uses
autologoutvariable (minutes) - Converts seconds to minutes (rounds down, minimum 1 minute)
- Cannot enforce readonly
autologout
/etc/default/shell-timeout:
TMOUT_SECONDS=1800
TMOUT_GIDS=500
TMOUT_READONLY=yes/etc/default/shell-timeout:
TMOUT_SECONDS=900
TMOUT_GIDS=100 200/etc/default/shell-timeout.d/exceptions.conf:
# Add audit group
TMOUT_GIDS=300
# Remove specific power users
TMOUT_UIDS_NOCHECK=1050 1051/etc/default/shell-timeout:
TMOUT_SECONDS=600
TMOUT_UIDS=1000 1001 1002 1003 1004/etc/default/shell-timeout.d/admin-exception.conf:
# Remove admins from timeout
TMOUT_UIDS_NOCHECK=1000 1001The scripts validate TMOUT_SECONDS to ensure:
- It is not empty
- It contains only digits (0-9)
- It is greater than zero
- It is not a float/decimal
Invalid values cause the script to exit without setting a timeout.
- Use
TMOUT_READONLY=yesin POSIX shells to prevent users from unsetting the timeout- "C shells" cannot enforce readonly - consider this when choosing the default shells for security-sensitive accounts
- Timeouts apply per-shell session, not per SSH connection or shell scripts
- Consider combining with SSH timeout settings for comprehensive idle timeout
- Users can still use screen/tmux to maintain sessions, but idle shells may still terminate
- Check that user's UID or GID is in the configured lists
- Verify configuration file syntax (no syntax errors)
- Test with:
idto see user's UID and GIDs - Source the script manually to see any errors
- Remember the
_NOCHECKelement state that the ID will not be explicitly selected - Verify configuration file syntax (no syntax errors)
- Test with:
idto see user's UID and GIDs - Verify no secondary group is in the configutation
- Source the script manually to see any errors
- Check for multiple configuration files overriding values
- Remember csh/tcsh converts to minutes (rounds down)
- Verify
TMOUT_SECONDSis valid positive integer
- Check file permissions (should be 644)
- Verify configuration file syntax
- Look for shell-specific issues in
/var/log/messages
When modifying these scripts:
- Maintain POSIX compliance for
.shversion - Test on bash and zsh
- Test csh version on both csh and tcsh
- Update this README with any new features or changes
- Update tests with new workflows