Files
Bash_Scrips/shell_history_audit.sh
2025-06-23 21:19:51 +02:00

110 lines
4.0 KiB
Bash
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#!/usr/bin/env bash
# SPDX-License-Identifier: GPL-3.0-or-later
# Copyright © 2025 Roy Cohen <roy@wondercohen.nl>
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the “Software”), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED
# Wonder Cohen - The Hague The Netherlands
# shell_history_audit.sh put in /etc/profile.d
# Logs every interactive-bash command (including within sudo) to /var/log/history
# Last-update: 2025-06-23
### Installation notes:
## Create the script
# /etc/profile.d/shell_history_audit.sh
## Create log directory and group
# sudo groupadd -f historylog
# sudo mkdir -p /var/log/history
# sudo chown root:historylog /var/log/history
# sudo chmod 1770 /var/log/history
## Create the error log
# sudo touch /var/log/history_audit_errors.log
# sudo chown root:historylog /var/log/history_audit_errors.log
# sudo chmod 666 /var/log/history_audit_errors.log
## Secure script
# sudo chmod 644 /etc/profile.d/shell_history_audit.sh
# sudo chown root:root /etc/profile.d/shell_history_audit.sh
## Make log files append-only (optional)
# sudo find /var/log/history -type f -exec chattr +a {} \;
#
## Sudo environment setting
# visudo
# Defaults env_keep += "HISTFILE HISTTIMEFORMAT"
#
##############################################################################
# Config change these once
HISTDIR="/var/log/history"
AUDITGROUP="historylog" # group allowed to read the logs
LOG_MODE=0640 # -rw-r----- root:historylog
DIR_MODE=1770 # drwxrwx--T root:historylog
AUTO_LOGOUT=3600 # seconds
ERRLOG="/var/log/history_audit_errors.log"
##############################################################################
# Skip for non-interactive shells
[[ $- != *i* ]] && return
##############################################################################
# Auto-logout
readonly TMOUT="$AUTO_LOGOUT"
export TMOUT
##############################################################################
# Determine source user (for sudo tracking)
if [[ -n "${SUDO_USER:-}" && $SUDO_USER != "$USER" ]]; then
SRC="$SUDO_USER"
else
SRC=$(logname 2>/dev/null || echo "$USER")
fi
LOGFILE="$HISTDIR/${USER}_${SRC}.log"
##############################################################################
# Create logfile if directory is writable and it doesn't exist
if [[ -w "$HISTDIR" && ! -e "$LOGFILE" ]]; then
touch "$LOGFILE" # we have permission
chmod "$LOG_MODE" "$LOGFILE" 2>/dev/null || true
chown "$USER:$AUDITGROUP" "$LOGFILE" 2>/dev/null || true
fi
##############################################################################
# Check group membership (user must be in $AUDITGROUP)
if ! id -nG "$USER" | grep -qw "$AUDITGROUP"; then
logger -t shell_history_audit "DENIED: $USER is not in $AUDITGROUP group. History logging skipped."
return 0
fi
##############################################################################
# Activate history logging only when logfile exists & is writable
if [[ -w "$LOGFILE" ]]; then
export HISTFILE="$LOGFILE"
export HISTSIZE=
export HISTFILESIZE=
export HISTIGNORE=''
export HISTCONTROL='ignoreboth'
export HISTTIMEFORMAT='%F %T '
shopt -s histappend
case "${PROMPT_COMMAND:-}" in
*history\ -a*) : ;;
*) PROMPT_COMMAND="history -a${PROMPT_COMMAND:+; $PROMPT_COMMAND}" ;;
esac
else
# Log error (optional)
echo "$(date '+%F %T') WARN: Could not activate logging for $USER to $LOGFILE" >> "$ERRLOG" 2>/dev/null || true
fi