Take the 2-minute tour ×
Ask Ubuntu is a question and answer site for Ubuntu users and developers. It's 100% free, no registration required.

Our small company runs an Ubuntu Server 11.10, to which a couple of people have SSH access. The actual terminals are sometimes used, too. How can we locally log all Bash commands run, along with user and time stamp?

We can assume that no-one is nefarious and actively trying to avoid the logging, but we'd still prefer the users not to have direct write-access to their log files. Simultaneous sessions must be handled correctly.

share|improve this question

6 Answers 6

up vote 8 down vote accepted

For BASH shells, edit the system-wide BASH runtime config file:

sudo -e /etc/bash.bashrc

Append to the end of that file:

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

Set up logging for "local6" with a new file:

sudo -e /etc/rsyslog.d/bash.conf

And the contents...

local6.*    /var/log/commands.log

Restart rsyslog:

sudo service rsyslog restart

Log out. Log in. Voila!

But I forgot about log rotation:

sudo -e /etc/logrotate.d/rsyslog

There is a list of log files to rotate the same way...

/var/log/mail.warn
/var/log/mail.err
[...]
/var/log/message

So add the new bash-commands log file in that list:

/var/log/commands.log

Save.

share|improve this answer
    
Forgot about log rotation which I added to the answer. –  user8290 Jan 7 '12 at 16:13
    
This way works, but I could invent a method around it (with csh, .bash_logout perhaps). I would go with Sabacon's acct solution. These were excellent reads: linuxjournal.com/article/6144 and beginlinux.com/blog/2010/01/… –  user8290 Jan 8 '12 at 2:19
1  
I believe this can be easily deactivated by the user by simply resetting or unsetting PROMPT_COMMAND or exec-ing to a non-bash shell. –  Stefan Lasiewski Dec 9 '13 at 18:19
    
Is there anything special about local6? What does it refer to? –  Benubird Feb 25 at 11:26
    
@Benubird it looks like there's a few preset facility levels, 8 of them being local0-local7: en.wikipedia.org/wiki/Syslog . 0 means emergency, 7 means debug, and 6 is just shy of 7, "normal operational messages." –  munchybunch May 16 at 5:16

A process accounting system may be helpful in this regard, particularly the acct Install acct package that provides the lastcomm and ac commands

The ac commands prints out statistics about users' connection time, in hours. This is the amount of time that the user has been connected to the system, either remotely via SSH or a serial terminal, or while on the console.

The lastcomm command displays information about the previously executed commands. The most recent entries are given at the top of the list. Also displayed is the total amount of CPU time that each process used.

An old tutorial that may be helpful is here:

http://www.linuxjournal.com/article/6144?page=0,1

Other accounting commands like last and so on can be found in this tutorial:

http://www.techrepublic.com/article/system-accounting-in-linux/1053377

share|improve this answer

You can find here a script to log all bash commands/built-ins into a text-file or a syslog server without using a patch or a special executable tool.

Very easy to deploy, as it is a simple shell script that need to be called once at the initialization of the bash.

It is free and I hope it suit your needs.

share|improve this answer
1  
This is a good answer but it's preferable to include the steps and the script in the body of the answer, instead of linking to your blog. Can you please edit your answer to include this? –  Tom Brossman Sep 22 '12 at 16:28

To take care of multiple sessions not over-writing the history file, you will have to put "shopt -s histappend" in a Bash startup file. See, also this question on the same problem.

share|improve this answer

try this (the solutions above will not work 100% with bash 4.3):

export HISTTIMEFORMAT="%Y-%m-%d %T "
export PROMPT_COMMAND='trap "" 1 2 15; history -a >(tee -a ~/.bash_history | while read line; do if [[ $line =~ ^#[0-9]*$ ]]; then continue; fi; logger -p user.info -t "bash[$$]" "($USER) $line"; done); trap 1 2 15;'

this does the logging AND it prevents logging of timestamps that are used for the bash history file. the trap is needed, since bash will send the signals to the "subjob" after pressing strg+c multiple times (tested with bash 4.3). this will force the logout of the current user (e.g. logged in with sudo)

share|improve this answer

You could use snoopy.

Snoopy logger may suit your purpose well. It is not intended to be unavoidable logging solution, but rather a helpful tool for diligent admins who prefer to keep track of their own actions.

Disclosure: I am snoopy maintainer.

share|improve this answer
    
Please provide instructions on installing and using it in the answer. –  muru Nov 6 at 0:45
    
Detailed installation instructions are available on the snoopy github page, which is the main snoopy resource right now: github.com/a2o/snoopy. I am agains providing installation instructions in other places as primary location is maintained by design and others are not. BTW Readme was just updated to be more structured. –  Bostjan Skufca Nov 6 at 1:31
    
Maybe so. But without even a summary of the steps needed to use this, this is a link-only answer and likely to be deleted. –  muru Nov 6 at 1:35
    
I visited your link and I assume that the installation instructions for Ubuntu would be sudo make install and sudo reboot instead of make install and reboot, but what about the make enable command? Would that command need to be prefixed by sudo in Ubuntu? –  karel Nov 6 at 1:36
    
Well, I provided a pointer to an alternative and viable solution. If that is not what this site is all about, then by all means it should get deleted, together with my account. –  Bostjan Skufca Nov 6 at 1:38

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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