转文转自:http://www.sudu.cn/info/index.php?op=article&id=17049

实现该功能要求如下:
1.接受审计的登录用户默认shell必须为bash
2.bash版本至少3.00或以上

需要该要求的原因是实现功能的方法需要用到history命令的HISTTIMEFORMAT变量和PROMPT_COMMAND变量.
对于其他的shell我并未测试.如果其他shell可以实现这两个变量的功能那么理论上也可以使用.

实现方法如下:
 

 
  
  1. root用户  
  2. 1.创建一个审计日志文件  
  3. touch /var/log/audit.log  
  4. 2.将日志文件所有者赋予一个最低权限的用户  
  5. chown nobody:nobody /var/log/audit.log  
  6. 3.给该日志文件赋予所有人的写权限  
  7. chmod 002 /var/log/audit.log  
  8. 4.设置文件权限,使所有用户对该文件只有追加权限  
  9. chattr +a /var/log/audit.log 

5.编辑/etc/profile
在末尾添加下面内容
 

 
  
  1. HISTSIZE=1000  
  2. HISTTIMEFORMAT="%Y/%m/%d %T   ";export HISTTIMEFORMAT  
  3. export HISTORY_FILE=/var/log/audit.log  
  4. export PROMPT_COMMAND='{ thisHistID=`history 1|awk "{print \\$1}"`;lastCommand=`history 1| awk "{\\$1=\"\" ;print}"`;user=`id -un`;whoStr=(`who -u am i`);realUser=${whoStr[0]};logMonth=${whoStr[2]};logDay=${whoStr[3]};logTime=${whoStr[4]};pid=${whoStr[6]};ip=${whoStr[7]};if [ ${thisHistID}x != ${lastHistID}x ];then echo -E `date "+%Y/%m/%d %H:%M:%S"` $user\($realUser\)@$ip[PID:$pid][LOGIN:$logMonth $logDay $logTime] --- $lastCommand ;lastHistID=$thisHistID;fi; } >> $HISTORY_FILE' 



重新登录后,即可看到/var/log/audit.log刷新的实时日志
 

 
  
  1. 2011/06/07 17:00:01 root(root)@(10.162.2.2)[PID:17453][LOGIN:Jun 7 16:59] --- 2011/06/07 16:59:34 vi /etc/profile  
  2.  
  3. 2011/06/07 17:00:01          记录时间/命令执行完成时间  
  4. root(root)                            执行命令的用户(最初登录的用户)  
  5. @(10.162.2.2)                    IP  
  6. PID:17453                           最初登录时的LOGIN产生的PID  
  7. [LOGIN:Jun 7 16:59]           最初登录时的登录时间  
  8. 2011/06/07 16:59:34          命令执行开始的时间  
  9. vi /etc/profile                       执行的命令 

该审计功能是通过bash的一个变量PROMPT_COMMAND的特性实现.

经过本人测试,发现确实可以实现!

之后的方法,我认为可以过过命令行来查询每个用户的执行的命令,例如:

 
  
  1. [root@open*** ~]# cat /var/log/audit.log | grep "root(root)" | awk '$2>="09:44:00" && $2<"09:49:00" ' 
  2. 2012/02/06 09:44:22 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:44:22 su - cheng  
  3. 2012/02/06 09:44:22 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:44:22 su - cheng  
  4. 2012/02/06 09:44:28 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:44:28 cat /var/log/audit.log  
  5. 2012/02/06 09:44:33 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:44:33 cat /var/log/audit.log  
  6. 2012/02/06 09:44:43 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:44:42 ping www.sina.com.cn  
  7. 2012/02/06 09:44:44 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:44:44 cat /var/log/audit.log  
  8. 2012/02/06 09:45:03 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:03 nslookup www.sina.com.cn  
  9. 2012/02/06 09:45:05 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:05 cat /var/log/audit.log  
  10. 2012/02/06 09:45:16 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:16 nslookup www.google.com.hk  
  11. 2012/02/06 09:45:19 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:19 cat /var/log/audit.log  
  12. 2012/02/06 09:45:34 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:34 ls  
  13. 2012/02/06 09:45:39 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:39 cat 3322.org  
  14. 2012/02/06 09:45:42 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:45:42 cat /var/log/audit.log  
  15. 2012/02/06 09:46:49 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:49 cat /var/log/audit.log  
  16. 2012/02/06 09:47:08 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:47:08 ls  
  17. 2012/02/06 09:47:14 root(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:47:14 cat /etc/profile  

 其他用户的操作命令记录,解释一下cheng(root),它的意思是原本登录的用户是root,后来切换到了cheng这个账户。如果用户使用的是cheng这个账户登录的话,那么显示会是cheng.cheng.

 
  
  1. [root@open*** ~]# cat /var/log/audit.log | grep "cheng(root)" | awk '$1>=2012/02/06 ' | awk '$2>="09:44:00" && $2<"09:49:00" ' 
  2. 2012/02/06 09:46:27 cheng(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:27 cat /etc/passwd  
  3. 2012/02/06 09:46:32 cheng(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:32 ll  
  4. 2012/02/06 09:46:33 cheng(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:33 ls  
  5. 2012/02/06 09:46:34 cheng(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:34 cd  
  6. 2012/02/06 09:46:35 cheng(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:35 ls  
  7. 2012/02/06 09:46:46 cheng(root)@[PID:(192.168.10.68)][LOGIN:2012-02-06 09:44 .] --- 2012/02/06 09:46:46 cat /etc/passwd  

通过以上的测试,发现已基本实际了账户审计,命令记录功能。当然为了日后考虑,可以给audit.log这个文件做循环。

如何做audit.log的日志轮换呢?

 
  
  1. [root@IP120 ~]# cat /etc/logrotate.d/audit  
  2. /var/log/audit.log { 
  3.     weekly  
  4.     missingok 
  5.     dateext 
  6.     rotate 15 
  7.     sharedscripts 
  8.     prerotate 
  9.     /usr/bin/chattr -a /var/log/audit.log 
  10.     endscript 
  11.     sharedscripts 
  12.     postrotate 
  13.       /bin/touch /var/log/audit.log 
  14.       /bin/chmod 002 /var/log/audit.log   
  15.       /bin/chown nobody:nobody /var/log/audit/audit.log 
  16.       /usr/bin/chattr +a /var/log/audit.log 
  17.     endscript 

可以测试一下!刚跑过了一次。

 
  
  1. [root@IP120 ~]# logrotate -vf /etc/logrotate.d/audit  
  2. reading config file /etc/logrotate.d/audit 
  3. reading config info for /var/log/audit.log  
  4. Handling 1 logs 
  5. rotating pattern: /var/log/audit.log  forced from command line (15 rotations) 
  6. empty log files are rotated, old logs are removed 
  7. considering log /var/log/audit.log 
  8.   log needs rotating 
  9. rotating log /var/log/audit.log, log->rotateCount is 15 
  10. destination /var/log/audit.log-20120726 already exists, skipping rotation 
  11. running prerotate script 
  12. running postrotate script