By adding the following entry in /etc/bashrc, we can log the commands executed by all the users on a Linux machine.
This would be certainly helpful for tracking commands on Critical servers.
This would be certainly helpful for tracking commands on Critical servers.
PROMPT_COMMAND='history -a >(logger -t "$USER[$PWD] $SSH_CONNECTION")'
After you add the above entry at the end of /etc/bashrc file, execute the command 'source /etc/bashrc' or logout and login back to your session. Now the commands executed by all the users will be logged in /var/log/messages.
Note: If you wish to log the commands on to a different file, please check the solution given in the comments section.
Apr 18 13:35:21 Linux-Mach root[/root] 192.168.4.5 51650 172.16.0.252 22: uptime
Apr 18 13:35:24 Linux-Mach root[/opt] 192.168.4.5 51650 172.16.0.252 22: cd /opt
Apr 18 13:35:26 Linux-Mach root[/opt] 192.168.4.5 51650 172.16.0.252 22: ls -lR
Apr 18 13:35:35 Linux-Mach root[/opt] 192.168.4.5 51650 172.16.0.252 22: iostat -x 2
Apr 18 13:35:39 Linux-Mach root[/root] 192.168.4.5 51650 172.16.0.252 22: cd /root
Apr 18 13:35:39 Linux-Mach root[/root] 192.168.4.5 51650 172.16.0.252 22: ls -l
Apr 18 13:35:51 Linux-Mach root[/home] 192.168.4.5 51650 172.16.0.252 22: cd /home
Apr 18 13:35:52 Linux-Mach root[/home] 192.168.4.5 51650 172.16.0.252 22: ls
Apr 18 13:35:56 Linux-Mach root[/home] 192.168.4.5 51650 172.16.0.252 22: httpd -t
Apr 18 13:51:24 Linux-Mach test1[/home/test1] 192.168.6.8 9106 172.16.0.252 22: ls -l
Apr 18 13:53:20 Linux-Mach test1[/var/lock/subsys] 192.168.6.8 9106 172.16.0.252 22: cd /var/lock/subsys
Apr 18 13:53:30 Linux-Mach test1[/var/lock/subsys] 192.168.6.8 9106 10.160.0.252 22: ls -ltr
Sample test result:
Apr 18 13:35:21 Linux-Mach root[/root] 192.168.4.5 51650 172.16.0.252 22: uptime
Apr 18 13:35:24 Linux-Mach root[/opt] 192.168.4.5 51650 172.16.0.252 22: cd /opt
Apr 18 13:35:26 Linux-Mach root[/opt] 192.168.4.5 51650 172.16.0.252 22: ls -lR
Apr 18 13:35:35 Linux-Mach root[/opt] 192.168.4.5 51650 172.16.0.252 22: iostat -x 2
Apr 18 13:35:39 Linux-Mach root[/root] 192.168.4.5 51650 172.16.0.252 22: cd /root
Apr 18 13:35:39 Linux-Mach root[/root] 192.168.4.5 51650 172.16.0.252 22: ls -l
Apr 18 13:35:51 Linux-Mach root[/home] 192.168.4.5 51650 172.16.0.252 22: cd /home
Apr 18 13:35:52 Linux-Mach root[/home] 192.168.4.5 51650 172.16.0.252 22: ls
Apr 18 13:35:56 Linux-Mach root[/home] 192.168.4.5 51650 172.16.0.252 22: httpd -t
Apr 18 13:51:24 Linux-Mach test1[/home/test1] 192.168.6.8 9106 172.16.0.252 22: ls -l
Apr 18 13:53:20 Linux-Mach test1[/var/lock/subsys] 192.168.6.8 9106 172.16.0.252 22: cd /var/lock/subsys
Apr 18 13:53:30 Linux-Mach test1[/var/lock/subsys] 192.168.6.8 9106 10.160.0.252 22: ls -ltr
Updated one:
# echo $PROMPT_COMMAND
RETRN_VAL=$?;logger -p local3.debug "$(whoami) $remoteip [$$]: $(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//") [$RETRN_VAL]"
On RHEL 8.x
[root@rhel8 ]# cat /etc/profile.d/prompt.sh
remoteip=$(who am i | awk '{print $5}' | sed "s/[()]//g")
export PROMPT_COMMAND='RETRN_VAL=$?;logger -p local3.debug "$(whoami) $remoteip [$$]: $(history 1 | sed "s/^[ ]*[0-9]\+[ ]*//") [$RETRN_VAL]"'
[root@rhel8 ]#
Good one Ashok
ReplyDeleteThis was an excellent one, is their any option to store the command in different location instead of /var/log/message
ReplyDeleteHi Siva, Good question. It should be possible by adjusting the Syslog facility. I will come out with a solution soon.
ReplyDeleteHi Siva, Here's the solution for you to log the commands on to different file.
ReplyDeleteLets say you want to capture the command execution in a different file called "/var/log/usercommands".
Open the /etc/syslog.conf file and insert the syslog facility entry (local[0-6].info) as shown below:
*.info;mail.none;authpriv.none;cron.none /var/log/messages
local2.info /var/log/usercommands
(Please note that you can use the Syslog facility "local0-6" for any purpose)
After this, restart the 'syslog' service.
Update the entry in /etc/bashrc as follows:
PROMPT_COMMAND='history -a >(logger -p local2.info -t "$USER[$PWD] $SSH_CONNECTION")'
Run 'source /etc/bashrc'
Now all the commands will be captured in /var/log/usercommands.
Note: Using '-p' with logger command, we can redirect the logs to a different Facility with different priority defined in /etc/syslog.conf file.
More details on Syslog facilities and priorities: http://content.hccfl.edu/pollock/aunix2/logging.htm
Thankyou for providing the solution
ReplyDeleteBy making the variable "readonly" the end user cannot change it and conceal their actions.
ReplyDeletereadonly PROMPT_COMMAND='history -a >(logger -t "$USER[$PWD] $SSH_CONNECTION")'
or
readonly PROMPT_COMMAND='history -a >(logger -p local2.info -t "$USER[$PWD] $SSH_CONNECTION")'
That was really helpful. Thanks.
DeleteWow...that was an Excellent tip Jason !! Thankyou so much !!
ReplyDeleteGuys, I'm getting the following error while running "source /etc/bashrc" command. Please help me out the resolution for this.
ReplyDelete/root# source /etc/bashrc
-sh: PROMPT_COMMAND: line 5: syntax error near unexpected token `('
-sh: PROMPT_COMMAND: line 5: `history -a >(logger -t "$USER[$PWD] $SSH_CONNECTION")'
(**root**on usclswups011)
/root#
This comment has been removed by the author.
ReplyDelete@Basha, This is a Syntax error in /etc/bashrc file. It appears you are using a Back tick (`) instead of single-quote (') infront of "history -a". Please correct that and try.
ReplyDeleteThanks Ashok..
ReplyDeleteHi Ashok,
ReplyDeleteIs there a way to transmit the user issue command to another server for instance a centralized logging server?
Yes, there is.
DeleteYou just have to selectively ship a certain type of logs to a remote server. For ex, in rsyslog to ship all logs over UDP, you do something like:
*.* @syslog.server.com
You just need to replace *.* with more specific priority.
Yes, you can push the logs to Centralized Log server.
ReplyDelete-Ashok
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteBut this is not working for normal users
ReplyDeleteHi Ashok, great tutorial! just one thing, this is not logging any user commands, it's logging just root commands. Is it possible to log in ALL users' commands? Thanks!!
ReplyDeleteIn your bashrc if you put in a variable
ReplyDeleteWHOIAM=l`who mom likes | awk '{print $1}'
then put the variable in your
readonly PROMPT_COMMAND='history -a >(logger -p local2.info -t "$WHOIAM:$USER[$PWD] $SSH_CONNECTION")'
This way you will also log on one line if someone SU's to someone else. So if someone SU's to root you will see the commands as root and also be able to tell the origination user
whoops.. type
ReplyDeleteWHOIAM=l`who mom likes | awk '{print $1}'
should read
WHOIAM=`who mom likes | awk '{print $1}'
You could use snoopy: https://github.com/a2o/snoopy
ReplyDeleteHi Ashok,
ReplyDeleteI keep getting
-bash: PROMPT_COMMAND: readonly variable
Pls help
do an "unset -f PROMPT_COMMAND". Then login via another session and run "source /etc/bashrc". It worked for me
DeleteHi Ashok,
ReplyDeleteThanks for nice guide, It's working as excepted,
My case, I am exec. command and different machine, Not same machine, When I login the particular server executing some command means it's recording nicely.
In my case ::
I am executing 'df -H' command from different not recording.
ssh sysops@172.16.30.215 'df -H'
Please guide me.
I see the logs duplicated in "messages" file and also "usercommands" file. Is it possible to save the logs only in "usercommands" file and not is messages?
ReplyDeleteHi,
ReplyDeleteIt works for me but it seems this solution is not logging commands if the user is always trying to execute same commands repeatedly.
Ex.
If the user is executing “uptime” command repeatedly, it is only logging once.
If the user is executing “uptime” and then another command such as “ls -lrt” and then uptime, it is logging everything as expected.
How we can fix this?
Fantastic article. Thank you.
ReplyDeleteI agree with "THE MIRROR", it would be better if the commands are not getting written to /var/log/messages as well
is there any way to log every user command making their own respective user log file.
ReplyDelete