How do I log history or "secure" bash against history removal?

This is a question which has no answer applicable to bash. You are here because you asked or wanted to know how to find out what a user had executed when they unset or /dev/nulled their shell history. There are several problems with this.

The first issue is:

This innocuous looking command does what you would presume it to: it kills the current shell off. However, the .bash_history is ONLY written to when bash is allowed to exit cleanly. As such, sending SIGKILL to bash will prevent logging to .bash_history

Users may also set variables that disable shell history, or simply make their .bash_history a symlink to /dev/null. All of these will defeat any attempt to spy on them through their .bash_history file.

The second issue is permissions. The bash shell is executed as a user. This means that the user can read or write all content produced by or handled by the shell. Any location you would try to log to, MUST be writeable to by the user, and not a privileged user. This is because the shell specifically tries to ensure the user does not exceed its privileges. Imagine a regular user writing a root read/write only history. This is creative license for exploiting and gaining escalated privileges on the server, and thus an extremely bad idea.

The third issue is location. Assume that you pursue a chroot jail for your bash users. This is a fantastic idea, and a good step towards securing your server. However, placing your users in a chroot jail conversely affects the ability to log the users' actions. Once jailed, your user can only write to content within its specific jail. This makes finding user writeable extraneous logs a simple matter, and enables the attacker to find your hidden logs much easier than would otherwise be the case.

Where does this leave you? Unfortunately, nowhere good, and definitely not what you wanted to know. If you want to record all of the commands issues to BASH by a user, your best bet is to modify BASH so that it actually records them, in real time, as they are executed -- not when the user logs off. This is still not reliable, though, because end users may simply upload their own shell and run that instead of your hacked BASH. Or they may use one of the other shells already on your system, instead of your hacked BASH. But, for those who absolutely must have some form of patch available, you can use the patch located at (patch submitted by _sho_ -- use at your own risk. The results of a code-review with improvements are here: -- Heiner).

For a more serious approach to this problem, consider BSD process accounting (kernel-based) instead of focusing on shells.