If you are a Linux system administrator, you’ve probably used the history command before. It allows you to list previously executed commands in your shell. But the history command has a few shortcomings if you want to use it as a simple auditing tool. For example:
- It only shows commands from the current shell session.
- History is written to the filesystem only when the shell exits.
- It is user-specific.
These shortcomings always annoyed me. The two main reasons I needed a global command execution history were:
- I need a way to track what I’ve done to a system even after some time (including commands I run inside
tmux). - I need a way to know what others have executed on a customer-managed system.
The correct way to implement this would probably be using auditd or logging tools like auditd or snoopy. But I didn’t want to complicate things I just needed a simple solution.
Looking around the internet, I learned that I can configure a special Bash variable, PROMPT_COMMAND, to execute a command before the shell prompt appears.
Here’s a quick guide on how to set up a simple global command execution log.
Create a login shell profile script
sudo sh -c 'echo "# Log all commands to /var/log/global-commands.log
export PROMPT_COMMAND='\''echo \"\$(whoami) [\$$] \$(date \"+%Y-%m-%d %H:%M:%S\") \$(history 1 | sed \"s/^[ ]*[0-9]\+[ ]*//\")\" >> /var/log/global-commands.log'\''" > /etc/profile.d/global-logging.sh'
The above command will create
/etc/profile.d/global-logging.shwhich sets the special variablePROMPT_COMMAND. This variable runs after every executed shell command, capturing:
- The current user (
whoami)- The PID of the current shell (
$$)- The exact timestamp when the command was executed
- The most recent command, cleaned up from history (
$(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//"))
Create the log file
sudo touch /var/log/global-commands.log
Set the proper ownership and permission
sudo chown root:adm /var/log/global-commands.log
sudo chmod 622 /var/log/global-commands.log
Finally, Make the log file immutable
chattr +a /var/log/global-commands.log
After this, you’ll need to log out and back in for the configuration to take effect.
Full Script
sudo sh -c 'echo "# Log all commands to /var/log/global-commands.log
export PROMPT_COMMAND='\''echo \"\$(whoami) [\$$] \$(date \"+%Y-%m-%d %H:%M:%S\") \$(history 1 | sed \"s/^[ ]*[0-9]\+[ ]*//\")\" >> /var/log/global-commands.log'\''" > /etc/profile.d/global-logging.sh'
sudo touch /var/log/global-commands.log
sudo chown root:adm /var/log/global-commands.log
sudo chmod 622 /var/log/global-commands.log
chattr +a /var/log/global-commands.log