分类: LINUX
2008-05-02 20:01:14
您认为您拥有一个安全的 Linux® 系统吗?在安装和设置过程中按照最佳实践的提示是必须的,但是如果您没有设置正常的系统审计,就丢失了一半保险。本文讨论现有的一些工具,并提供了几个样例脚本来对真实环境中的处理实现自动化。
关于如何安装一个安全的 Linux 系统已经撰写了很多文章和书籍。但是为了确保满足安全性需求而安装系统之后,整个战役才打赢了一半。另外一半需要确保系统在整个生命周期中都可以满足安全性需求(并且您可以证明这一点)。这就意味着需要对系统进行周期性审计,才能确保不会出现问题。
系统审计需求
例程系统审计过程中需要验证的安全性需求应该与系统安装过程中使用的需求和安全性准则相同。这个 3 部分的 developerWorks 系列文章 “增强 Linux 的安全性” 向您简要介绍了如何安装一个非常安全的 Linux 系统。正常的系统审计也可以帮助提炼安装新机器时所使用的安全策略,因为它有助于关闭关于实际使用的子系统的反馈循环。
满足这些需求的第一组工具是系统审计和基于主机的入侵检测。本文着重介绍的是系统审计。基于主机的入侵检测系统有 tripwire、AIDE 和 Samhain,它们都可以检测出何时对文件系统进行了修改,因此对于确保系统仍然维持在已知状态来说是至关重要的一些工具。Linux Gazette 上有一篇有关使用这些工具的有趣文章 “Constructive Paranoia”(链接请参看下面的 参考资料)。
本文的重点是基于管理大型学术网络子网的系统管理员的真实需求而总结出的一些周期性的系统审计实践。这些管理员所学到的教训同样适用于企业 intranet 和那些希望防止自己的机器在蠕虫军队面前变成一具僵尸的家庭用户。管理员的系统需要周期性地进行随机的系统审计,在此过程中需要执行一些例行的审计操作(例如显示周期性查看的审计和系统日志,检查已经失效的用户帐号)。另外,系统管理员还需要解决以下问题:
这些 suid 文件是干什么用的?
确定系统中的 suid 和 sgid 文件 — 并对那些不需要的文件禁用这种权限 — 是安装安全系统的一条基本原则。这种任务很常见,find
手册页在它的例子中就列出了这个任务所使用的参数。清单 1 是一个执行典型的 find
命令的脚本,可以帮助回答 suid 文件执行什么功能,以及它属于哪个包;这样可以帮助管理员定位这些文件,并确定这些文件是应该保留在系统中还是应该删除。(您可以从本文后面 下载 一节的 zip 文件下载清单 1、3、4 的代码)。
清单 1. 搜索 suid/sgid 文件的精简后的样例输出
[root@localhost hpc]# ./find_setuids.pl / 04755 root /usr/X11R6/bin/cardinfo cardinfo - PCMCIA card monitor and control utility for X pcmcia-cardinfo-3.2.7-107.3 04755 root /usr/bin/opiepasswd opiepasswd - Change or set a user's password for the OPIE authentication system. Opie-2.4-544.1 04755 root /usr/bin/opiesu opiesu - Replacement su(1) program that uses OPIE challenges opie-2.4-544.1 04755 root /usr/bin/sudo sudo - execute a command as another user sudo-1.6.7p5-117.4 |
哪些文件系统包含人人可写的目录?
作为一名系统管理员,您可能会对人人可写的目录感兴趣,从而满足所有用户可写的文件系统应该使用 nosuid 属性进行挂载的需求。用户可写的目录包括用户的根目录,以及任何人人可写的目录。之所以有这种要求是为了防止创建其他用户或管理员可能会不经意执行的 suid 可执行程序。然而,如果在一个合法的 suid 可执行程序与一个人人可写的目录在同一个文件系统中,因此使用 nosuid 选项来挂载的,那么 suid 位就会被忽略,这个可执行程序也就无法正确执行。您也可能会考虑在自己的多用户系统中实现这种限制。
清单 1 中的脚本也会对每个普通文件系统进行测试,寻找人人可写的目录,并在输出结果末尾报告这个文件系统是否包含一个人人可写的目录。对于每个 suid/sgid 文件来说,它还报告这个文件是否在一个包含人人可写目录的文件系统中。
对人人可写目录的样例输出结果精简后如下所示:/ Contains both suid/sgid files and world writable directories.
系统使用了哪些网络端口?都用于什么目的?
有几种方法可以用来检测系统上使用了哪些端口。nmap、netstat 和 lsof 都是非常有用的工具。
- Nmap 是一个非常灵活的工具,它可以主动或被动地扫描远程(和本地)系统。
- Netstat 给出了有关本地系统的网络信息。默认情况下,它会显示打开的连接。
- Lsof 可以列出系统中的打开文件。它可以用来获取有关端口使用情况的信息,因为它还可以显示有关网络套接字的信息。
Kurt Seifried 维护了一个列有 8,457 个常用端口的清单。(这个端口清单的链接请参看后面的 参考资料。)您可以使用这些数据来帮助解释这个端口用于什么目的,如果防火墙关闭这个端口会产生什么影响。他还包含了有关特洛伊木马和根工具通常使用的端口的信息;例如,31337 通常会被 Back Orifice 使用,而 12345、12346 和 20034 都会由 netbus 使用。
清单 2 包含了一个使用 lsof 和 netstat 的脚本,用来以一种更容易阅读的格式显示系统的当前端口使用情况。
清单 2. port_scan.sh 的样例输出
[root@localhost hpc]# ./port_scan.sh
please wait...
PORT SERVICE LINK
22 sshd
http://www.seifried.org/security/ports/0/22.html
25 sendmail
http://www.seifried.org/security/ports/0/25.html
123 ntpd
http://www.seifried.org/security/ports/0/123.html
631 cupsd
http://www.seifried.org/security/ports/0/631.html
46336 <-> 22 ssh **
在清单 2 中,编号较小的端口(小于 1024)标识的是系统上运行的守护进程,除非被防火墙阻断,否则它们就会接收传入的信息。编号较大的端口 46336 给出了一个外发 ssh 连接,以及连接到另一端的端口(22)。这意味着阻塞这个临时端口上的外发通信会阻断诸如 ssh 之类的常用客户机程序。有关使用防火墙阻塞更高端口的影响的更详细内容,请参看 参考资料 中 Kurt 的端口清单 。
这些脚本和工具可以实时显示在某个时间点上的端口使用情况。即使有些端口现在没有使用,审计子系统可以用来查找已经使用了哪些端口(在审计日志文件记录的时间范围内)。将下面的审计规则添加到 /etc/audit.rules 中就可以记录对 bind 的调用情况。
-a entry,always -S socketcall -F a0=2
参数 -a entry,always
说明了在系统调用执行开始时总要调用的规则。 -S socketcall
说明了这个审计规则是用于 socketcall 系统调用的。这个 socketcall 系统调用在 i386 架构上是多元的,因此需要使用 -F a0=2
选项将所生成的审计记录仅仅限制在 bind 上。
其他架构对 bind 系统调用的处理方式不同,因此这些命令和脚本必须稍加修改才能处理 i386 之外的架构。审计事件可以记录为多条审计记录,它们使用一个共享序号关联在一起。ausearch 会使用序列号将相关记录关联在一起,并将它们作为一个组呈现出来。-i 标记请求使用数字值,例如在可能时可以将 saddr (IP 地址)和 uid (用户名)翻译成人们可以阅读的文本。
清单 3. ausearch 输出简化后的内容
# ausearch -i -sc socketcall
Abbreviated example output
----
type=SOCKETCALL msg=audit(11/20/2006 11:28:43.844:10) : nargs=3 a0=0
a1=b8004004 a2=10
type=SOCKADDR msg=audit(11/20/2006 11:28:43.844:10) : saddr=inet
host:127.0.0.1 serv:631
type=SYSCALL msg=audit(11/20/2006 11:28:43.844:10) : arch=i386
syscall=socketcall(bind) success=yes exit=0 a0=2 a1=bfffaca0 a2=b8000664
a3=1 items=0 pid=3340 auid=unknown(4294967295) uid=root gid=root euid=root
suid=root fsuid=root egid=root sgid=root fsgid=root comm=cupsd
exe=/usr/sbin/cupsd
----
type=SOCKETCALL msg=audit(11/20/2006 16:40:46.169:16) : nargs=3 a0=6
a1=b8056720 a2=10
type=SOCKADDR msg=audit(11/20/2006 16:40:46.169:16) : saddr=inet
host:192.0.34.166 serv:123
type=SYSCALL msg=audit(11/20/2006 16:40:46.169:16) : arch=i386
syscall=socketcall(bind) success=yes exit=0 a0=2 a1=bffff9a0 a2=b80004a8
a3=6 items=0 pid=3523 auid=unknown(4294967295) uid=root gid=root euid=root
suid=root fsuid=root egid=root sgid=root fsgid=root comm=ntpd
exe=/usr/sbin/ntpd
这个输出结果显示每个对于 bind 的调用都会生成 3 个审计记录。第一个记录类型是 SOCKETCALL 记录,它显示按条目传递给 bind 的参数个数和参数值。第二个记录类型是 SOCKADDR 记录,它以 IP 地址和所使用的端口形式给出了主机。第三个记录类型是 SYSCALL 记录,它显示对于 bind 的调用是否成功,退出的参数给出了进程 ID、所执行的文件、显示生成这个调用的进程的有效性和实际用户/组信息。对于我们的目的来说,最感兴趣的内容在 serv
中,这是 SOCKADDR 记录的一部分,它记录了所使用的端口,以及 SYSCALL 记录的 exe=
字段,这个字段说明了调用 bind 的程序是什么。
清单 4 包含了一个简单的脚本,它使用 sed 和 awk 将 ausearch 的输出压缩成只有不重复的(忽略时间)可执行程序和端口号字段。
清单 4. auportprint.sh 的样例输出
[root@localhost hpc]# ./auportprint.sh
22 /usr/sbin/sshd
123 /usr/sbin/ntpd
123 /usr/sbin/ntpdate
631 /usr/sbin/cupsd
原文链接:http://www.ibm.com/developerworks/cn/linux/l-security-audit.html