經過一段時間的琢磨,以及查找上網資料,雖然問題媒體沒有得到解決,但卻是算是找到了爲啥這樣不行的原因,也算是給這樣一個問題畫上了問好。
接着上一篇的文章分析,又做了如下嘗試:
-
懷疑使軟件的自帶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進程
https://blog.csdn.net/iteye_2225/article/details/82412714
https://www.cnblogs.com/g2thend/articles/11245139.html
https://blog.csdn.net/KgdYsg/article/details/89503457
測試結果:這一圈看下來,貌似都有關係,又都沒有直接關係,我無法驗證。。。
- 終於在一篇文章下面,給了我一個還算全面的認知
應用層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這樣進行的行爲