From the looks of things, fixing ksh to make history alteration impossible is fairly easy. I've seen all the recommendations to make HIST* environment variables read-only, and the use of chattr to make the history file append-only (with chattr +a .sh_history).

Bash, however, has two things which seem to make it impossible to prevent history alteration: the history command (with history -c and history -d) and the separation of the history file from the actual run-time history (kept in memory). I also read here on serverfault that if you kill the current shell, then history won't be written out.

Is there any way to prevent history alteration for Bash? I want to be able to save all user commands without the user being able to remove anything from the history whatsoever.

Any further tips on Korn shell are also welcome. (I know about ksh-93 auditing... don't know if we can use it.)

  • I also found some information on auditd and on lastcomm, both of which can help track user commands and bypass shell history altogether.
    – Mei
    May 23, 2011 at 22:02

2 Answers 2


Here's a solution for sending all commands executed to a syslog server.


Extract from the blog post

Here are two methods to send a copy of all commands executed by the users to a Syslog server. The first one will use the Bash “trap” feature. The second one is a patch to apply in the Bash source code.

Using a trap

Just add the following lines in your /etc/profile:

function log2syslog
   declare command
   command=$(fc -ln -0)
   logger -p local1.notice -t bash -i — $USER : $command
trap log2syslog DEBUG

/etc/profile is parsed and executed when Bash is started. The goal is to use the trap feature and call a function each time the user generates activity. The trap function (log2syslog) will extract the last command from the history and log it to Syslog using the logger command. Very easy to implement but this method:

spawns new process at each command logged (can have a negative effect when the server activity is high)
is not transparent to the user (regular users can’t edit /etc/profile but can read it!)

That’s why the second method will be preferred. Using a patch

The method is to apply a patch on the Bash source tree and recompile the shell. It requires a environment with a compiler and the source code but this method will use less CPU and will be completely transparent!

An example of patch is available here. It takes five minutes to manually apply the patch to the Bash 4 source tree.

Here is an example of Syslog message:

Feb 27 19:30:51 honey bash: HISTORY: PID=21099 UID=1000 echo foo!
  • When answer questions on an SE site, please include at least a summary of the solution in your answer, not just a link. Links go stale, but answers here are archived with their questions in publicly accessible data dumps.
    – Caleb
    May 19, 2011 at 11:24
  • well I have updated my answer with the details, but can't help but feel plagiaristic May 19, 2011 at 11:32
  • 1
    There is a fine line between referencing other people's stuff and plagerising :) In this case I think I would re-word to summarize a little bit, but still include the code for the trap. The patch method I would mention and perhaps link to the site where it was mentioned, but I wouldn't include all that in your post because, if you notice, the link to the mentioned patch is dead! This is exactly the problem we want to avoid by providing complete answers. There is no point in telling people to patch if you can't find the patch.
    – Caleb
    May 19, 2011 at 11:41
  • This was a fantastic idea. I've already put it in, and may or may not stick with this.
    – Mei
    May 23, 2011 at 21:29

If you want to log what your users are doing then take a look at snoopy. It's also available as a package to install for CentOS.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.