linux下自建ssh堡垒机一篇中有提到记录history记录以备核查。这里结和PROMPT_COMMAND 和syslog日志服务器做一个histroy记录的统计存放和查看。

一、利用PROMPT_COMMAND记录history到文件

PROMPT_COMMAND是bash下的一个变量,用于在在每条命令运行之前进行的提示。可以执行下面的命令做一个测试:

1export HISTORY_FILE=/var/log/`date '+%y-%m-%d'`.log
2export PROMPT_COMMAND='{ date "+%y-%m-%d %T ##### $(who am i |awk "{print \$1\" \"\$2\" \"\$5}") #### $(pwd) #### $(history 1 | { read x cmd; echo "$cmd"; })"; } >> $HISTORY_FILE'  

运行完上面两个命令,再在当前终端上随意敲一些指令,然后去cat /var/log/date ‘+%y-%m-%d’.log ,发现刚刚执行的命令都在这里。根据上面的测试,我们可以将上面两行加入到/etc/profile中,然后再执行source /etc/profile生效。

注:需使用bash shell,对于csh、zsh等无效。

二、logger

logger 是一个shell 命令接口,可以通过该接口使用rsyslog(rsyslog是syslog的加强版,如果系统是syslog也可以)的系统日志模块,还可以从命令行直接向系统日志文件(或者自定义的文件)写入一行信息。
logger的用法,具体的参数可以用man查看。

1logger [-is] [-f file] [-p pri] [-t tag] [-u socket] [ message ... ]

常用的参数如下:

1-i     逐行记录每一次logger的进程ID。
2-s     记录消息到标准错误, 包括系统日志。
3-f     file 记录特定的文件(将file的内容作为message)4-p     pri 输入消息的特定优先级。 优先级可以是自定义的数值或者诸如"facility.level"的格式. 举例: "-p local3.info",local3 facility这个设备的消息级别为info。默认是"user.notice"
5-t     tag 为每行信息打上特定的标签.
6-u     sock 以特定的socket代替内嵌系统常规工作
7-d     使用一个数据进程代替一个流连接到这个socket.
8--     结束参数列表, 这个允许消息以一个“-”开始
9其中"facility.level"与rsyslog中的一样。

三、rsysylog

Linux系统日志信息分为两个部分内核信息和设备信息。共用配置文件/etc/rsyslog.conf

  • 内核信息 klogd syslogd /var/log/messages等文件
  • 设备信息 syslogd /var/log/messages等文件

其中设备可以使用自定义的设备local0-local7,使用自定义的设备照样可以将设备信息(日志)送给rsyslog。

四、整合实现

环境变量配置

1[root@test01 ~]# tail -n 1 /etc/profile
2export PROMPT_COMMAND='logger -p local0.info "$(ifconfig | grep -E "eth|em" -A 1 | grep "10.211" | grep -oP "(?

注:ifconfig部分里的grep ‘10.211’是因为主机上有两个IP,内网IP为10.211段。

这样bash环境下每次执行一条命令后,logger会将执行该命令和该命令的相关环境如登录IP、执行目录、执行时间、主机IP、执行用户等信息(可以看成是自定义设备local0,设备的日志等级自定义为info级别)送给rsyslog服务器。

rsyslog配置

由于redhat6版本下的日志程序默认为rsyslog,这里就以rsyslog为例。为了保证日志的完整性,除了将日志发送到远程的rsyslog日志集中服务器外,还落地存储一份到本地。本地和远程的rsyslog服务配置如下:

1*.info;mail.none;authpriv.none;cron.none;local0.none    /var/log/messages

该行新增加内容local0.none,意思是所有local0设备的全部等级日志信息都不记录到文件/var/log/messages中。

1local0.info           /var/log/audit.log

这是新增加的一行内容,意思是所有local0设备的info等级的日志信息记录到文件/var/log/audit.log中。远程集中接收日志的rsyslog服务器的配置文件也要改成和上面的两行一样,修改配置文件后需要重启rsyslogd服务使其生效。

1*.* @10.211.0.250

这行还是不变,意思是所有日志的所有等级都发送一份到远程(IP为10.211.0.250)的rsyslog日志集中服务器。@表示使用UDP协议发送,@@表示使用TCP协议发送。

logrotate

由于audit.log文件会不断地增大,需要类似像message、cron等日志一样的切割,要在logrotate的配置文件/etc/logrotate.d/syslog增加一行就行了。

 1/var/log/cron
 2/var/log/maillog
 3/var/log/messages
 4/var/log/secure
 5/var/log/spooler
 6#以下为新增的一行
 7/var/log/audit.log
 8{
 9    sharedscripts
10    postrotate
11    /bin/kill -HUP `cat /var/run/syslogd.pid 2> /dev/null` 2> /dev/null || true
12    endscript
13}

最后看看本地文件/var/log/audit.log ,如下:

 1[root@test01 ~]# tail /var/log/audit.log
 2Oct  6 10:08:15 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] logger
 3Oct  6 10:08:38 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] vim /etc/profile
 4Oct  6 10:36:19 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] man logger
 5Oct  6 10:36:19 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] man logger
 6Oct  6 10:36:27 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] man rsyslog
 7Oct  6 10:36:51 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] man rsyslogd
 8Oct  6 10:41:40 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] tail /etc/profile
 9Oct  6 10:56:17 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] tail -n 1 /etc/profile
10Oct  6 11:24:49 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] vim /etc/rsyslog.conf
11Oct  6 11:28:20 test01 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] cat /etc/logrotate.d/syslog
12[root@test01 ~]#

远程集中收集日志的服务器文件/var/log/audit.log

 1[root@xxxxxx log]# tail /var/log/audit.log
 2Oct  6 11:02:56 xx-xx-06 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 10:59 (xxx.xxx.xxx.xxx) [/root] vim /etc/crontab
 3Oct  6 11:03:11 xx-xx-01-WEB06 root: xxx.xxx.xxx.xxx root pts/1 2013-10-06 11:02 (xxx.xxx.xxx.xxx) [/root] more /opt/xxx/xxxxxxx/xxx/xxx/settings_local.php
 4Oct  6 11:03:28 xx-xx-06 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 10:59 (xxx.xxx.xxx.xxx) [/root] vim /etc/crontab
 5Oct  6 11:03:34 xx-xx-06 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 10:59 (xxx.xxx.xxx.xxx) [/root] ps aux | grep sphinx
 6Oct  6 11:03:50 xx-xx-06 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 11:03 (xxx.xxx.xxx.xxx) [/root] ps aux | grep sphinx
 7Oct  6 11:04:06 xx-xx-06 root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 11:03 (xxx.xxx.xxx.xxx) [/root] /usr/local/mongodb/mongostat
 8Oct  6 11:24:49 xxxx root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] vim /etc/rsyslog.conf
 9Oct  6 11:28:20 xxxx root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] cat /etc/logrotate.d/syslog
10Oct  6 11:38:18 xxxx root: xxx.xxx.xxx.xxx root pts/0 2013-10-06 09:30 (xxx.xxx.xxx.xxx) [/root] tail /var/log/audit.log
11Oct  6 11:42:52 xxxxxxxxx root:  root pts/0 2013-10-06 09:28 (xxx.xxx.xxx.xxx) [/var/log] tailf /var/log/audit.log
12[root@xxxxxx log]#

五、总结

这里还有三个问题:

1、敲空命令的时候会将最近一次执行的命令的信息再重复送一份给rsyslog;

2、export PROMPT_COMMAND

如果将PROMPT_COMMAND导出到用户工作区,那么对于有经验的用户就可以做赋值操作 export PROMPT_COMMAND =“” ,简单的语法就会导致记录功能当前session端不可用,所以PROMPT_COMMAND必须设置成只读的属性,readonly PROMPT_COMMAND 。

3、rsyslog在日志服务器上不会按主机将所有主机的日志信息区分开,而是统一的放到了/var/log/audit.log文件中,这里可以考虑使用syslog-ng按规则进行区分存放。每台主机的日志存放在该度机相对应的目录下,而且可以按日期生成相应的文件,这样便于检索。或者直接通过syslog-ng存入数据库。