A. 如何選擇一個 linux Tracer
tracer 是一個高級的性能分析和診斷工具,但是不要讓這名詞唬住你,如果你使用過 strace 和tcpmp,其實你就已經使用過 tracer 了。系統 tracer 可以獲取更多的系統調用和數據包。它們通常能跟蹤任意的內核和應用程序。
有太多的 linux tracer 可以選擇。每一種都有其官方的(或非官方的)的卡通的獨角獸吉祥物,足夠撐起一台"兒童劇"了。
那麼我們應該使用哪個 tracer 呢?
我會為兩類讀者回答這個問題,大部分人和性能/內核工程師。過一段時間這些可能會發生變化,我會持續跟進並補充,大概會一年更新一次。
多數人
多數人 (開發者,系統管理員,開發管理者,運維人員,評測人員,等等) 不關心系統追蹤器的細節。下面是對於追蹤器你應該知道和做的:
1. 使用perf_events分析CPU性能
使用 perf_events 做 CPU 性能分析。性能指標可以使用flame graph 等工具做可視化。
git clone --depth 1 https://github.com/brendangregg/FlameGraph
perf record -F 99 -a -g -- sleep 30
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > perf.svg
Linux perf_events (又稱 "perf",同命令名) 是 Linux 用戶的官方追蹤器和性能分析器。內置於內核代碼,有很好維護(近來獲得快速增強),通常通過 linux 命令行工具包添加。
perf 有很多功能,如果只能推薦一個,我選擇 CPU 性能分析。盡陵友管這只是采樣,而不是從技術上追蹤事件。最難的部分是獲取完整的棧和信息,我為 java 和 node.js 做的一個演講 Linux Profiling at Netflix中已經說過這個問題
2.了解其他的Tracer
正如我一個朋友說的:「你不需要知道如何操作 X 射線機器,但是一旦你吞了一枚硬幣,你得知道這得去做 X 射線」,你應該了解各種 tracer 都能做什麼,這樣就能在你工作中真正需要 tracer 的時候,你既可以選擇稍後學習使用,也可以雇相應的人來完成。
簡短來說:幾乎所有的東西都可以使用 tracer 來尺手槐進行分析和跟蹤。如,文件系統,網路處理器,硬體驅動器,全部的應用程序。可以看一下我的個人網站上關於 ftrace的文章,還有我寫的薯螞關於perf_events 文檔介紹,可以做為一個追蹤(或者性能分析)的例子。
3. 尋求前端支持工具
如果你正想買一個能支持跟蹤 Linux 的性能分析工具(有許多賣這類工具的公司)。想像一下,只需要直接點擊一下界面就能「洞察」整個系統內核,包括隱藏的不同堆棧位置的熱圖,我在Monitorama talk 中介紹了一個這樣帶圖形界面的工具。
我開源了一些我自己開發的前端工具,盡管只是 CLI (命令行界面)而不是(圖形界面)。這些工具也會讓人們更加快速容易的使用 tracer。比如下面的例子,用我的 perf_tool,跟蹤一個新進程:
# ./execsnoopTracing exec()s. Ctrl-C to end.
PID PPID ARGS
22898 22004 man ls
22905 22898 preconv -e UTF-8
22908 22898 pager -s
22907 22898 nroff -mandoc -rLL=164n -rLT=164n -Tutf8
[...]
在 Netflix 上,我們創建了一個 Vector,一個分析工具的實例同時也是 Linux 上的 tracer 的最終前端。
致性能或內核工程師
我們的工作變的越來越困難,很多的人會問我們怎麼樣去追蹤,哪種路徑可以用!為了正確理解一個路徑,你經常需要花上至少100個小時才能做到。理解所有的 linux 路徑去做出理性的決定是一個浩大的工程。(我可能是唯一一個接近做到這件事情的人)
這里是我的建議,可以二選其一:
A) 選中一個全能的路徑,並且使它標准化,這將涉及花費大量的時間去弄清楚它在測試環境中的細微差別和安全性。我現在推薦 SystemTap 的最新版本(ie,從源代碼構建)。我知道有些公司已經選用 LTTng,而且他們用的很好,盡管它不是非常的強大(雖然它更安全)。Sysdig 可以成為另一個候選如果它可以增加追蹤點或者 kprobes。
B) 遵循我上面提供的流程圖,它將意味著盡可能更多的使用 ftrace 或者 perf_event, eBPF 會得到整合,之後其他的路徑像 SystemTap/LTTng 會去填補這個空白。這就是我目前在 Netflix 做的工作。
tracer 的評論:
1. ftrace
我喜歡用 ftrace,它是內核 hacker 的首選,內置於系統內核,可以使用跟蹤點(靜態檢查點),能調用內核 kprobes 和 uprobes 調試工具。並且提供幾個這樣的功能:帶可選過濾器和參數的事件追蹤功能;在內核中進行統計的事件計數和定時功能;還有函數流程遍歷的功能。可以看一下內核代碼中 ftrace.txt 例子了解一下。ftrace 由 /sys 控制,僅支持單一的 root 用戶使用(但是你可以通過緩沖區實例破解以支持多用戶)。某些時候 Ftrace 的操作界面非常繁瑣,但是的確非常「hack」,而且它有前端界面。Steven Rostedt,ftace 的主要作者,創建了 trace-cmd 命令工具,而我創建了 perf 的工具集。我對這個工具最大的不滿就是它不可編程。舉例來說,你不能保存和獲取時間戳,不能計算延遲,不能把這些計算結果保存成直方圖的形式。你需要轉儲事件至用戶級別,並且花一些時間去處理結果。ftrace 可以通過 eBPF 變成可編程的。
2.perf_events
perf_events 是 Linux 用戶的主要跟蹤工具,它內置在內核源碼中,通常通過 linux-tools-commom 加入。也稱「perf」,同前端工具名稱,通常用來跟蹤和轉儲信息到一個叫做 perf.data 的文件中,perf.data 文件相當於一個動態的緩沖區,用來保存之後需要處理的結果。ftrace 能做到的,perf_events 大都也可以做到,perf-events 不能做函數流程遍歷,少了一點兒「hack」勁兒(但是對於安全/錯誤檢查有更好的支持)。它可以進行 CPU 分析和性能統計,用戶級堆棧解析,也可以使用對於跟蹤每行局部變數產生的調試信息。它也支持多用戶並發操作。和 ftrace 一樣也不支持可編程。如果要我只推薦一款 tracer,那一定是 perf 了。它能解決眾多問題,並且它相對較安全。
3. eBPF
extended Berkeley Packet Filter(eBPF)是一個可以在事件上運行程序的高效內核虛擬機(JIT)。它可能最終會提供 ftrace 和 perf_events 的內核編程,並強化其他的 tracer。這是 Alexei Starovoitov 目前正在開發的,還沒有完全集成,但是從4.1開始已經對一些優秀的工具有足夠的內核支持了,如塊設備I/O的延遲熱圖。可參考其主要作者 Alexei Starovoitov 的BPF slides和eBPF samples。
4. SystemTap
SystemTap 是最強大的tracer。它能做所有事情,如概要分析,跟蹤點,探針,uprobes(來自SystemTap),USDT和內核編程等。它將程序編譯為內核模塊,然後載入,這是一種獲取安全的巧妙做法。它也是從tree發展而來,在過去有很多問題(多的可怕)。很多不是 SystemTap 本身的錯——它常常是第一個使用內核追蹤功能,也是第一個碰到 bug 的。SystemTap 的最新版本好多了(必須由源代碼編譯),但是很多人仍然會被早期版本嚇到。如果你想用它,可先在測試環境中使用,並與irc.freenode.net上 的 #systemtap 開發人員交流。(Netflix 有容錯機制,我們已經使用了 SystemTap,但是可能我們考慮的安全方面的問題比你們少。)我最大的不滿是,它似乎認為你有常常沒有的內核 debug 信息。實際上沒有它也能做很多事情,但是缺少文檔和例子(我必須自己全靠自己開始學習)。
5. LTTng
LTTng 優化了事件採集,這比其他 tracers 做得好。它從 tree 發展而來,它的核心很簡單:通過一組小規模的固定指令集將事件寫入追蹤緩沖區,這種方式使它安全、快速,缺點是它沒有內核編碼的簡單途徑。我一直聽說這不是一個大問題,因為盡管需要後期處理,它也已經優化到可以充分的度量。此外,它還首創了一個不同的分析技術,更多對所有關注事件的黑盒記錄將稍後以 GUI 的方式進行研究。我關心的是前期沒有考慮到要錄制的事件缺失問題如何解決,但我真正要做的是花更多時間來看它在實踐中用的怎麼樣。這是我花的時間最少的一個 tracer(沒有什麼特殊原因)。
6. Ktap
ktap 在過去是一款前景很好的 tracer,它使用內核中的 lua 虛擬機處理,在沒有調試信息的情況下在嵌入式設備上運行的很好。它分為幾個步驟,並在有一段時間似乎超過了 Linux 上所有的追蹤器。然後 eBPF 開始進行內核集成,而 ktap 的集成在它可以使用 eBPF 替代它自己的虛擬機後才開始。因為 eBPF 仍將持續集成幾個月,ktap 開發者要繼續等上一段時間。我希??今年晚些時候它能重新開發。
7. dtrace4linux
dtrace4linux 主要是 Paul Fox 一個人在業余時間完成的,它是 Sun DTrace 的 Linux 版本。它引入矚目,還有一些 provider 可以運行,但是從某種程度上來說還不完整,更多的是一種實驗性的工具(不安全)。我認為,顧忌到許可問題,人們會小心翼翼的為 dtrace4linux 貢獻代碼:由於當年 Sun 開源DTrace 使用的是 CDDL 協議,而 dtrace4linux 也不大可能最終進入 Linux kernel。Paul 的方法很可能會使其成為一個 add-on。我很樂意看到 Linux 平台上的 DTrace 和這個項目的完成,我認為當我加入 Netflix 後將會花些時間來協助完成這個項目。然而,我還是要繼續使用內置的 tracers,如 ftrace 和 perf_events。
8.OL DTrace
Oracle Linux DTrace為了將 DTrace 引入 Linux,特別是 Oracle Linux,做出了很大的努力。這些年來發布的多個版本表明了它的穩定進展。開發者們以一種對這個項目的前景看好的態度談論著改進 DTrace 測試套件。很多有用的 provider 已經完成了,如:syscall, profile, sdt, proc, sched 以及 USDT。我很期待 fbt(function boundary tracing, 用於內核動態跟蹤)的完成,它是 Linux 內核上非常棒的 provider。OL DTrace 最終的成功將取決於人們對運行 Oracle Linux(為技術支持付費)有多大興趣,另一方面取決於它是否完全開源:它的內核元件是開源的,而我沒有看到它的用戶級別代碼。
9. sysdig
sysdig是一個使用類tcpmp語法來操作系統事件的新tracer,它使用lua提交進程。它很優秀,它見證了系統跟蹤領域的變革。它的局限性在於它只在當前進行系統調用,在提交進行時將所有事件轉儲為用戶級別。你可以使用系統調用做很多事情,然而我還是很希望它能支持跟蹤點、kprobe和uprobe。我還期待它能支持eBPF做內核摘要。目前,sysdig開發者正在增加容器支持。留意這些內容。
延伸閱讀
我關於 tracer 的工作包括:
ftrace:我的 perf-tools工具集(參考實例目錄);我在 lwn.net 上的 關於ftrace的文章;LISA14的發言;還有帖子:函數計數, iosnoop,opensnoop,execsnoop,TCP轉發, uprobes 以及USDT。
perf_evenets:我的網頁 perf_events實例;SCALE上的發言Netflix的Linux性能分析;還有帖子CPU采樣,靜態追蹤點,熱點圖,計數,內核行追蹤,off-CPU時間圖。
eBPF:帖子eBPF:邁出一小步,和一些BPF工具(我需要發布更多)。
SystemTap:我很久以前寫了一篇有點過期的帖子使用SystemTap。最近,我發布了一些工具systemtap-lwtools來演示如何在沒有內核診斷信息的情況下使用SystemTap。
LTTng:我只花了一點時間,還不足以發表任何內容。
ktap:我的網頁ktap實例包含一些早期版本的單行小程序和腳本。
dtrace4linux:我在系統性能一書中給出了一些實例,並曾經開發了一些小的修復程序,如timestamps。
OL DTrace:由於它直接由DTrace轉變而來,很多我早期關於DTrace的工作都有相關性(如果在這里給出鏈接的話就太多了,可以在我的主頁上搜索)。當它更完善時,我會開發一些特殊工具。
sysdig:我向 fileslower 和 subsecond offset spectrogram 貢獻了代碼。
其他:我寫了關於strace 的注意事項。
請不要有更多的 tracer!如果你想知道為什麼 Linux 不僅僅只有一個 tracer,或者只用本身的DTrace,你可以在我的演講稿從DTrace到Linux中找到答案,從28張幻燈片開始。
感謝Deirdré Straughan的編輯,以及與 General Zoi 的小馬寶莉創作者一起創作的 tracing 小馬。
B. 如何選擇一個 Linux Tracer
tracer 是一個高級的性能分析和診斷工具,但是不要讓這名詞唬住你,如果你使用過 strace 和tcpmp,其實你就已經使用過 tracer 了。系統 tracer 可以獲取更多的系統調用和數據包。它們通常能跟蹤任意的內核和應用程序。
有太多的 linux tracer 可以選擇。每一種都有其官方的(或非官方的)的卡通的獨角獸吉祥物,足夠撐起一台"兒童劇"了。
那麼我們應該使用哪個 tracer 呢?
我會為兩類讀者回答這個問題,大部分人和性能/內核工程師。過一段時間這些可能會發生變化,我會持續跟進並補充,大概會一年更新一次。
多數人
多數人 (開發者,系統管理員,開發管理者,運維人員,評測人員,等等) 不關心系統追蹤器的細節。下面是對於追蹤器你應該知道和做的:
1. 使用perf_events分析CPU性能
使用 perf_events 做 CPU 性能分析。性能指標可以使用flame graph 等工具做可視化。
git clone --depth 1 https://github.com/brendangregg/FlameGraph
perf record -F 99 -a -g -- sleep 30
perf script | ./FlameGraph/stackcollapse-perf.pl | ./FlameGraph/flamegraph.pl > perf.svg
Linux perf_events (又稱 "perf",同命令名) 是 Linux 用戶的官方追蹤器和性能分析器。內置於內核代碼,有很好維護(近來獲得快速增強),通常通過 linux 命令行工具包添加。
perf 有很多功能,如果只能推薦一個,我選擇 CPU 性能分析。盡管這只是采樣,而不是從技術上追蹤事件。最難的部分是獲取完整的棧和信息,我為 java 和 node.js 做的一個演講 Linux Profiling at Netflix中已經說過這個問題
2.了解其他的Tracer
正如我一個朋友說的:「你不需要知道如何操作 X 射線機器,但是一旦你吞了一枚硬幣,你得知道這得去做 X 射線」,你應該了解各種 tracer 都能做什麼,這樣就能在你工作中真正需要 tracer 的時候,你既可以選擇稍後學習使用,也可以雇相應的人來完成。
簡短來說:幾乎所有的東西都可以使用 tracer 來進行分析和跟蹤。如,文件系統,網路處理器,硬體驅動器,全部的應用程序。可以看一下我的個人網站上關於 ftrace的文章,還有我寫的關於perf_events 文檔介紹,可以做為一個追蹤(或者性能分析)的例子。
3. 尋求前端支持工具
如果你正想買一個能支持跟蹤 Linux 的性能分析工具(有許多賣這類工具的公司)。想像一下,只需要直接點擊一下界面就能「洞察」整個系統內核,包括隱藏的不同堆棧位置的熱圖,我在Monitorama talk 中介紹了一個這樣帶圖形界面的工具。
我開源了一些我自己開發的前端工具,盡管只是 CLI (命令行界面)而不是(圖形界面)。這些工具也會讓人們更加快速容易的使用 tracer。比如下面的例子,用我的 perf_tool,跟蹤一個新進程:
# ./execsnoopTracing exec()s. Ctrl-C to end.
PID PPID ARGS
22898 22004 man ls
22905 22898 preconv -e UTF-8
22908 22898 pager -s
22907 22898 nroff -mandoc -rLL=164n -rLT=164n -Tutf8
[...]
在 Netflix 上,我們創建了一個 Vector,一個分析工具的實例同時也是 Linux 上的 tracer 的最終前端。
致性能或內核工程師
我們的工作變的越來越困難,很多的人會問我們怎麼樣去追蹤,哪種路徑可以用!為了正確理解一個路徑,你經常需要花上至少100個小時才能做到。理解所有的 linux 路徑去做出理性的決定是一個浩大的工程。(我可能是唯一一個接近做到這件事情的人)
這里是我的建議,可以二選其一:
A) 選中一個全能的路徑,並且使它標准化,這將涉及花費大量的時間去弄清楚它在測試環境中的細微差別和安全性。我現在推薦 SystemTap 的最新版本(ie,從源代碼構建)。我知道有些公司已經選用 LTTng,而且他們用的很好,盡管它不是非常的強大(雖然它更安全)。Sysdig 可以成為另一個候選如果它可以增加追蹤點或者 kprobes。
B) 遵循我上面提供的流程圖,它將意味著盡可能更多的使用 ftrace 或者 perf_event, eBPF 會得到整合,之後其他的路徑像 SystemTap/LTTng 會去填補這個空白。這就是我目前在 Netflix 做的工作。
tracer 的評論:
1. ftrace
我喜歡用 ftrace,它是內核 hacker 的首選,內置於系統內核,可以使用跟蹤點(靜態檢查點),能調用內核 kprobes 和 uprobes 調試工具。並且提供幾個這樣的功能:帶可選過濾器和參數的事件追蹤功能;在內核中進行統計的事件計數和定時功能;還有函數流程遍歷的功能。可以看一下內核代碼中 ftrace.txt 例子了解一下。ftrace 由 /sys 控制,僅支持單一的 root 用戶使用(但是你可以通過緩沖區實例破解以支持多用戶)。某些時候 Ftrace 的操作界面非常繁瑣,但是的確非常「hack」,而且它有前端界面。Steven Rostedt,ftace 的主要作者,創建了 trace-cmd 命令工具,而我創建了 perf 的工具集。我對這個工具最大的不滿就是它不可編程。舉例來說,你不能保存和獲取時間戳,不能計算延遲,不能把這些計算結果保存成直方圖的形式。你需要轉儲事件至用戶級別,並且花一些時間去處理結果。ftrace 可以通過 eBPF 變成可編程的。
2.perf_events
perf_events 是 Linux 用戶的主要跟蹤工具,它內置在內核源碼中,通常通過 linux-tools-commom 加入。也稱「perf」,同前端工具名稱,通常用來跟蹤和轉儲信息到一個叫做 perf.data 的文件中,perf.data 文件相當於一個動態的緩沖區,用來保存之後需要處理的結果。ftrace 能做到的,perf_events 大都也可以做到,perf-events 不能做函數流程遍歷,少了一點兒「hack」勁兒(但是對於安全/錯誤檢查有更好的支持)。它可以進行 CPU 分析和性能統計,用戶級堆棧解析,也可以使用對於跟蹤每行局部變數產生的調試信息。它也支持多用戶並發操作。和 ftrace 一樣也不支持可編程。如果要我只推薦一款 tracer,那一定是 perf 了。它能解決眾多問題,並且它相對較安全。
3. eBPF
extended Berkeley Packet Filter(eBPF)是一個可以在事件上運行程序的高效內核虛擬機(JIT)。它可能最終會提供 ftrace 和 perf_events 的內核編程,並強化其他的 tracer。這是 Alexei Starovoitov 目前正在開發的,還沒有完全集成,但是從4.1開始已經對一些優秀的工具有足夠的內核支持了,如塊設備I/O的延遲熱圖。可參考其主要作者 Alexei Starovoitov 的BPF slides和eBPF samples。
4. SystemTap
SystemTap 是最強大的tracer。它能做所有事情,如概要分析,跟蹤點,探針,uprobes(來自SystemTap),USDT和內核編程等。它將程序編譯為內核模塊,然後載入,這是一種獲取安全的巧妙做法。它也是從tree發展而來,在過去有很多問題(多的可怕)。很多不是 SystemTap 本身的錯——它常常是第一個使用內核追蹤功能,也是第一個碰到 bug 的。SystemTap 的最新版本好多了(必須由源代碼編譯),但是很多人仍然會被早期版本嚇到。如果你想用它,可先在測試環境中使用,並與irc.freenode.net上 的 #systemtap 開發人員交流。(Netflix 有容錯機制,我們已經使用了 SystemTap,但是可能我們考慮的安全方面的問題比你們少。)我最大的不滿是,它似乎認為你有常常沒有的內核 debug 信息。實際上沒有它也能做很多事情,但是缺少文檔和例子(我必須自己全靠自己開始學習)。
5. LTTng
LTTng 優化了事件採集,這比其他 tracers 做得好。它從 tree 發展而來,它的核心很簡單:通過一組小規模的固定指令集將事件寫入追蹤緩沖區,這種方式使它安全、快速,缺點是它沒有內核編碼的簡單途徑。我一直聽說這不是一個大問題,因為盡管需要後期處理,它也已經優化到可以充分的度量。此外,它還首創了一個不同的分析技術,更多對所有關注事件的黑盒記錄將稍後以 GUI 的方式進行研究。我關心的是前期沒有考慮到要錄制的事件缺失問題如何解決,但我真正要做的是花更多時間來看它在實踐中用的怎麼樣。這是我花的時間最少的一個 tracer(沒有什麼特殊原因)。
6. Ktap
ktap 在過去是一款前景很好的 tracer,它使用內核中的 lua 虛擬機處理,在沒有調試信息的情況下在嵌入式設備上運行的很好。它分為幾個步驟,並在有一段時間似乎超過了 Linux 上所有的追蹤器。然後 eBPF 開始進行內核集成,而 ktap 的集成在它可以使用 eBPF 替代它自己的虛擬機後才開始。因為 eBPF 仍將持續集成幾個月,ktap 開發者要繼續等上一段時間。我希??今年晚些時候它能重新開發。
7. dtrace4linux
dtrace4linux 主要是 Paul Fox 一個人在業余時間完成的,它是 Sun DTrace 的 Linux 版本。它引入矚目,還有一些 provider 可以運行,但是從某種程度上來說還不完整,更多的是一種實驗性的工具(不安全)。我認為,顧忌到許可問題,人們會小心翼翼的為 dtrace4linux 貢獻代碼:由於當年 Sun 開源DTrace 使用的是 CDDL 協議,而 dtrace4linux 也不大可能最終進入 Linux kernel。Paul 的方法很可能會使其成為一個 add-on。我很樂意看到 Linux 平台上的 DTrace 和這個項目的完成,我認為當我加入 Netflix 後將會花些時間來協助完成這個項目。然而,我還是要繼續使用內置的 tracers,如 ftrace 和 perf_events。
8.OL DTrace
Oracle Linux DTrace為了將 DTrace 引入 Linux,特別是 Oracle Linux,做出了很大的努力。這些年來發布的多個版本表明了它的穩定進展。開發者們以一種對這個項目的前景看好的態度談論著改進 DTrace 測試套件。很多有用的 provider 已經完成了,如:syscall, profile, sdt, proc, sched 以及 USDT。我很期待 fbt(function boundary tracing, 用於內核動態跟蹤)的完成,它是 Linux 內核上非常棒的 provider。OL DTrace 最終的成功將取決於人們對運行 Oracle Linux(為技術支持付費)有多大興趣,另一方面取決於它是否完全開源:它的內核元件是開源的,而我沒有看到它的用戶級別代碼。
9. sysdig
sysdig是一個使用類tcpmp語法來操作系統事件的新tracer,它使用lua提交進程。它很優秀,它見證了系統跟蹤領域的變革。它的局限性在於它只在當前進行系統調用,在提交進行時將所有事件轉儲為用戶級別。你可以使用系統調用做很多事情,然而我還是很希望它能支持跟蹤點、kprobe和uprobe。我還期待它能支持eBPF做內核摘要。目前,sysdig開發者正在增加容器支持。留意這些內容。
延伸閱讀
我關於 tracer 的工作包括:
ftrace:我的 perf-tools工具集(參考實例目錄);我在 lwn.net 上的 關於ftrace的文章;LISA14的發言;還有帖子:函數計數, iosnoop,opensnoop,execsnoop,TCP轉發, uprobes 以及USDT。
perf_evenets:我的網頁 perf_events實例;SCALE上的發言Netflix的Linux性能分析;還有帖子CPU采樣,靜態追蹤點,熱點圖,計數,內核行追蹤,off-CPU時間圖。
eBPF:帖子eBPF:邁出一小步,和一些BPF工具(我需要發布更多)。
SystemTap:我很久以前寫了一篇有點過期的帖子使用SystemTap。最近,我發布了一些工具systemtap-lwtools來演示如何在沒有內核診斷信息的情況下使用SystemTap。
LTTng:我只花了一點時間,還不足以發表任何內容。
ktap:我的網頁ktap實例包含一些早期版本的單行小程序和腳本。
dtrace4linux:我在系統性能一書中給出了一些實例,並曾經開發了一些小的修復程序,如timestamps。
OL DTrace:由於它直接由DTrace轉變而來,很多我早期關於DTrace的工作都有相關性(如果在這里給出鏈接的話就太多了,可以在我的主頁上搜索)。當它更完善時,我會開發一些特殊工具。
sysdig:我向 fileslower 和 subsecond offset spectrogram 貢獻了代碼。
其他:我寫了關於strace 的注意事項。
請不要有更多的 tracer!如果你想知道為什麼 Linux 不僅僅只有一個 tracer,或者只用本身的DTrace,你可以在我的演講稿從DTrace到Linux中找到答案,從28張幻燈片開始。
感謝Deirdré Straughan的編輯,以及與 General Zoi 的小馬寶莉創作者一起創作的 tracing 小馬。
C. 我的嗅探器程序無法分析數據包的類型
包
0. 前言
來源:《Computer Security》A Hands-on Approach — Wenliang Du
所有的代碼/文檔見github:https://github.com/da1234cao/computer_security
chapter 12 Packet sniffing and spoffing.
這一章有點硬核。知識點不難,但對socket編程有點要求。
我看過《unix網路編程》第一卷 前五章 ,背景知識還是相當欠缺。這章內容雖然看完,基本明白,但距離實際動手完成一個簡單的有線/無線嗅探工具還挺遠。本文,暫時僅僅看看書上的嗅探實現。
1. 摘要與總結
首先介紹了網卡的工作原理,嗅探需要網卡的工作模式(雜亂模式/監控模式)。
為了提數凱游早過濾過濾不需要的數據包,介紹了BPF。
接著用三種方式:普通套接字,原生套接字,pcap API,遞進的講述了包的嗅探過程。
2. 包(Packet)的接收
2.1 網卡
參考文章:網卡工作原理詳解 、關於網路的混雜模式 、實戰無線網路分析(篇一)無線監聽
簡單了解下:
網卡(Network Interface Card,NIC)是一塊被設計用來允許計算機在計算機網路上進行通訊的計算機硬體。每塊網卡有一個硬體地址,被稱為MAC地址;網卡孫衫接入網路,使得用戶可以通過電纜或無線相互連接;用戶A要發送信息給B,通過電纜或者無線進行廣播;每一塊網卡都將廣播的內容拷貝到自己的網卡內存中,檢查頭部信息中的MAC地址,判斷是否是發送給自己的。如果是則將其拷貝進入內存,否則丟棄;因為MAC唯一,所以最後只有B接受了用戶A的信息。
維基網路:混雜模式(promiscuous mode)。一般計算機網卡都工作在非混雜模式下,此時網卡只接受來自網路埠的目的地址指向自己的數據。當網卡工作在混雜模式下時,網卡將來自介面的所有數據都捕獲並交給相應的驅動程序。網卡的混雜模式一般在網路管理員分析網路數據作為網路故障診斷手段時用到,同時這個模式也被網路黑客利用來作為網路數據竊聽的入口。在Linux操作系統中設置網卡混雜模式時需要管理員許可權。在Windows操作系統和Linux操作系統中都有使用混雜模式的抓包工具,比如著名的開源軟體Wireshark。
監控模式(monitor mode)。 類似於有線網路的混雜模式。 無線網卡在監視模式下運行時支持嗅探。 與乙太網不同,無線設備面臨附近其他設備的干擾。 這將嚴重阻礙網路連接的性能。 為解決此問題,WIFI設備在不同的信道上傳輸數據。接入點將附近的設備連接到不同的信道,以減少它們之間的干擾影響。 Wifi網卡還設計為在整個可用帶寬和通道的片上進行通信。 將這些卡置於監視模式時,它們將捕獲802. 1I幀,這些幀在它們正在偵聽的通道上傳輸。 這意味著,與乙太網不同,無線網卡可能會丟失同一網路上的信息,因為它位於不同的信道上。 大多數無線網卡不支持監視器模式或製造商禁用了該模式。
2.2 (BSD Packet Filter)BPF
參考文章:BPF與eBPF
這個參考文章我沒懂。目前大概知道怎麼回事就好。後面使用pcap API會用到這里的概念。
嗅探網路流量時,嗅探器只對薯銷某些類型的數據包感興趣,例如TCP數據包或DNS查詢數據包,這是很常見的。系統可以將所有捕獲的數據包提供給嗅探器程序,後者可以丟棄不需要的數據包。這是非常低效的,因為處理這些不需要的數據包並將其從內核傳送到嗅探器應用程序需要花費時間。當有很多不需要的數據包時,浪費的時間相當可觀。最好盡早過濾這些不需要的數據包。
隨著對數據包捕獲的需求的增加,Unix操作系統定義了BSD數據包過濾器(BSD Packet Filter,BPF)以支持較低級別的過濾。 BPF允許用戶空間程序將過濾器附加到套接字,這實際上是告訴內核盡早丟棄不需要的數據包。過濾器通常使用布爾運算符以人類可讀的格式編寫,並被編譯為偽代碼並傳遞給BPF驅動程序。然後由BPF偽機(一個專門為數據包過濾設計的內核級狀態機)解釋該低級代碼。
3. 包的嗅探
3.1 通常套接字編程接收包
/**
* 作用:將進入伺服器所有IP的9090埠的UDP內容,輸出。
*
* 准備:
* 一個套接字描述符:scoket函數,指定期望的通信協議類型
* 一個監聽套接字:指定協議族,ip,埠
* bind:將一個本地協議地址賦予一個套接字(描述符)
* recvfrom:接受經指定的socket 傳來的數據,放入buf --》准備個buffer,一個客戶端套接字,套接字長度
*
* 頭文件:
* netinet/in.h 定義了ip地址結構 struct sockaddr_in (struct in_addr作為sockaddr_in 的成員)
* 還有函數 htons等,以及一些宏。
* sys/socket.h 定義了一些列的socket API函數 如
* socket(),bind() listen() , send() ,sendmsg(),setsockopt(),等等。
* unistd.h close函數
*
* 驗證:echo "Hello World\!" | nc -4u 127.0.0.1 9090
*/
#include <stdio.h>
#include <string.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <errno.h>
#include <unistd.h>
int main(void){
int sock;
struct sockaddr_in server;
int client_len;
struct sockaddr_in client;
char buf[1000];
// IPV4,數據包套接字,UDP傳輸協議
sock = socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP);
if(sock <= 0){
perror("error in socket");
return -1;
}
// 用這個初始化為零,比memset函數少一個參數
// sockaddr_in結構體中sin_zero,還沒用;整個結構體用之前,我們全部初始化為零
// IPv4協議族,監聽該伺服器上所有IP的9090埠
// 按照網路標准轉化位元組序
bzero(&server,sizeof(server));
server.sin_family = AF_INET;
server.sin_addr.s_addr = htonl(INADDR_ANY);
server.sin_port = htons(9090);
// 將一個本地協議地址賦予一個套接字(描述符)
if( bind(sock,(struct sockaddr *)&server,sizeof(server)) < 0){
perror("error in bind");
return -1;
}
while (1){
bzero(buf,sizeof(buf));
// 進入一個慢系統調用;
recvfrom(sock,buf,sizeof(buf)-1,0,(struct sockaddr *)&client,&client_len);
printf("%s",buf);
}
close(sock);
return 0;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
3.2 使用原生套接字接收包