Skip to content

Instantly share code, notes, and snippets.

@dayreiner
Last active August 1, 2024 04:59
Show Gist options
  • Save dayreiner/cbe525defc5159c2ae36 to your computer and use it in GitHub Desktop.
Save dayreiner/cbe525defc5159c2ae36 to your computer and use it in GitHub Desktop.
Log all users zsh / bash commands via syslog without 3rd-party tools or auditd

Sending Bash and ZSH Commands to Syslog

Also posted here: http://18pct.com/sending-bash-and-zsh-commands-to-syslog/

Your bash/zsh history is great if its complete, but it doesn't capture commands across all users, sudo's, root commands etc. In particular with test environments, someone may perform a "one-off" procedure and then months later it needs to be repeated. It would be nice to be able to look up what the user did at the time, and searching through multiple, possibly truncated history files is a pain.

Tools like typescript are great if you're actively documenting, but not something you would use all the time in practice and capture more than just a history of your commands. There are third-party tools like rootsh and Snoopy that can accomplish this, but third-party tools can be overkill if all you want is a quick reference in a relatively controlled environment.

If you need an "official" record of all user actions, you should be using process accounting or better-yet auditd instead (which can be configured to record all user commands). This method is just a trivial way to get a searchable record of all user actions on a box for convenience -- not for security or auditing purposes.

Syslog Setup

Assuming your distribution uses rsyslog, in /etc/rsyslog.d create a file called commands.log with the following contents:

local6.*    /var/log/commands.log

This will log anything going to local6 in to a local file called commands.log. You can adjust this as you want, or send everything to a central syslog server or logstash instance.

Bash and ZSH Setup

This method takes advantage of the built-in PROMPT_COMMAND variable in bash and the precmd function in ZSH. Both of these are used to execute something with every command entered in the shell, making them perfect for capturing command input and piping it to syslog.

Global Bash Profile Setup

Add the following line to the bottom of the global /etc/bashrc file on your system:

# Log commands to syslog for future reference
export PROMPT_COMMAND='RETRN_VAL=$?;logger -p local6.debug "$(whoami) [$$]: $(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//" ) [$RETRN_VAL]"'

Alternately, you can just add this to the end of your .bashrc if you just want to do this for a single user for some reason.

Global ZSH Profile Setup

Add the following line to the bottom of the global /etc/zshrc file on your system:

# Log commands to syslog for future reference
precmd() { eval 'RETRN_VAL=$?;logger -p local6.debug "$(whoami) [$$]: $(history | tail -n1 | sed "s/^[ ]*[0-9]\+[ ]*//" ) [$RETRN_VAL]"' }

Alternately, you can just add this to the end of your .zshrc if you just want to do this for a single user for some reason.

Log Format

From now on, whenever someone logs into the system using bash or zsh, you'll get a nice log in order of all the commands that were executed on the box and by whom:

Feb 16 16:12:44 myhost root: jim [16285]: sudo yum update [1]
Feb 16 16:16:32 myhost bob: bob [10033]: docker ps  [0]
Feb 16 16:16:36 myhost satin: satin [10033]: docker ps -a [0]
@spirit986
Copy link

the file in rsyslog.d should be commands.conf ?

Yes I can confirm myself it is commands.conf inside /etc/rsyslog.d

@XCM-jj
Copy link

XCM-jj commented Mar 31, 2021

how to log command run with sh(/use/bin/sh /bin/sh )?

@Stef-Lan
Copy link

I tried using this code although whenever a new shell is opened or an empty command is sent, it will log the latest command used. Is there a way to avoid this?

@lmaddox
Copy link

lmaddox commented Aug 1, 2024

@Stef-Lan not with the PROMPT_COMMAND technique (I use this for adding an audible success/failure indicator, and I've chosen to live with the quirk you've described). The "cleaner" way is to use the classic. The difficulty being creating/maintaining a .deb+PPA autodeployment pipeline for your forensically-enhanced bash shell. Still looking for a ZSH variant of the solution

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment