Take the 2-minute tour ×
Unix & Linux Stack Exchange is a question and answer site for users of Linux, FreeBSD and other Un*x-like operating systems.. It's 100% free, no registration required.

I would like to modify the history settings for all users on the systems that I manage. I would like it to contain the information from the connecting terminal like from who

sysadmin:/ # who
sysadmin  pts/0        Mar 26 07:11 (sysadmin.doofus.local)

I currently modify my history in the following ways. I know that many of these settings have been covered here several times. However, I pulled this code from "Linux System Administration Recipes by: Juliet Kemp" long ago.

shopt -s histappend
PROMPT_COMMAND='history -n;history -a'
HISTSIZE=100000
HISTFILESIZE=100000
HISTTIMEFORMAT="%m/%d/%y %T  "

shopt -s histappend fixes problem when you have multiple terminals open information may be lost.

PROMPT_COMMAND='history -n;history -a' extends to give real-time appending to history across multiple terminals.

HISTSIZE=100000 HISTFILESIZE=100000 extends the amount of history retention

HISTTIMEFORMAT="%m/%d/%y %T " prefaces each line of history with a time stamp

What you typically get with history

835  ls
836  cd ..

My modified current history results

5853  03/26/12 07:16:49  ls
5854  03/26/12 07:16:50  ll

The return from history I would like to see

5853  03/26/12 07:16:49  sysadmin.doofus.local    ls
5854  03/26/12 07:16:50  sysadmin.doofus.local    ll

001  03/26/12 05:11:29  demo_user.doofus.local    cd
002  03/26/12 05:11:30  demo_user.doofus.local    ll

I am not "married" to seeing the DNS name. I would only want it there if it pulls it from who or another location without the need to perform a lookup or query of any kind. I would be happy with IP address.

002  03/26/12 05:11:30  192.168.0.2    ll

Why? I manage several systems where a userid that several users of the same group share to do their daily tasks. This would allow me to correlate their real location & actual user within the organization to what they did in in the history.

I am aware that this is not optimal and would like to change it but, when you are on a ship the size of the a cruise liner you don't attempt to make hairpin turns. (Note: when you do the passengers try to toss you overboard)

Anyway, until I am able to migrate them to a better solution I would like to have this tracking ability.

Also, if you have any recommendations over what I am currently using for my history modifications I would love to hear it.

Thanks,

Edit: 1

I do not want to run other programs or have to configure anything additional "within reason."

I want to add 0 overhead, if I do have to add it needs to be small.

I do trust my users I just would like (should something happen) to see which of the say 10 users that logged into the system with the same user:password did it. Or, it might not have been a user it could have been a forgotten cron on a system that performs a connection as a user to do something. Or an application Ex: BMC Control-M that connects over ssh and runs tasks. It is not so much about finding "bad users" as being able to track it down with a minimum of effort.

Edit 2:

The systems are running SLES and RHEL

share|improve this question
1  
Sounds like process accounting may be useful. The shell history was never designed for logging, and if you do want to use it you have to trust all of your users. See related question on monitoring activity and a related answer. –  jw013 Mar 27 '12 at 15:36
    
@jw013 Thanks for the comment. However, that has to be configured and managed plus I given the information I have read I would be best off excluding directories like /proc /dev and users /home directories. This adds overhead. Whereas history is already being recorded and their connection information is known to the system connecting IP etc... This information if not already available "statically" could be set that way or stored in a variable or file and input to the history records and the performance hit would be very small or 0. –  2bc Mar 27 '12 at 17:09
    
If this is on Linux, consider using auditd. I'm not sure if its logs will give you enough information. The difficulty of what you want is precisely why shared accounts are so decried. –  Gilles Mar 27 '12 at 21:49
    
It is on Linux, I will edit my question to make that clear. auditd is a lot like inotify you have to tell it what to monitor for changes. Individual files, directories, etc.. I don't want to go to that level of configuration. In fact (I do) but essentially don't care so much. I have puppet to handle that stuff. auditd comes with the additional load and time to setup as well. If an account is modifying something I still would like to look back in the history and see who or what is logging in and trying. –  2bc Mar 27 '12 at 22:32
2  
hm,since PROMPT_COMMAND= just runs normal commands before the next prompt, couldn't you write a function calling sed/awk that works on the last line of the history file to add in the information. then call that function in PROMPT_COMMAND= to append the data? it would be hackish but should do the job. –  llua Apr 9 '12 at 15:16
show 2 more comments

2 Answers

Following paragraphs describe the idea in general and are outdated in some aspects, but you can use then use latest from this page. Lets use a big file ~/.bash_history.archive (separate from HISTFILE=~/.bash_history). And then on exit from each bash session lets append new history lines to it.

The first problem with this approach was: how to make bash to call this script on each exit? Sure if you exit it by typing 'exit' then you can alias 'exit' function but I use shortcut Ctrl-D for that and I could not find a way on how to reassign it to something but not builtin exit function.

So the 1st attempt was: to forbid Ctrl-D by

export IGNOREEOF=10

and define double Ctrl-X combination to call exit function.

But the right approach is to use exit tramp of bash, which is a perfect solution because it gets called regardless of the way you exit bash: Ctrl-D, exit, close xterm window.

trap 'archive_history' EXIT

Following step is to define a starting line in our bash_history so we can save only new lines and make sure that we append to a history file.

export CURBASHSTART=`grep -v "^[ \t]*$" $HISTFILE | wc -l | awk '{print $1}'` CURBASHDATE=`date`

shopt -s cmdhist histappend

That is all we need at the bash start - now we know from which history line current (fresh) history begins. To save history add next piece to your ~/.bashrc.

archive_history()
{
    HISTORYOLD=${HISTFILE}.archive
    CURTIME=`date`
    CURTTY=`tty`
    if  [ x$HISTDUMPPED = x ]; then
      echo "#-${HOSTNAME}-- ${CURBASHDATE} - ${CURTIME} ($CURTTY) ----" >>   $HISTORYOLD

      history $(($HISTCMD-${CURBASHSTART-0})) | sed -e 's/^[ ]*[0-9][0-9]* [ ]*//g'  >> $HISTORYOLD
      export HISTDUMPPED=1
    fi
}

exit ()
{
   archive_history
   builtin exit

}

File ~/.inputrc should contain next lines to redefine exit shortcut to Ctrl-x x. On a first try you might feel that it is terrible shortcut, but then you get used to it - believe me.

$if Bash
# to exit through calling exit function which will archive the history
"\C-x\C-x": "exit\n"
# to dump history we have so far
"\C-x\C-w": "archive_history\n"

$endif

Also if your bash session is a login session and you exit by calling 'logout', then you might add next line to your ~/.bash_logout

archive_history

After all the mentioned actions are done you can find your ~/.bash_history.archive file containing sections like these

#-belka-- Sun Oct 12 21:52:13 EDT 2003 - Sun Oct 12 21:53:25 EDT 2003 (/dev/pts/13) ----
exit
aptitude
exit
#-washoe-- Sun Oct 12 18:03:16 EDT 2003 - Sun Oct 12 23:06:48 EDT 2003 (/dev/pts/3) ----

exit
cd progr/letters/resume/
e resume.tex

which in general can be read as usual history file if you wish.

share|improve this answer
add comment

From llua's suggestion, we can work a little more with history. Append a line to the system-wide BASH RC file, perhaps /etc/bash.bashrc.

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

Set up logging for "local6" in your system logger. Maybe something like this:

local6.*    /var/log/commands.log

Restart the system logger. Perhaps set up log file rotation. Log out; log in; and, the history is now written to /var/log/commands.log in a format like this:

date time hostname logger: username [audit_pid]: command [return_val]

This could be tweaked further to taste.

share|improve this answer
add comment

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.