经过一段时间的琢磨,以及查找上网资料,虽然问题媒体没有得到解决,但却是算是找到了为啥这样不行的原因,也算是给这样一个问题画上了问好。

接着上一篇的文章分析,又做了如下尝试:

  • 怀疑使软件的自带shell问题,有可能是软件自己的shell和系统的shell变量是不互通的,LD_PRELOAD没有传递到软件shell里面,这个一听,感觉很靠谱啊,测试一下:
    因为也在做mongodb,mongodb是自带shell的,所以模仿mongo的shell看一下,mongo的shell又是如何实现的呢?去看了mongo的源码,原来如此,mongo源码分析请看;
    自己写了一个小的测试程序,进行测试
    测试结果:可以监控
  • 我有注意到,httpd的进程运行的apache用户权限,那么,是不是这个问题呢?
    每个用户都有自己的环境变量,一般我们修改环境变量都去修改/etc/profile,但是我到apache用户下面查看环境变量时,却没有我设置的环境变量,原来,环境变量的设置是有点问题的,/etc/profile改变的全局shell终端的环境变量,/etc/bashrc则修改的全部用户的环境变量。在/etc/bashrc中添加好环境变量,再次测试
linux环境变量的设置文件
/etc/profile 全局用户,应用于所有的Shell。
/$HOME/.profile 当前用户,应用于所有的Shell。
/etc/bash_bashrc 全局用户,应用于Bash Shell。
~/.bashrc 局部当前,应用于Bash Sell。

测试结果:所有终端手动操作可监控,httpd数据传输操作不可监控

  • 又注意到,httpd的启动方式和父进程貌似有点嫌疑,盘他
# ps -ef | grep httpd
root     27519 10015  0 04:00 pts/1    00:00:00 grep --color=auto httpd
root     30626     1  0 Mar23 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache   30627 30626  0 Mar23 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache   30628 30626  0 Mar23 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache   30629 30626  0 Mar23 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache   30630 30626  0 Mar23 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND
apache   30631 30626  0 Mar23 ?        00:00:00 /usr/sbin/httpd -DFOREGROUND

http被设计为一个独立运行的后台进程,它会建立一个处理请求的子进程或线程的池。

1.-DFOREGROUND选项的作用
-DFOREGROUND选项确实意味着Apache不会fork,但这并不意味着它附加到你的shell!
2.apache 用户的作用
这里发现进程的发起者居然都是apache,这是为了保护系统而产生的一个系统用户,该用户只负责Httpd守护进程操作,这样如果Httpd服务被入侵,而保护了操作系统。

3.父进程为1的httpd进程


测试结果:这一圈看下来,貌似都有关系,又都没有直接关系,我无法验证。。。

  • 终于在一篇文章下面,给了我一个还算全面的认知
应用层Preload Hook
  对于Preload的解释,详见[Preload Hook原理](#Preload Hook原理)。Preload Hook是指利用系统支持的preload能力,将模块自动注入进程实现hook。可以通过以下手段使用Preload技术:一种是环境变量配置(LD_PRELOAD);另一种是文件配置:(/etc/ld.so.preload)。
若使用命令行指定LD_PRELOAD则只影响该新进程及子进程;若写入全局环境变量则LD_PRELOAD对所有新进程生效;父进程可以控制子进程的环境变量从而取消preload
文件preload方式影响所有新进程且无法被取消
可以拦截到系统调用和普通库函数
实现和操作最为简单,只需要编写同名系统调用函数即可实现hook
可以使用动态调用方式或自定义实现方式绕过

看了这段解释,似乎能够解释为什么httpd的进程捕获不到

1.http启动之后,创建了子进程,并且是apache用户的进程,这个时候,数据接收发送都是通过这些子进程来处理,所以监控不到,
2.创建完子进程之后,httpd让自己init(进程id为1)接管,之后就没有动作了,所以不会有监控记录
3.前面还提到, -DFOREGROUND这个参数,可能有关系,但是我没有证据
4.

测试结果:LD_PRELOAD无法监控类似于httpd这样进行的行为

参考:Linux Preload Hook原理与实践