[转]生成 AIX 审计报告
生成 AIX 审计报告
审计筛选
在 IBM Systems 杂志(2009 年 8 月)上,我发表了一篇名为 “Monitoring Events with AIX Audit” 的文章(请参阅 参考资料)。 在那篇文章中,我没有讨论审计报告的生成过程。AIX 提供的 auditselect 实用程序可以从审计日志中选择事件记录。但是,当采用流模式进行审计时,可以使用 sed 和 awk 实用程序生成格式化的报告。在本文中,我将讨论审计事件并演示如何生成日常审计报告。
AIX 审计可以配置为三种模式:流、二进制或者流和二进制。我个人喜欢选用流模式,因为它以文本模式写审计日志文件,允许实时地查看审计事件。流模式将事件写入 循环的缓冲文件 stream.out 中。因此,如果包含审计日志文件的文件系统满了,它仍然会继续将事件写到日志文件的开头。
当以二进制模式使用审计时,会以二进制格式写入数据。如果希望长期收集并保存审计事件记录,该模式一般是首选方式。但是,作为良好的管理实践,也可以使用流模式保存审计事件的历史记录。
在开始配置审计时,必须非常小心地进行尝试,在刚开始收集审计事件时,毫无疑问会出错。负责审计的系统管理员会对此进行核查。要想监视相应的事件,则需要定期修改 /etc/security/config
文件。关于可监视事件的完整列表,请参阅 参考资料 中的红皮书《Accounting and auditing》。对确定要监视的事件之后,可以通过其他文件定制监视,例如:
/etc/sudoers /etc/ssh/sshd_config /etc/syslog.conf |
在 /etc/security/objects
文件中设置要监视的特殊文件和系统特有的文件。
在 objects 文件中,可以指定应该监视的文件(称为对象),以及应该监视读、写还是执行操作。监视 sudoers
、sshd_config
和 syslog.conf
文件的写操作的典型设置如下:
/etc/sudoers.tmp: w = "SUDO_WRITE" /etc/syslog.conf: w = "SYSLOG_WRITE" /etc/ssh/sshd_config: w = "W_SSHD_CONFIG_IBM" |
前面示例中 objects 文件的输出格式是:
full path name of file: < access mode> = "tag name" |
其中的 access mode
是 r(代表读访问)、w(代表写访问)和 x(代表执行访问)。tag name
是监视的文件的唯一名称。应该确保 tag name
描述了指定的访问模式。另外注意,每一行上只能有一个 access mode
条目。因此,如果要监视 /etc/ssh/sshd_config
的读写访问,则可以设置以下条目:
/etc/ssh/sshd_config w = "W_SSHD_CONFIG_IBM" r = "R_SSHD_CONFIG_IBM" |
对于写访问,我使用的标记名以 "W_" 开头;对于读访问,标记名以 "R_" 开头。这有助于在查看审计日志或审计报告时明确区分读访问和写访问。
为了让审计系统了解如何将每个对象作为一条记录输出到审计日志中,需要使用 /etc/security/events
文件中的相应条目。
使用简单的 printf 语句就足够了。例如,要想记录 /etc/ssh/sshd_config
和 /etc/security/audit/objects
文件中指定的标记名 W_SSHD_CONFIG_IBM,可以进行以下设置:
* /etc/ssh/sshd_config W_SSHD_CONFIG_IBM = printf "%s" |
在这个示例中,代码行开头是一个 '*',然后是监视的文件的完整路径名,接着是 objects 文件中指定的标记名,最后是一个 printf 语句,可输出传递给的命令的字符串。
要想让审计系统输出所有已分析的、作为被监视命令一部分的选项,则需要确保审计系统输出了记录的剩余部分。因此,在 /etc/security/streamcmds
文件中要确保 auditpr 命令包含 '-v'。下面是一个示例:
/usr/sbin/auditstream | auditpr -v > /audit/stream.out & |
监视的审计事件放在 /etc/security/config
文件中。可在该文件中创建包含要监视的事件的类。config 文件的内容如下所示。通常会将事件类分配给用户,还指定默认分配给系统上的每个用户的类。一个用户可以属于一个或多个类。注意,在 "general" 类中,我只监视用户属性更改,例如密码更改、组更改、chuser、rmuser、adduser 和 su 尝试。而您的配置可能很不一样。
# cat /etc/security/audit/config streammode = on binmode = off bin: trail = /audit/trail bin1 = /audit/bin1 bin2 = /audit/bin2 binsize = 25000 cmds = /etc/security/audit/bincmds stream: cmds = /etc/security/audit/streamcmds classes: general = File_Write,PASSWORD_Change,USER_Change,USER_Remove,USER_Create ,GROUP_Change,GROUP_Create,GROUP_Remove,USER_SU,PASSWORD_Flags users: default = general |
可以使用 lsuser 命令查看当前分配给用户的审计类,您会看到审计类 general 被分配给所有用户。在 config 文件的 users 部分中,指出了该类是分配给所有用户的默认类。但是,正如前面提到的,一个用户可以属于多个类。
# lsuser -a auditclasses ALL root auditclasses=general daemon auditclasses=general bin auditclasses=general sys auditclasses=general adm auditclasses=general lpd auditclasses=general lp auditclasses=general invscout auditclasses=general snapp auditclasses=general ipsec auditclasses=general ftp auditclasses=general dxtans auditclasses=general ukazap auditclasses=general euazap auditclasses=general auazap auditclasses=general beazap auditclasses=general laazap auditclasses=general …. … |
要想启动审计子系统,请输入以下命令:
# audit start |
要想停止审计子系统,请输入以下命令:
# audit stop |
使用以下命令查看当前的设置,包括定义的类及其事件,以及系统上的可用事件和正在监视的对象(首先要确认目前正在进行审计):
# audit query |
如果重新引导服务器或停止运行审计服务,那么重新启动系统时会覆盖 stream.out 审计日志。因此,一定要通过某种机制把当前的 stream.out 内容保存并复制到新的文件中(稍后讨论这个问题)。要想确保在重新引导系统时重新启动审计,一定要在 /etc/rc.tcpip
文件中添加以下行:
# start audit /usr/sbin/audit start 1>&- 2>&- |
如果重新引导服务器,则需要确保通过命令或脚本复制 stream.out 日志文件。这些命令应该放在 /etc/rc.tcpip
文件中审计启动命令前面,以避免启动审计时日志文件内容被重写。
当审计系统报告事件时,它会报告相关用户最初的登录 ID,而不是此用户通过用户 su 得到的 ID。这只适用于本地连接。对于通过 SSH 等远程连接的用户,则报告连接时使用的登录 ID。AIX 审计系统并不知道建立 SSH 连接之前用户 su 的所作所为。
关于系统上典型的审计日志文件,参见清单 1;它还显示了记录的追踪部分:
event login status time command --------------- -------- ----------- ------------------------ ------------------ ------------- USER_SU dxtans OK Mon Jan 10 19:05:13 2011 su root PASSWORD_Change dxtans OK Mon Jan 10 19:06:27 2011 passwd alpha PASSWORD_Flags dxtans OK Mon Jan 10 19:06:33 2011 pwdadm alpha -c USER_SU bravo FAIL Mon Jan 10 19:07:01 2011 su root GROUP_Change dxtans OK Mon Jan 10 19:07:33 2011 chgroup admin users=dxtans,charlie PASSWORD_Change root OK Mon Jan 10 19:08:31 2011 tsm charlie USER_SU charlie OK Mon Jan 10 19:08:36 2011 su root USER_Change charlie OK Mon Jan 10 19:08:54 2011 chuser zulu rlogin=true |
仔细看一下清单 1。从前几行可以看出,用户 dxtans 通过用户 su 变成了 root 用户。然后,他更改了用户 alpha 的密码和 pwdadm 标志。因为我们让审计系统输出记录的剩余部分,现在可以看到传递给 pwdadm 的命令选项是 'alpha -c'。如果不输出记录的剩余部分,就没有这些信息。用户 bravo 也试图通过用户 su 变成 root 用户,但是失败了。这可能是因为用户 bravo 不知道密码,或者由于不属于 root 用户的子组而没有得到授权。在这个示例中,用户 bravo 没有得到访问 root 用户的授权,因此这个操作是违规的。
注意,当输出记录的追踪部分时,可在单独的行上输出这部分。在生成报告时,必须把记录的这两个部分连接起来,让输出符合报告的格式要求。这会让报告以列的形式呈现,awk 可以从这些列中提取信息。
要想生成报告,第一个任务是取得 stream.out 的拷贝。在查看 stream.out 文件时您会发现,对于某个文件执行写操作时,可能有多个条目。在记录对 /etc/sudoers
文件的写操作时,尤其可能出现这种情况。因此,一定要通过 uniq 处理文件,去掉重复的条目。然后,使用 sed 将记录的两个部分合并到同一行上,并且还需要生成报告的标题。
下面的代码实现了上述目标。假设 stream.out 文件被解析为第一个参数 ($1) ,产生的输出重定向到 holdf 文件:
cat $1 | uniq > holdf mv holdf $1 sed '1i\ '$host' P-Series Audit Report on User Account Changes /command/a\ --------------------------------------------------------- $!N;s/\n/ / # pull in the last column s/ //g' $1 >holdf |
日志的内容包含以下列格式:
- 第 1 列是实际的事件,例如 USER_Change。
- 第 2 列是用户的登录 ID。
- 第 3 列是执行的命令的退出状态,值是 OK 或 FAIL。
- 第 4-8 列是事件的日期/时间,比如 Tue Jan 11 11:42:02 2011。
- 第 9 列是执行的命令,例如 chuser。
- 第 10 列是传递给此命令的所有其他信息,也就是记录尾部包含的信息,通常是传递的参数。
现在,我们可以提取日常审计报告需要的信息,只提取与自己的审计安全策略有关的信息。例如,监视未授权的账号切换,或者更改尚未通过事件票据 (incident ticket) 或系统更改请求进行授权的用户账户属性。
注意,您可能不关心系统管理员通过用户 su 得到的账号,因为这可能是正常的管理工作。您可能不关心用户是否更改了自己的密码,但是当然可以要求由 root 用户更改密码,无论用户 ID 是什么。完成信息提取之后,可以通过电子邮件把生成的报告发送给管理经理或系统管理员,让他们通过事件票据或更改请求来审查和证明该报告。
我发现,对于希望满足的每个条件,使用单独的 awk 语句更便于管理。这样更容易修改关于提取什么信息的规则或模式,尤其是当您不在时,可方便其他系统管理员修改规则。通过在 awk 语句中使用 NOT 操作符,可以指定不应该提取哪些记录。然后,通过 AND 关系将脚本中包含的所有 awk 语句连接起来。例如,为了排除用户由于失误试图通过 su 变成本身的事件,可以使用:
!($1 =="USER_SU" && $2 ==$10) |
为了不包含 root 用户(他通过用户 su 将用户 ID 变成了 poppy),我们可以使用:
!($1=="USER_SU" && $2=="root" && $9=="su" && $10=="poppy") |
为了忽略用户修改自己的密码的事件,可以使用:
!($1=="PASSWORD_Change" && $2 == $10) |
通过 AND 关系将这些语句(和其他 awk 语句)连接起来,结果只产生了我们希望排除的记录。例如:
awk ' !($1 =="USER_SU" && $2 ==$10 && !($1=="USER_SU" && $2=="root" && $9=="su" && $10=="poppy") && !($1=="PASSWORD_Change" && $2 == $10) && ...more awk statements... ... |
如果不关心任何用户是否通过 su 变成另一个用户,那么可以排除这些事件。例如,假设用户 genrep1 是共用的用户 ID,报告中不需要这些事件,则可以使用以下代码排除这些事件:
!($1=="USER_SU" && $10=="genrep1") |
如果想基于模式搜索来忽略整个记录,则可以使用以下搜索语句:
/ <pattern>/ |
要忽略包含字符串 'xnpd' 的所有记录,可以使用以下 awk 语句:
!/xntpd/ |
选出不希望每天报告的记录或事件之后,可使用 awk END 块语句输出 "end of report"。要筛选 holdf 文件中的事件,可以使用以下语句:
awk ' !($1 =="USER_SU" && $2 ==$10) && !($1=="USER_SU" && $2=="root" && $9=="su" && $10=="poppy") && !($1=="PASSWORD_Change" && $2 == $10) END {print "\t\t\t\t--- end of report ---"}' holdf |
生成报告之后,可以通过电子邮件将报告发送给系统管理员或经理审查。
清单 2 给出一个脚本以及审计日志 stream.out 文件中可以忽略的事件。清单中包含的模式规则只作为演示示例。清单 2 包含的 awk 语句演示了如何对 stream.out 文件应用 awk 模式,可以根据自己的需要改进和定制它。生成报告之后,可通过电子邮件将它发送到邮件列表 rs6admins。
#!/bin/sh # auditfilter if [ $# != 1 ] then echo "`basename $0` <audit_log>" exit 1 fi if [ ! -f $1 ] then echo "file does not exist" exit 1 fi holdf=/tmp/holdf host=$(hostname) # extract the date part of the filename for the report report=$(basename $1) # filename ie: audit0118.log date_rep=$(echo $report | sed -e 's/audit//g' -e 's/.log//g') mth=$(echo $date_rep | cut -c 1,2) day=$(echo $date_rep | cut -c 3,4) datex="$day / $mth" # email list here list="rs6admins " mailit2() { sendmail -t <<mayday To:$list Subject:audit report on $host Content-Type: text/html Content-Transfer-Encoding: 7bit <body> <body bgcolor="#C0C0C0"> Generated: `date` <br> Date of Audit : $datex <hr> <br> <pre> $(cat $1) </pre> </body> mayday } cat $1 | uniq > $holdf mv $holdf $1 # do header and join lines sed '1i\ '$host' P-Series Audit Report on User Account Changes /command/a\ --------------------------------------------------------- $!N;s/\n/ / # get rid of the ** line s/-*//g # pull in the last column, these are spaces - adjust as required in sed s/ //g' $1 >$holdf # filter out awk ' !($1 =="USER_SU" && $2 ==$10) && !($1=="USER_SU" && $2=="root" && $9=="su" && $10=="poppy") && !($1=="PASSWORD_Change" && $2 == $10) && !($1=="USER_SU" && $10=="operator") && !($1=="USER_SU" && $10=="genrep1") && !/xntpd/ END {print "\t\t\t\t--- end of report ---"}' $holdf >$1.rep # cat $1.rep mailit2 $1.rep |
清单 3 调用 auditfilter 脚本。auditfilter 脚本执行完之后,生成两个文件。一个包含格式化的审计报告,其文件名采用以下格式:
audit<month><day>.log.rep |
另一个是当前 stream.out 文件的拷贝,其文件名采用以下格式:
audit<month><day>.log |
#!/bin/sh # auditroll OUTFILE=/audit/audit`date +%m%d`.log # # Shut down auditing /usr/sbin/audit shutdown sleep 3 # # Move contents of capture file mv /audit/stream.out $OUTFILE # # Restart auditing /usr/sbin/audit start # # Kill off processes using the audit file fuser -k $OUTFILE # # Filter contents of audit file /audit/auditfilter $OUTFILE |
仔细看一下清单 3,它使用 date 命令作为已复制的 stream.out 文件的文件名的一部分来指定新文件名。然后关闭审计,将 stream.out 文件转移到新的文件 (OUTFILE),以生成新的审计报告文件。随后,重新启动审计;为这些天的审计活动创建一个新的 stream.out 文件。为了保证安全性,确保关闭审计之后没有任何针对 OUTFILE 运行的进程,可以使用 fuser 终止这些进程。
在执行 auditfilter 脚本时,它在与图 1 相似的电子邮件中生成格式化的报告。
可以在每个工作日执行 auditroll 脚本,生成关于前几天的审计活动的报告。
按照我的观点,在 AIX 上使用审计是必须做的工作。可以通过审计工作监视系统上与安全相关的事件。在企业环境中收集审计报告时,我建议最好将所有报告都整理为一个电子邮件以便审查。
学习
- 文章 "Monitoring Events with AIX Audit" 讲解如何配置 AIX 审计系统。
- 阅读 Auditing and Accounting on AIX 指南,了解如何在 AIX 系统上设置并维护审计。
- AIX and UNIX 专区:developerWorks 的“AIX and UNIX 专区”提供了大量与 AIX 系统管理的所有方面相关的信息,您可以利用它们来扩展自己的 UNIX 技能。
- AIX and UNIX 新手入门:访问“AIX and UNIX 新手入门”页面可了解更多关于 AIX 和 UNIX 的内容。
- AIX and UNIX 专题汇总:AIX and UNIX 专区已经为您推出了很多的技术专题,为您总结了很多热门的知识点。我们在后面还会继续推出很多相关的热门专题给您,为了方便您的访问,我们在这里为您把本专区的所有专题进行汇总,让您更方便的找到您需要的内容。
-
AIX and UNIX 下载中心:在这里你可以下载到可以运行在 AIX 或者是 UNIX 系统上的 IBM 服务器软件以及工具,让您可以提前免费试用他们的强大功能。
- IBM Systems Magazine for AIX 中文版:
本杂志的内容更加关注于趋势和企业级架构应用方面的内容,同时对于新兴的技术、产品、应用方式等也有很深入的探讨。IBM Systems
Magazine 的内容都是由十分资深的业内人士撰写的,包括 IBM 的合作伙伴、IBM
的主机工程师以及高级管理人员。所以,从这些内容中,您可以了解到更高层次的应用理念,让您在选择和应用 IBM 系统时有一个更好的认识。
讨论
-
参与 developerWorks 博客 并加入 developerWorks 社区。
- 加入 developerWorks 中文社区。查看开发人员推动的博客、论坛、组和维基,并与其他 developerWorks 用户交流。
- 参与 AIX 和 UNIX® 论坛: