aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--.gitignore1
-rw-r--r--README.md549
-rw-r--r--imgs/all.drawio67
-rw-r--r--imgs/listener.drawio106
-rw-r--r--listener/audit.go16
-rw-r--r--listener/deal.go35
-rw-r--r--listener/global.go20
-rw-r--r--listener/godo.go37
-rw-r--r--listener/mongo.go15
-rw-r--r--listener/organize.go20
-rw-r--r--notes.md318
11 files changed, 1127 insertions, 57 deletions
diff --git a/.gitignore b/.gitignore
index 336d320..5d9b70a 100644
--- a/.gitignore
+++ b/.gitignore
@@ -12,3 +12,4 @@ old/go.*
12!logs/*.log 12!logs/*.log
13 13
14__debug_bin* 14__debug_bin*
15*.svg \ No newline at end of file
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..bd0dbf8
--- /dev/null
+++ b/README.md
@@ -0,0 +1,549 @@
1# 项目背景
2
3随着 k8s/云原生等技术日渐普及,docker 容器在生产中的应用愈加广泛。由于 docker 并不是一个完整的操作系统,使用的内核依然是宿主机内核,则在 docker 实际使用过程中,可能会遭受攻击或产生泄露,从而威胁其他 docker 或宿主机。因而我们需要对 docker 内部的进程行为、文件修改等进行监视,在出现问题后便于回溯。
4
5# 设计思路
6
7## 整体设计
8
9项目整体采用 MVC 的设计方式,设计思路如下图所示:
10
11<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="550px" height="450px" viewBox="-0.5 -0.5 789 561" content="&lt;mxfile&gt;&lt;diagram id=&quot;I_XTTxZs5cPDDl4HmgJE&quot; name=&quot;第 1 页&quot;&gt;7Vldb5swFP01kbaHTYADSR6btN0eWmlSpK19dIMD1gzOjGnIfv1sbPNlqtJ8NG21p+Dra+N77jmXCxmBRVJ8Y3AT39IQkZHnhMUIXI48z/XdifiRlp2yBL6nDBHDoXaqDUv8F2mjo605DlHWcuSUEo43beOKpila8ZYNMka3bbc1Je27bmCELMNyBYlt/YVDHivr1JvU9u8IR7G5sxvM1EwCjbOOJIthSLcNE7gagQWjlKurpFggIsEzuKh110/MVgdjKOVDFmjcHyHJdWwjLyBi6XxNxQ4CG7hSE8GfXB5qvqAJXomJJUwz8XO7rKdkPHxH2v5yny9ZmcIL4eBON0XpWi8KIvl7g9O8EA6/EUslXdQpxMnVQZSTBq26icdonoZIBuOK6W2MOVpu1JG3gnvCFvOE6GkdK2IcFU/i5VZZEPRFNEGc7YSLWTDWidPMnRhKbmseBMYnbnFAG6HmXlTtXadHXOgM9WdrbGWL4IyjFDGD1wMzUH2KaEg/HwaYhP4aJpjIaO3EKwctT3d6GoTHvo2wG/QhPD0CwiZLLUF0IERpeCGLiBitCMwygcphqKEC8zsxcPT1feP6smgOdmaQirjumoN7ffNyUC8qR2aVigSFVnHr5EZES3OmdW8A4JBFiDd4aGeQIQI5fmzv3pcNvfQHxWWN0Zn3OpkPJp2EqlPpVc2i1tkIPLeRisXaqCRHFc8wvrgWX/RDhzKbOAL5G/ggqhuYMyRqInwop5w2fyDBUSrJJbIilA3mUk9YPH0u9ESCw1Au3Fef+oT67vXD6DndOgemfbAI+55KrybCr57/ch26/3V4Xh0CizIwD7E8DKHRh1Oi91pKnJ1ViXsIsfVA1DscXYpjW4rg0OLYLyF/0umGuk3OcC36rY0qbR5fi57dQ+F0TbMPp8LZK6mw5y1tjYnE4t1192B6zu7eC/YsZ5lQB39LVa4ubCdsOHo6jqfKXCN9fk/2jO3Qahh02DPbsxqOnc5G3bfzI1bDicW5nxht36N4A3+AeMHJxHvOXsRtarRS7MtU6pxEpQbvpkoV586l0rH/TKsxVKVBp/nxwclUCuyeJaFpRC/tT45ZDDfyMoQcZuI1H71NsXZLnBf0iNXrE2s3XfuIFQx4hTdAwvJjyZsEsfqkbxjo2CD2dStT/8UQimH92V8xuP7zBFz9Aw==&lt;/diagram&gt;&lt;/mxfile&gt;">
12 <defs />
13 <g>
14 <rect x="40" y="450" width="640" height="110" rx="16.5" ry="16.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
15 <g transform="translate(-0.5 -0.5)">
16 <switch>
17 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
18 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 638px; height: 1px; padding-top: 505px; margin-left: 41px;">
19 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
20 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
21 <font style="font-size: 18px;" face="Comic Sans MS">
22 Linux kernel
23 </font>
24 </div>
25 </div>
26 </div>
27 </foreignObject>
28 <text x="360" y="509" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
29 Linux kernel
30 </text>
31 </switch>
32 </g>
33 <rect x="40" y="190" width="160" height="180" rx="24" ry="24" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
34 <g transform="translate(-0.5 -0.5)">
35 <switch>
36 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
37 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 280px; margin-left: 41px;">
38 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
39 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
40 listener
41 <br />
42 (godo)
43 </div>
44 </div>
45 </div>
46 </foreignObject>
47 <text x="120" y="285" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
48 listener...
49 </text>
50 </switch>
51 </g>
52 <path d="M 40 450 L 40 376.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
53 <path d="M 40 371.12 L 43.5 378.12 L 40 376.37 L 36.5 378.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
54 <g transform="translate(-0.5 -0.5)">
55 <switch>
56 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
57 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 411px; margin-left: 41px;">
58 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
59 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
60 connector
61 </div>
62 </div>
63 </div>
64 </foreignObject>
65 <text x="41" y="416" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
66 connector
67 </text>
68 </switch>
69 </g>
70 <path d="M 200 450 L 200 376.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
71 <path d="M 200 371.12 L 203.5 378.12 L 200 376.37 L 196.5 378.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
72 <g transform="translate(-0.5 -0.5)">
73 <switch>
74 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
75 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 411px; margin-left: 201px;">
76 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
77 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
78 audit log
79 </div>
80 </div>
81 </div>
82 </foreignObject>
83 <text x="201" y="416" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
84 audit log
85 </text>
86 </switch>
87 </g>
88 <path d="M 120 190 L 294.7 73.53" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
89 <path d="M 299.07 70.62 L 295.19 77.42 L 294.7 73.53 L 291.3 71.59 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
90 <g transform="translate(-0.5 -0.5)">
91 <switch>
92 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
93 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 131px; margin-left: 210px;">
94 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
95 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
96 infos
97 </div>
98 </div>
99 </div>
100 </foreignObject>
101 <text x="210" y="136" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
102 infos
103 </text>
104 </switch>
105 </g>
106 <rect x="280" y="190" width="160" height="180" rx="24" ry="24" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
107 <g transform="translate(-0.5 -0.5)">
108 <switch>
109 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
110 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 158px; height: 1px; padding-top: 280px; margin-left: 281px;">
111 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
112 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
113 filter
114 </div>
115 </div>
116 </div>
117 </foreignObject>
118 <text x="360" y="285" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
119 filter
120 </text>
121 </switch>
122 </g>
123 <path d="M 360 183.63 L 360 146.37" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
124 <path d="M 360 188.88 L 356.5 181.88 L 360 183.63 L 363.5 181.88 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
125 <path d="M 360 141.12 L 363.5 148.12 L 360 146.37 L 356.5 148.12 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
126 <rect x="550" y="190" width="130" height="180" rx="19.5" ry="19.5" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
127 <g transform="translate(-0.5 -0.5)">
128 <switch>
129 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
130 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 128px; height: 1px; padding-top: 280px; margin-left: 551px;">
131 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
132 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
133 Viewer
134 </div>
135 </div>
136 </div>
137 </foreignObject>
138 <text x="615" y="285" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
139 Viewer
140 </text>
141 </switch>
142 </g>
143 <path d="M 420 70 L 609.58 186.66" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
144 <path d="M 614.05 189.41 L 606.25 188.73 L 609.58 186.66 L 609.92 182.76 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
145 <path d="M 300 18 C 300 -6 420 -6 420 18 L 420 122 C 420 146 300 146 300 122 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
146 <path d="M 300 18 C 300 36 420 36 420 18 M 300 27 C 300 45 420 45 420 27 M 300 36 C 300 54 420 54 420 36" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
147 <g transform="translate(-0.5 -0.5)">
148 <switch>
149 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
150 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 92px; margin-left: 301px;">
151 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
152 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
153 mongoDB
154 </div>
155 </div>
156 </div>
157 </foreignObject>
158 <text x="360" y="97" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
159 mongoDB
160 </text>
161 </switch>
162 </g>
163 <path d="M 727 325 C 727 291 727 274 757 274 C 737 274 737 240 757 240 C 777 240 777 274 757 274 C 787 274 787 291 787 325 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
164 </g>
165</svg>
166
167项目主要分为信息采集、信息过滤、数据库、信息展示四个模块,其工作方式如下:
168
169- 信息采集模块,在各宿主机上安装、并**以 root 权限启动**,负责监听由 Linux 内核发出的 netlink connector 消息、audit 审计消息,将其整理为有关进程的、有关文件的数据,送入数据库中。
170- 在使用时,用信息过滤模块连接数据库,该模块将从数据库中取出所有的消息并过滤无关内容,得到以 docker 守护进程为根的进程树;并在此树的基础上,对数据库中关于文件的记录进行过滤与整理。完成后,将过滤得到的数据送入数据库。
171- 信息展示模块,简要地展示过滤得到的、有关 docker 的数据。
172
173## 信息采集
174
175<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="900px" height="250px" viewBox="-0.5 -0.5 1161 321" content="&lt;mxfile&gt;&lt;diagram id=&quot;bYij1YhiqdmEnY_ocicr&quot; name=&quot;第 1 页&quot;&gt;7VrLcuI4FP0alp3yAz9YBpLMLNLVXcViepbCFkYV22KEeKS/vq8sydiWKQgY4lCzAevKkqV7zj3SlT1wJ9nuL4aWi+80xunAseLdwH0aOI7jDofwJyzv0uJ7jjQkjMTSZO8NU/IbK6OlrGsS41XtRk5pysmyboxonuOI12yIMbqt3zanaf2pS5RgwzCNUGpa/yExX0hr6AR7+9+YJAv9ZNsfyZoM6ZvVTFYLFNNtxeQ+D9wJo5TLq2w3walwnvaLbPdyoLYcGMM5P6WB68kWG5Su1eQGjp9C2/GcQhcwQv6upu3/t6a64tuqAOURbrDDJQA73tcLj6Ko3mZCMxJBxRTlK/j7Pq3e7ifiP6N5QuOZfjyMWY5A1ip3lYNxwHNLcRkjjlacMrgebxeE4+lSPnwL3APbgmcplOyyjw1mHO8O+ssuUQD6Ypphzt7hFt3A0hxU1A1Vcbvnga3BXVQ44GojUtxLyr738MCFQugAWkFv0LIfoCIlK47zIvrEzwKL+a1jAiOZ6IHNmG6yRCvRW7ZKROjTbf5RqJeMRhj6OAr0DEVvCaPrPP6x5inJcYcEGHk1/G27hQB+CwFGXeAfHsP/Y1CeRRcJkiPw/8ESlIt7HYvhaBOX6JK8YATegFfFY2fCg5zBGECOCRWUydfZDLOvSIGhYx2lQLlUdU6BUW8o4AoKvLZIwBtmebHiq/WXskIPrAQXZJhT9gbTxDuhEyVHJgUGhUJAL9kXlgjXq0tEiXuVH4F3HX4Mrd4sEUPBjyeM0mLqMPOKICi5KEBfr0TVEmYAIJMUF/oxp3sZ+fimoA80CNzjMmF7LTLhBF3wwOmNTrySfL2ryMJpUBag4Fjhcf2d3bdT4LKuBtewBa6GR3AeP4rkBUpRCkoJYNWcINz5gjKSihmYYMobVDJlh1AWCvxLNRbX/8K19eB4qvgkPGPpwrsu5DC1X9WCbBZ4urxvV5R0QzkfHBupVQMhmDNdM8XNksccMVg+qttgE0mGU8TJpt5/Gyqq6U9KikjYNdDVDAgbwMpxqVbVpKrRUSnCuqOmsMvJGB0VJCnncxpvzPxNbcCtlCYmhcD7r2gGUeiOGYbYRbOiyqozCaUkyQXNABnYo7ljEVkE8t9HVZGROBYNP865QTUxV08flOnwkQiWUXIB8CeHo3/IrZc5NMVz3uLOGeWcZr1xp1ZE1aR777alsZ8jdsF5YufcUOxGVxG78IhE9VHrzOxX7/PuTecuXeBOjkQzm8yx2Ae/mcc3lWTurkTwgK+vLYJeW6L2OSJ4ngZeRwL1EWdNAsN2iCo787Y8StsuVEo3qCuc0zzJPVUqjXOjZuLQnVTq9yk9IFe/0gl9fFal19AatNLrQt4EQUdLbHisow554xq8eVZHNve1wsoAucEK6/Unse/XXle/y/hKkWh01Dwh6DASzcT+TiPxVjm9Z+b0nxOJ9hlhaH/1fNNp7qLOPVwbukc66jAGzXOKMuFUryjuLBb9W8Vi24vsF+FcMM4v1rh+ZZiHvHrtDNM3N3OftfU4OQl4sGALWtt+uJZzRPuK0k/MCHhIRNMlgmi1CKJ3nU1J2JEghsc66k4QfXMzW7y2vUsxlOFzAzH0277B63mK8GD5QSNhd4L/47QvcWpuddWHFdEC5eBq43D3LgP4UkIcCGAo7j/QlejsP3N2n/8A&lt;/diagram&gt;&lt;/mxfile&gt;">
176 <defs />
177 <g>
178 <path d="M 1040 40 C 1040 -13.33 1160 -13.33 1160 40 L 1160 280 C 1160 333.33 1040 333.33 1040 280 Z" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
179 <path d="M 1040 40 C 1040 80 1160 80 1160 40 M 1040 60 C 1040 100 1160 100 1160 60 M 1040 80 C 1040 120 1160 120 1160 80" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
180 <g transform="translate(-0.5 -0.5)">
181 <switch>
182 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
183 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 118px; height: 1px; padding-top: 210px; margin-left: 1041px;">
184 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
185 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
186 <font face="Comic Sans MS" style="font-size: 18px;">
187 mongodb
188 </font>
189 </div>
190 </div>
191 </div>
192 </foreignObject>
193 <text x="1100" y="214" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
194 mongodb
195 </text>
196 </switch>
197 </g>
198 <rect x="225" y="30" width="160" height="90" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
199 <path d="M 241 30 L 241 120 M 369 30 L 369 120" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
200 <g transform="translate(-0.5 -0.5)">
201 <switch>
202 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
203 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 126px; height: 1px; padding-top: 75px; margin-left: 241px;">
204 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
205 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
206 <font face="Comic Sans MS" style="font-size: 18px;">
207 1. listen to the audit,
208 <br />
209 pass msg down
210 </font>
211 </div>
212 </div>
213 </div>
214 </foreignObject>
215 <text x="304" y="79" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
216 1. listen to the audi...
217 </text>
218 </switch>
219 </g>
220 <rect x="450" y="30" width="210" height="90" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
221 <path d="M 471 30 L 471 120 M 639 30 L 639 120" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
222 <g transform="translate(-0.5 -0.5)">
223 <switch>
224 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
225 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 166px; height: 1px; padding-top: 75px; margin-left: 473px;">
226 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
227 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
228 <font style="font-size: 18px;" face="Comic Sans MS">
229 2. Organize recvd msg into events by transection number
230 </font>
231 </div>
232 </div>
233 </div>
234 </foreignObject>
235 <text x="556" y="79" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
236 2. Organize recvd msg into e...
237 </text>
238 </switch>
239 </g>
240 <rect x="385" y="210" width="275" height="90" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
241 <path d="M 413 210 L 413 300 M 632 210 L 632 300" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
242 <g transform="translate(-0.5 -0.5)">
243 <switch>
244 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
245 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 218px; height: 1px; padding-top: 255px; margin-left: 414px;">
246 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
247 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
248 <font style="font-size: 18px;" face="Comic Sans MS">
249 3. Listen to the kernel connector, gets fork/exit events, pass them down
250 </font>
251 </div>
252 </div>
253 </div>
254 </foreignObject>
255 <text x="523" y="259" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
256 3. Listen to the kernel connector, g...
257 </text>
258 </switch>
259 </g>
260 <rect x="760" y="30" width="150" height="270" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
261 <path d="M 775 30 L 775 300 M 895 30 L 895 300" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
262 <g transform="translate(-0.5 -0.5)">
263 <switch>
264 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
265 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 117px; height: 1px; padding-top: 165px; margin-left: 776px;">
266 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
267 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
268 <font face="Comic Sans MS" style="font-size: 18px;">
269 4. Deal with events recvd, push pid/file info into db
270 </font>
271 </div>
272 </div>
273 </div>
274 </foreignObject>
275 <text x="835" y="169" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
276 4. Deal with events...
277 </text>
278 </switch>
279 </g>
280 <rect x="0" y="30" width="100" height="270" rx="15" ry="15" fill="rgb(255, 255, 255)" stroke="rgb(0, 0, 0)" pointer-events="all" />
281 <g transform="translate(-0.5 -0.5)">
282 <switch>
283 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
284 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 98px; height: 1px; padding-top: 165px; margin-left: 1px;">
285 <div data-drawio-colors="color: rgb(0, 0, 0); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
286 <div style="display: inline-block; font-size: 12px; font-family: Helvetica; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; white-space: normal; overflow-wrap: normal;">
287 <font style="font-size: 18px;" face="Comic Sans MS">
288 Linux kernel
289 </font>
290 </div>
291 </div>
292 </div>
293 </foreignObject>
294 <text x="50" y="169" fill="rgb(0, 0, 0)" font-family="Helvetica" font-size="12px" text-anchor="middle">
295 Linux kernel
296 </text>
297 </switch>
298 </g>
299 <path d="M 100 97.5 L 218.63 97.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
300 <path d="M 223.88 97.5 L 216.88 101 L 218.63 97.5 L 216.88 94 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
301 <g transform="translate(-0.5 -0.5)">
302 <switch>
303 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
304 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 98px; margin-left: 164px;">
305 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
306 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
307 audit log
308 </div>
309 </div>
310 </div>
311 </foreignObject>
312 <text x="164" y="104" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
313 audit log
314 </text>
315 </switch>
316 </g>
317 <g transform="translate(-0.5 -0.5)">
318 <switch>
319 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
320 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 96px; margin-left: 102px;">
321 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
322 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
323 audit
324 </div>
325 </div>
326 </div>
327 </foreignObject>
328 <text x="102" y="96" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px">
329 audit
330 </text>
331 </switch>
332 </g>
333 <path d="M 100 232.5 L 378.63 232.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
334 <path d="M 383.88 232.5 L 376.88 236 L 378.63 232.5 L 376.88 229 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
335 <g transform="translate(-0.5 -0.5)">
336 <switch>
337 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
338 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 233px; margin-left: 244px;">
339 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
340 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
341 process
342 </div>
343 </div>
344 </div>
345 </foreignObject>
346 <text x="244" y="239" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
347 process
348 </text>
349 </switch>
350 </g>
351 <g transform="translate(-0.5 -0.5)">
352 <switch>
353 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
354 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 231px; margin-left: 102px;">
355 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
356 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
357 netlink
358 <br />
359 connector
360 </div>
361 </div>
362 </div>
363 </foreignObject>
364 <text x="102" y="231" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px">
365 netlink...
366 </text>
367 </switch>
368 </g>
369 <path d="M 385 75 L 443.63 75" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
370 <path d="M 448.88 75 L 441.88 78.5 L 443.63 75 L 441.88 71.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
371 <path d="M 660 232.5 L 753.63 232.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
372 <path d="M 758.88 232.5 L 751.88 236 L 753.63 232.5 L 751.88 229 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
373 <g transform="translate(-0.5 -0.5)">
374 <switch>
375 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
376 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 233px; margin-left: 712px;">
377 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
378 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
379 Events
380 </div>
381 </div>
382 </div>
383 </foreignObject>
384 <text x="712" y="239" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
385 Events
386 </text>
387 </switch>
388 </g>
389 <path d="M 660 97.5 L 753.63 97.5" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
390 <path d="M 758.88 97.5 L 751.88 101 L 753.63 97.5 L 751.88 94 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
391 <g transform="translate(-0.5 -0.5)">
392 <switch>
393 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
394 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 98px; margin-left: 712px;">
395 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
396 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
397 Events
398 </div>
399 </div>
400 </div>
401 </foreignObject>
402 <text x="712" y="104" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
403 Events
404 </text>
405 </switch>
406 </g>
407 <path d="M 100 300 L 378.63 300" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
408 <path d="M 383.88 300 L 376.88 303.5 L 378.63 300 L 376.88 296.5 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
409 <g transform="translate(-0.5 -0.5)">
410 <switch>
411 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
412 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 301px; margin-left: 244px;">
413 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
414 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
415 process info
416 </div>
417 </div>
418 </div>
419 </foreignObject>
420 <text x="244" y="306" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
421 process info
422 </text>
423 </switch>
424 </g>
425 <g transform="translate(-0.5 -0.5)">
426 <switch>
427 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
428 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe flex-end; justify-content: unsafe flex-start; width: 1px; height: 1px; padding-top: 299px; margin-left: 102px;">
429 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: left;">
430 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
431 /proc fs
432 </div>
433 </div>
434 </div>
435 </foreignObject>
436 <text x="102" y="299" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px">
437 /proc fs
438 </text>
439 </switch>
440 </g>
441 <path d="M 910 97.5 L 1039.99 96.68" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
442 <path d="M 1045.24 96.65 L 1038.26 100.19 L 1039.99 96.68 L 1038.22 93.19 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
443 <g transform="translate(-0.5 -0.5)">
444 <switch>
445 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
446 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 98px; margin-left: 978px;">
447 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
448 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
449 pid info
450 </div>
451 </div>
452 </div>
453 </foreignObject>
454 <text x="978" y="103" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
455 pid info
456 </text>
457 </switch>
458 </g>
459 <path d="M 910 232.5 L 1041.67 232.63" fill="none" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="stroke" />
460 <path d="M 1046.92 232.64 L 1039.92 236.13 L 1041.67 232.63 L 1039.93 229.13 Z" fill="rgb(0, 0, 0)" stroke="rgb(0, 0, 0)" stroke-miterlimit="10" pointer-events="all" />
461 <g transform="translate(-0.5 -0.5)">
462 <switch>
463 <foreignObject pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" style="overflow: visible; text-align: left;">
464 <div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 1px; height: 1px; padding-top: 233px; margin-left: 980px;">
465 <div data-drawio-colors="color: rgb(0, 0, 0); background-color: rgb(255, 255, 255); " style="box-sizing: border-box; font-size: 0px; text-align: center;">
466 <div style="display: inline-block; font-size: 18px; font-family: &quot;Comic Sans MS&quot;; color: rgb(0, 0, 0); line-height: 1.2; pointer-events: all; background-color: rgb(255, 255, 255); white-space: nowrap;">
467 file change
468 <br />
469 info
470 </div>
471 </div>
472 </div>
473 </foreignObject>
474 <text x="980" y="239" fill="rgb(0, 0, 0)" font-family="Comic Sans MS" font-size="18px" text-anchor="middle">
475 file change...
476 </text>
477 </switch>
478 </g>
479 </g>
480 <switch>
481 <g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility" />
482 <a transform="translate(0,-5)" xlink:href="https://www.diagrams.net/doc/faq/svg-export-text-problems" target="_blank">
483 <text text-anchor="middle" font-size="10px" x="50%" y="100%">
484 Text is not SVG - cannot display
485 </text>
486 </a>
487 </switch>
488</svg>
489
490信息采集模块对应本项目下的 listener 目录,主要负责收集 Linux-kernel 发出的 audit 系统审计消息、netlink connector 进程消息。分为四个协程,各自功能如下:
491
492- 1 号协程,**接收来自内核的 audit 审计消息**,传递给 2 号协程
493- 2 号,拿到 1 号发来的消息。对于 audit 审计消息而言,一个事件会被拆分为多条消息发送,但使用相同的时间戳、事务号。因而 2 号将收到的**消息使用正则表达式进行简单解析,并用哈希表按照事务号存储**,直到收到 eoe(本事件到此结束),**将 hash 表中整理得到的 Event 事件发送给 4 号协程**。
494- 3 号,接收来自内核的 connector 消息,获取其中的进程事件(fork/exit)及进程号(ppid/parentTgid/pid/tgid),并通过/proc 文件系统查询 pid 对应的命令行参数 args、当前运行目录 cwd、根文件系统 rootfs、docker id(从 cgroup 查看),**整理为 Event 事件,发送给 4 号协程**
495- 4 号,**接收 Event 事件,判断其类型,分别处理**。代码中事件类型主要有进程复制、进程退出、进程执行文件(execve)、文件打开、文件关闭、写文件、切换根系统(pivot_root)等几种。
496
497## 信息过滤
498
499### 进程过滤与优化
500
501首先,由于 listener 模块在插入时采用了多线程,可能出现同一个进程的两条消息被并行处理、数据库中出现两条记录,因而第一步,是**将相同 pid 的多条记录合并为一条**。
502
503现在开始考虑清洗数据的问题。Docker 是一个 C/S 架构的服务,因而我们真正关心的 docker 有关进程一定是 docker 守护进程的后代(虽然可能作为孤儿进程被 systemd 收养)。**过滤进程数据,只需要构建以守护进程为根的进程树**。在信息收集过程中,我们对 docker 守护进程(`/usr/bin/dockerd`)进行了特殊记录,标记了该 pid 的`star=true`。在过滤过程中,主要工作即围绕该 pid 展开。
504
505- 我们记录的条目以 pid 区分,而这里的 pid 实质上指的是 task id、可能是线程,tgid 才是 task group id 应当理解为进程。因而,为了构建进程树,最简单的办法是将各个 pid 按照 tgid 区分,成为一个新的结构;这些结构代表着进程、是进程树的节点,因而称为 tgidNode。在此过程中,我们也可以整理得到每个 tgid 的所有子代 tgid 编号。
506- 整理出来若干 tgidNode,从标记了 star 的 tgidNode 开始,采用广度优先遍历,得到整个进程树上的所有 tgidNode
507
508接着,进行**数据优化**:
509
510- 同一个 docker id 使用相同的 rootfs。在记录中,同一个 docker id 只有一个进程进行过 pivot_root,因而需要加以处理。
511- 同一个进程(tgid)的不同线程(pid)可能 ppid/parentTgid 不一样。原因为,在进程(pid==tgid)创建的时候,父进程一定还在;但过一会创建线程的时候,原父进程可能已死、该进程已经被 systemd 收容,所以记录的 ppid/parentTgid 不对。为解决该问题,需要检查每个 pid,如果存在该问题则进行修正,防止在按 pid 溯源时出错。
512- 部分 pid 可能并未收到对应的退出消息。为了部分地解决该问题,我们将进程退出时间(也就是 pid==tgid 的 pid 的退出时间)记录为没有 exit timestamp 的 pid 的退出时间。这样的补全是为了接下来在处理文件时使用。
513
514### 文件过滤
515
516众所周知,Linux 环境下,进程操作文件使用的是系统调用+文件描述符。
517
518在记录的时候,由于 Linux 下进程是通过 open 系统调用,传入文件名和权限,得到文件描述符,使用、关闭时都是操作文件描述符而非文件名,所以记录时应当把已经关闭的和尚未关闭的区分开来。写文件时,在已经打开但尚未关闭的文件里按照 pid+fd 查找,记录写入时间;关闭时,将记录从 fd 表删除,加上关闭时间后存储到关闭的文件里。
519
520但在整理时,二者都有写入记录,应该等同视之。将两张表的所有记录提取出来进行筛选,只保留 pid 在进程树上的那些文件记录;而后,对于尚未关闭的文件,查询 pid 退出时间,如有记录,则认为该文件在 pid 退出时才关闭。
521
522最后,将处理得到的 tgidNode 构成的进程树、筛选之后的文件,全部记录到数据库里。
523
524## 信息展示
525
526现在已经获取了进程树和文件修改的详细记录,展示即可。本项目目前是在过滤完成之后,直接由过滤模块将进程树、进程详细信息、文件修改记录全部打印到标准输出。
527
528# 编译与运行
529
530本项目的编译运行较为简单。
531
532在将本项目克隆下来后:
533
534```bash
535git submodule --init
536cd listener
537go build -o godo
538cd ../filter
539go build -o filter
540```
541
542编译完成后,将 godo 放置在宿主机上运行,**godo 必须以 root 权限运行**。有若干命令行参数,可以通过`sudo ./godo -h`查看。注意:
543
544- 指定参数使用等号,如`-diag`参数表示将内核原始 audit 消息输出到指定文件,使用时即`sudo ./godo -diag=1.txt`
545- 默认的数据库是本机的 mongodb,端口 27017;如要连接别的数据库,需要使用`-mongo`参数指定其链接,格式为`ip:port`。本处并未设置 mongodb 的用户名、密码,而是放开了权限直接登录。使用的数据库名为"test"。
546- backlog 大小默认为 1GB,最好只大不小。以字节为单位。
547- filter 放置在数据库所在的机器上,连接数据库。使用的数据库为 test,写入的数据库为 cooked。
548
549而filter程序则直接放置在**数据库所在机器上**,在需要回溯的时候,直接运行filter程序(数据库没有账号密码控制),会输出进程树、每个进程的参数,及最终受改变的文件列表。 \ No newline at end of file
diff --git a/imgs/all.drawio b/imgs/all.drawio
new file mode 100644
index 0000000..acfa35d
--- /dev/null
+++ b/imgs/all.drawio
@@ -0,0 +1,67 @@
1<mxfile host="65bd71144e">
2 <diagram id="I_XTTxZs5cPDDl4HmgJE" name="第 1 页">
3 <mxGraphModel dx="1038" dy="446" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
4 <root>
5 <mxCell id="0"/>
6 <mxCell id="1" parent="0"/>
7 <mxCell id="2" value="&lt;font face=&quot;Comic Sans MS&quot; style=&quot;font-size: 18px;&quot;&gt;Linux kernel&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
8 <mxGeometry x="140" y="710" width="640" height="110" as="geometry"/>
9 </mxCell>
10 <mxCell id="4" value="listener&lt;br&gt;(godo)" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Comic Sans MS;fontSize=18;" vertex="1" parent="1">
11 <mxGeometry x="140" y="450" width="160" height="180" as="geometry"/>
12 </mxCell>
13 <mxCell id="10" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=0;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="4">
14 <mxGeometry relative="1" as="geometry">
15 <mxPoint x="240" y="670" as="sourcePoint"/>
16 <mxPoint x="340" y="670" as="targetPoint"/>
17 </mxGeometry>
18 </mxCell>
19 <mxCell id="11" value="connector" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="10">
20 <mxGeometry relative="1" as="geometry"/>
21 </mxCell>
22 <mxCell id="12" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=0.25;exitY=0;exitDx=0;exitDy=0;entryX=1;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="2" target="4">
23 <mxGeometry relative="1" as="geometry">
24 <mxPoint x="240" y="670" as="sourcePoint"/>
25 <mxPoint x="340" y="670" as="targetPoint"/>
26 </mxGeometry>
27 </mxCell>
28 <mxCell id="13" value="audit log" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="12">
29 <mxGeometry relative="1" as="geometry"/>
30 </mxCell>
31 <mxCell id="19" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="4" target="30">
32 <mxGeometry relative="1" as="geometry">
33 <mxPoint x="570" y="480" as="sourcePoint"/>
34 <mxPoint x="345" y="340" as="targetPoint"/>
35 </mxGeometry>
36 </mxCell>
37 <mxCell id="20" value="infos" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="19">
38 <mxGeometry relative="1" as="geometry"/>
39 </mxCell>
40 <mxCell id="22" value="filter" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Comic Sans MS;fontSize=18;" vertex="1" parent="1">
41 <mxGeometry x="380" y="450" width="160" height="180" as="geometry"/>
42 </mxCell>
43 <mxCell id="26" value="" style="endArrow=classic;startArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=0.5;exitY=0;exitDx=0;exitDy=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="22" target="30">
44 <mxGeometry width="50" height="50" relative="1" as="geometry">
45 <mxPoint x="560" y="490" as="sourcePoint"/>
46 <mxPoint x="400" y="410" as="targetPoint"/>
47 </mxGeometry>
48 </mxCell>
49 <mxCell id="27" value="Viewer" style="rounded=1;whiteSpace=wrap;html=1;fontFamily=Comic Sans MS;fontSize=18;" vertex="1" parent="1">
50 <mxGeometry x="650" y="450" width="130" height="180" as="geometry"/>
51 </mxCell>
52 <mxCell id="29" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;" edge="1" parent="1" source="30" target="27">
53 <mxGeometry width="50" height="50" relative="1" as="geometry">
54 <mxPoint x="455" y="340" as="sourcePoint"/>
55 <mxPoint x="670" y="530" as="targetPoint"/>
56 </mxGeometry>
57 </mxCell>
58 <mxCell id="30" value="mongoDB" style="shape=datastore;whiteSpace=wrap;html=1;fontFamily=Comic Sans MS;fontSize=18;" vertex="1" parent="1">
59 <mxGeometry x="400" y="260" width="120" height="140" as="geometry"/>
60 </mxCell>
61 <mxCell id="32" value="" style="shape=actor;whiteSpace=wrap;html=1;fontFamily=Comic Sans MS;fontSize=18;" vertex="1" parent="1">
62 <mxGeometry x="827" y="500" width="60" height="85" as="geometry"/>
63 </mxCell>
64 </root>
65 </mxGraphModel>
66 </diagram>
67</mxfile> \ No newline at end of file
diff --git a/imgs/listener.drawio b/imgs/listener.drawio
new file mode 100644
index 0000000..3c7408e
--- /dev/null
+++ b/imgs/listener.drawio
@@ -0,0 +1,106 @@
1<mxfile host="65bd71144e">
2 <diagram id="bYij1YhiqdmEnY_ocicr" name="第 1 页">
3 <mxGraphModel dx="2344" dy="652" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
4 <root>
5 <mxCell id="0"/>
6 <mxCell id="1" parent="0"/>
7 <mxCell id="35" value="&lt;font style=&quot;font-size: 18px;&quot; face=&quot;Comic Sans MS&quot;&gt;mongodb&lt;/font&gt;" style="shape=datastore;whiteSpace=wrap;html=1;" vertex="1" parent="1">
8 <mxGeometry x="1010" y="80" width="120" height="320" as="geometry"/>
9 </mxCell>
10 <mxCell id="37" value="&lt;font style=&quot;font-size: 18px;&quot; face=&quot;Comic Sans MS&quot;&gt;1. listen to the audit,&lt;br&gt;pass msg down&lt;/font&gt;" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;" vertex="1" parent="1">
11 <mxGeometry x="195" y="110" width="160" height="90" as="geometry"/>
12 </mxCell>
13 <mxCell id="38" value="&lt;font face=&quot;Comic Sans MS&quot; style=&quot;font-size: 18px;&quot;&gt;2. Organize recvd msg into events by transection number&lt;/font&gt;" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;" vertex="1" parent="1">
14 <mxGeometry x="420" y="110" width="210" height="90" as="geometry"/>
15 </mxCell>
16 <mxCell id="39" value="&lt;font face=&quot;Comic Sans MS&quot; style=&quot;font-size: 18px;&quot;&gt;3. Listen to the kernel connector, gets fork/exit events, pass them down&lt;/font&gt;" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;" vertex="1" parent="1">
17 <mxGeometry x="355" y="290" width="275" height="90" as="geometry"/>
18 </mxCell>
19 <mxCell id="40" value="&lt;font style=&quot;font-size: 18px;&quot; face=&quot;Comic Sans MS&quot;&gt;4. Deal with events recvd, push pid/file info into db&lt;/font&gt;" style="shape=process;whiteSpace=wrap;html=1;backgroundOutline=1;" vertex="1" parent="1">
20 <mxGeometry x="730" y="110" width="150" height="270" as="geometry"/>
21 </mxCell>
22 <mxCell id="42" value="&lt;font face=&quot;Comic Sans MS&quot; style=&quot;font-size: 18px;&quot;&gt;Linux kernel&lt;/font&gt;" style="rounded=1;whiteSpace=wrap;html=1;" vertex="1" parent="1">
23 <mxGeometry x="-30" y="110" width="100" height="270" as="geometry"/>
24 </mxCell>
25 <mxCell id="44" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="37">
26 <mxGeometry relative="1" as="geometry">
27 <mxPoint x="100" y="180" as="sourcePoint"/>
28 <mxPoint x="240" y="190" as="targetPoint"/>
29 </mxGeometry>
30 </mxCell>
31 <mxCell id="45" value="audit log" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="44">
32 <mxGeometry relative="1" as="geometry"/>
33 </mxCell>
34 <mxCell id="46" value="audit" style="edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="44">
35 <mxGeometry x="-1" relative="1" as="geometry"/>
36 </mxCell>
37 <mxCell id="47" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="39">
38 <mxGeometry relative="1" as="geometry">
39 <mxPoint x="80" y="190" as="sourcePoint"/>
40 <mxPoint x="240" y="190" as="targetPoint"/>
41 </mxGeometry>
42 </mxCell>
43 <mxCell id="48" value="process" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="47">
44 <mxGeometry relative="1" as="geometry"/>
45 </mxCell>
46 <mxCell id="49" value="netlink&lt;br&gt;connector" style="edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="47">
47 <mxGeometry x="-1" relative="1" as="geometry"/>
48 </mxCell>
49 <mxCell id="50" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=0;entryY=0.5;entryDx=0;entryDy=0;" edge="1" parent="1" source="37" target="38">
50 <mxGeometry width="50" height="50" relative="1" as="geometry">
51 <mxPoint x="370" y="220" as="sourcePoint"/>
52 <mxPoint x="420" y="170" as="targetPoint"/>
53 </mxGeometry>
54 </mxCell>
55 <mxCell id="52" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0;entryY=0.75;entryDx=0;entryDy=0;" edge="1" parent="1" source="39" target="40">
56 <mxGeometry relative="1" as="geometry">
57 <mxPoint x="770" y="190" as="sourcePoint"/>
58 <mxPoint x="870" y="190" as="targetPoint"/>
59 </mxGeometry>
60 </mxCell>
61 <mxCell id="53" value="Events" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="52">
62 <mxGeometry relative="1" as="geometry"/>
63 </mxCell>
64 <mxCell id="54" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0;entryY=0.25;entryDx=0;entryDy=0;" edge="1" parent="1" source="38" target="40">
65 <mxGeometry relative="1" as="geometry">
66 <mxPoint x="770" y="190" as="sourcePoint"/>
67 <mxPoint x="770" y="180" as="targetPoint"/>
68 </mxGeometry>
69 </mxCell>
70 <mxCell id="55" value="Events" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="54">
71 <mxGeometry relative="1" as="geometry"/>
72 </mxCell>
73 <mxCell id="56" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=1;exitDx=0;exitDy=0;entryX=0;entryY=1;entryDx=0;entryDy=0;" edge="1" parent="1" source="42" target="39">
74 <mxGeometry relative="1" as="geometry">
75 <mxPoint x="270" y="280" as="sourcePoint"/>
76 <mxPoint x="430" y="280" as="targetPoint"/>
77 </mxGeometry>
78 </mxCell>
79 <mxCell id="57" value="process info" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="56">
80 <mxGeometry relative="1" as="geometry"/>
81 </mxCell>
82 <mxCell id="58" value="/proc fs" style="edgeLabel;resizable=0;html=1;align=left;verticalAlign=bottom;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="56">
83 <mxGeometry x="-1" relative="1" as="geometry"/>
84 </mxCell>
85 <mxCell id="63" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.25;exitDx=0;exitDy=0;entryX=0.053;entryY=0.302;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="40" target="35">
86 <mxGeometry relative="1" as="geometry">
87 <mxPoint x="780" y="280" as="sourcePoint"/>
88 <mxPoint x="880" y="280" as="targetPoint"/>
89 </mxGeometry>
90 </mxCell>
91 <mxCell id="64" value="pid info" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="63">
92 <mxGeometry relative="1" as="geometry"/>
93 </mxCell>
94 <mxCell id="65" value="" style="endArrow=classic;html=1;fontFamily=Comic Sans MS;fontSize=18;exitX=1;exitY=0.75;exitDx=0;exitDy=0;entryX=0.067;entryY=0.727;entryDx=0;entryDy=0;entryPerimeter=0;" edge="1" parent="1" source="40" target="35">
95 <mxGeometry relative="1" as="geometry">
96 <mxPoint x="780" y="280" as="sourcePoint"/>
97 <mxPoint x="880" y="280" as="targetPoint"/>
98 </mxGeometry>
99 </mxCell>
100 <mxCell id="66" value="file change&lt;br&gt;info" style="edgeLabel;resizable=0;html=1;align=center;verticalAlign=middle;fontFamily=Comic Sans MS;fontSize=18;" connectable="0" vertex="1" parent="65">
101 <mxGeometry relative="1" as="geometry"/>
102 </mxCell>
103 </root>
104 </mxGraphModel>
105 </diagram>
106</mxfile> \ No newline at end of file
diff --git a/listener/audit.go b/listener/audit.go
index ed48691..148378c 100644
--- a/listener/audit.go
+++ b/listener/audit.go
@@ -13,14 +13,14 @@ func read() error {
13 // Write netlink response to a file for further analysis or for writing 13 // Write netlink response to a file for further analysis or for writing
14 // tests cases. 14 // tests cases.
15 var diagWriter io.Writer 15 var diagWriter io.Writer
16 if *diag != "" { 16 // if *diag != "" {
17 f, err := os.OpenFile(*diag, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o600) 17 // f, err := os.OpenFile(*diag, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o664)
18 if err != nil { 18 // if err != nil {
19 return err 19 // return err
20 } 20 // }
21 defer f.Close() 21 // defer f.Close()
22 diagWriter = f 22 // diagWriter = f
23 } 23 // }
24 24
25 log.Println("starting netlink client") 25 log.Println("starting netlink client")
26 26
diff --git a/listener/deal.go b/listener/deal.go
index 70c2827..af65ff8 100644
--- a/listener/deal.go
+++ b/listener/deal.go
@@ -10,17 +10,8 @@ import (
10 "go.mongodb.org/mongo-driver/bson" 10 "go.mongodb.org/mongo-driver/bson"
11) 11)
12 12
13const (
14 dbName string = "test"
15 pidColName string = "pids"
16 fdColName string = "fds"
17 fileColName string = "files"
18)
19
20var pidCol, fdCol, fileCol mongoClient
21
22func initPidCol() (err error) { 13func initPidCol() (err error) {
23 // TODO: 这里是否需要补全一下进程信息? 14 // 这里是否需要补全一下进程信息?
24 dirs, err := os.ReadDir(fmt.Sprintf("/proc/%d/task", containerdPid)) 15 dirs, err := os.ReadDir(fmt.Sprintf("/proc/%d/task", containerdPid))
25 if err != nil { 16 if err != nil {
26 return err 17 return err
@@ -41,6 +32,9 @@ func initPidCol() (err error) {
41 process.Star = true 32 process.Star = true
42 } 33 }
43 err = pidCol.InsertOne(process) 34 err = pidCol.InsertOne(process)
35 if err != nil {
36 return err
37 }
44 } 38 }
45 return nil 39 return nil
46} 40}
@@ -49,27 +43,6 @@ func deal() {
49 defer wg.Done() 43 defer wg.Done()
50 var cooked Event 44 var cooked Event
51 var ok bool 45 var ok bool
52 var err error
53
54 if err = pidCol.init(dbName, pidColName); err != nil {
55 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
56 return
57 }
58 if err = initPidCol(); err != nil {
59 fmt.Fprintf(os.Stderr, "Err while initing pidcol: %v\n", err)
60 }
61
62 if err = fdCol.init(dbName, fdColName); err != nil {
63 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
64 return
65 }
66 if err = fileCol.init(dbName, fileColName); err != nil {
67 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
68 }
69
70 defer pidCol.Disconnect()
71 defer fdCol.Disconnect()
72 defer fileCol.Disconnect()
73 46
74 for { 47 for {
75 cooked, ok = <-cookedChan 48 cooked, ok = <-cookedChan
diff --git a/listener/global.go b/listener/global.go
index b782284..49d6e94 100644
--- a/listener/global.go
+++ b/listener/global.go
@@ -44,12 +44,6 @@ type Event struct {
44 destPath string 44 destPath string
45} 45}
46 46
47var wg sync.WaitGroup // 掌管协程
48var rawChan chan interface{} // 从接收到整理的管道
49var cookedChan chan Event // 整理好的信息的管道
50var syscallTable [500]string //记录一下系统调用
51var containerdPid int
52
53// 插入到数据库的结构 47// 插入到数据库的结构
54type Exec struct { 48type Exec struct {
55 Timestamp time.Time `bson:"timestamp"` 49 Timestamp time.Time `bson:"timestamp"`
@@ -84,3 +78,17 @@ type File struct {
84 Written []time.Time `bson:"written"` 78 Written []time.Time `bson:"written"`
85 CloseTimestamp time.Time `bson:"close_timestamp"` 79 CloseTimestamp time.Time `bson:"close_timestamp"`
86} 80}
81
82const (
83 dbName string = "test"
84 pidColName string = "pids"
85 fdColName string = "fds"
86 fileColName string = "files"
87)
88
89var wg sync.WaitGroup // 掌管协程
90var rawChan chan interface{} // 从接收到整理的管道
91var cookedChan chan Event // 整理好的信息的管道
92var syscallTable [500]string //记录一下系统调用
93var containerdPid int // 容器守护进程进程号
94var pidCol, fdCol, fileCol mongoClient // 数据库集合
diff --git a/listener/godo.go b/listener/godo.go
index 8d82231..0e1dc73 100644
--- a/listener/godo.go
+++ b/listener/godo.go
@@ -18,14 +18,15 @@ import (
18 18
19var ( 19var (
20 fs = flag.NewFlagSet("audit", flag.ExitOnError) 20 fs = flag.NewFlagSet("audit", flag.ExitOnError)
21 diag = fs.String("diag", "", "dump raw information from kernel to file") 21 diag = fs.String("diag", "godo.log", "dump raw information from kernel to file")
22 rate = fs.Uint("rate", 0, "rate limit in kernel (default 0, no rate limit)") 22 rate = fs.Uint("rate", 0, "rate limit in kernel (default 0, no rate limit)")
23 backlog = fs.Uint("backlog", 8192, "backlog limit") 23 backlog = fs.Uint("backlog", 1<<30, "backlog limit")
24 immutable = fs.Bool("immutable", false, "make kernel audit settings immutable (requires reboot to undo)") 24 immutable = fs.Bool("immutable", false, "make kernel audit settings immutable (requires reboot to undo)")
25 receiveOnly = fs.Bool("ro", false, "receive only using multicast, requires kernel 3.16+") 25 receiveOnly = fs.Bool("ro", false, "receive only using multicast, requires kernel 3.16+")
26 mongoURI = fs.String("mongo", "localhost:27017", "mongo database uri")
26) 27)
27 28
28const bufferPages = 100 29const bufferPages = 1000
29 30
30func main() { 31func main() {
31 // 检查用户身份,并添加auditd规则,监听所有syscall 32 // 检查用户身份,并添加auditd规则,监听所有syscall
@@ -41,7 +42,6 @@ func main() {
41 } 42 }
42 43
43 exec.Command("auditctl", "-D").Run() 44 exec.Command("auditctl", "-D").Run()
44 exec.Command("auditctl", "-b", "1000000000").Run()
45 exec.Command("auditctl", "--reset-lost").Run() 45 exec.Command("auditctl", "--reset-lost").Run()
46 46
47 var auditCmd *exec.Cmd 47 var auditCmd *exec.Cmd
@@ -78,24 +78,45 @@ func main() {
78 } 78 }
79} 79}
80 80
81func coroutine(client *libaudit.AuditClient) { 81func coroutine(client *libaudit.AuditClient) error {
82 // 各协程至此开始 82 // 各协程至此开始
83 bufferSize := bufferPages * syscall.Getpagesize() 83 bufferSize := bufferPages * syscall.Getpagesize()
84 rawChan = make(chan interface{}, bufferSize) 84 rawChan = make(chan interface{}, bufferSize)
85 cookedChan = make(chan Event, bufferSize) 85 cookedChan = make(chan Event, bufferSize)
86 86
87 var err error
88 if err = pidCol.init(dbName, pidColName); err != nil {
89 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
90 return err
91 }
92 if err = initPidCol(); err != nil {
93 fmt.Fprintf(os.Stderr, "Err while initing pidcol: %v\n", err)
94 }
95
96 if err = fdCol.init(dbName, fdColName); err != nil {
97 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
98 return err
99 }
100 if err = fileCol.init(dbName, fileColName); err != nil {
101 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
102 }
103
104 defer pidCol.Disconnect()
105 defer fdCol.Disconnect()
106 defer fileCol.Disconnect()
107
108 wg.Add(1)
109 go deal()
87 wg.Add(1) 110 wg.Add(1)
88 go procWatch() 111 go procWatch()
89
90 wg.Add(1) 112 wg.Add(1)
91 go receive(client) 113 go receive(client)
92 wg.Add(1) 114 wg.Add(1)
93 go orgnaze() 115 go orgnaze()
94 wg.Add(1)
95 go deal()
96 116
97 wg.Wait() 117 wg.Wait()
98 time.Sleep(2 * time.Second) 118 time.Sleep(2 * time.Second)
119 return nil
99} 120}
100 121
101func procWatch() error { 122func procWatch() error {
diff --git a/listener/mongo.go b/listener/mongo.go
index a51350e..36c471c 100644
--- a/listener/mongo.go
+++ b/listener/mongo.go
@@ -31,18 +31,27 @@ func (mc *mongoClient) init(dbName, colName string) error {
31 31
32func (mc *mongoClient) Connect(dbName, colName string) error { 32func (mc *mongoClient) Connect(dbName, colName string) error {
33 var err error 33 var err error
34 mc.client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) 34 // 设置连接MongoDB的参数
35 clientOptions := options.Client().ApplyURI("mongodb://" + *mongoURI)
35 36
37 // 创建一个带有超时的上下文
38 ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second)
39 defer cancel() // 确保在函数退出时取消上下文
40
41 // 使用带超时的上下文连接到MongoDB
42 mc.client, err = mongo.Connect(ctx, clientOptions)
36 if err != nil { 43 if err != nil {
37 return err 44 return err
38 } 45 }
39 46
40 ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) 47 // 尝试ping数据库以检查连接是否成功
41 err = mc.client.Connect(ctx) 48 err = mc.client.Ping(ctx, nil)
42 if err != nil { 49 if err != nil {
43 return err 50 return err
44 } 51 }
45 52
53 fmt.Println("Connected to MongoDB!")
54
46 mc.col = mc.client.Database(dbName).Collection(colName) 55 mc.col = mc.client.Database(dbName).Collection(colName)
47 mc.dbName = dbName 56 mc.dbName = dbName
48 mc.colName = colName 57 mc.colName = colName
diff --git a/listener/organize.go b/listener/organize.go
index 0c05eb4..cf6dad3 100644
--- a/listener/organize.go
+++ b/listener/organize.go
@@ -2,6 +2,7 @@ package main
2 2
3import ( 3import (
4 "fmt" 4 "fmt"
5 "io"
5 "os" 6 "os"
6 "regexp" 7 "regexp"
7 "strconv" 8 "strconv"
@@ -41,13 +42,30 @@ func orgnaze() {
41 var raw interface{} 42 var raw interface{}
42 var rawEvent libaudit.RawAuditMessage 43 var rawEvent libaudit.RawAuditMessage
43 44
45 var diagWriter io.Writer
46 var f *os.File
47 var err error
48 var fileName string
49 if *diag != "" {
50 fileName = *diag
51 } else {
52 fileName = "godo.log"
53 }
54
55 f, err = os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o664)
56 if err != nil {
57 f = nil
58 }
59 defer f.Close()
60 diagWriter = f
61
44 for { 62 for {
45 raw, ok = <-rawChan 63 raw, ok = <-rawChan
46 if !ok { 64 if !ok {
47 break 65 break
48 } 66 }
49 rawEvent = raw.(libaudit.RawAuditMessage) 67 rawEvent = raw.(libaudit.RawAuditMessage)
50 // fmt.Printf("type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) 68 fmt.Fprintf(diagWriter, "type=%v msg=%s\n", rawEvent.Type, rawEvent.Data)
51 69
52 switch rawEvent.Type { 70 switch rawEvent.Type {
53 case auparse.AUDIT_SYSCALL: 71 case auparse.AUDIT_SYSCALL:
diff --git a/notes.md b/notes.md
new file mode 100644
index 0000000..932e811
--- /dev/null
+++ b/notes.md
@@ -0,0 +1,318 @@
1# 背景说明
2
3本文档对[godo](https://git.qin-juan-ge-zhu.top/godo)编写过程中新了解到的技术、遇到的问题进行简要说明,以备所需。
4
5# 系统调用
6
7As is universually acknowledged, 操作系统、尤其是类 Unix 操作系统,以系统调用的形式对应用程序提供服务。系统调用是名称,有系统调用号与之对应(同一版本的内核在不同架构的 cpu 上,系统调用号可能不一样)。有的时候我们需要了解一些内核行为,但却不知道从何下手。可以通过查看内核源码来学习。
8
9系统调用可以在源码中查找到。由于本项目使用的是 centos 7,内核版本 3.10.0-1160、cpu 为 x86-64 架构,兹以该版本内核为例说明。
10
11要查看 fork 的系统调用号,查看`arch/x86/syscalls/syscall_64.tbl`。想要查看其具体的实现,则在源码根目录下执行`grep -rInP "SYSCALL_DEFINE\d\(fork"`,其中 SYSCALL_DEFINE+数字是 kernel 中定义的宏,展开即完整的函数声明。通过这种查找办法,我们可以快速地定位内核中对系统调用的处理函数,查看其工作原理。查看其他的内核相关内容也可以采取类似办法,即先用 grep 定位大致范围、看都有什么地方用到,然后找到真正起作用的地方,读相关代码。
12
13使用这些系统调用有两种办法:
14
15- 在 C 语言中直接调用同名函数,但大概率经过了 glibc 的封装
16- 手动封装。如下:
17
18```c
19#include <stdio.h>
20#include <sys/syscall.h>
21#include <sys/types.h>
22#include <sys/wait.h>
23#include <unistd.h>
24
25int main(){
26 pid_t pid = syscall(SYS_fork);
27 // syscall是一个变参函数,第一个参数是系统调用号,接下来的是系统调用的各个参数
28 // syscall定义在 unistd.h
29 // SYS_fork定义在 sys/syscall.h
30 if(pid == 0) {
31 printf("Child!\n");
32 } else {
33 printf("Parent!\n");
34 }
35 return 0;
36}
37```
38
39这种封装方式与经常被用来当作 os 教材的 Linux-0.11/0.12 有所区别。Linux-0.11 环境上,unistd.h 大致如下:
40
41```c
42#ifndef _UNISTD_H
43#define _UNISTD_H
44
45...
46#include <sys/stat.h>
47#include <sys/times.h>
48#include <sys/utsname.h>
49#include <utime.h>
50
51#ifdef __LIBRARY__
52
53#define __NR_setup 0 /* used only by init, to get system going */
54#define __NR_exit 1
55#define __NR_fork 2
56#define __NR_read 3
57#define __NR_write 4
58#define __NR_open 5
59#define __NR_close 6
60...
61
62#define _syscall0(type,name) \
63 type name(void) \
64{ \
65long __res; \
66__asm__ volatile ("int $0x80" \
67 : "=a" (__res) \
68 : "0" (__NR_##name)); \
69if (__res >= 0) \
70 return (type) __res; \
71errno = -__res; \
72return -1; \
73}
74
75#define _syscall1(type,name,atype,a) \
76type name(atype a) \
77{ \
78long __res; \
79__asm__ volatile ("int $0x80" \
80 : "=a" (__res) \
81 : "0" (__NR_##name),"b" ((long)(a))); \
82if (__res >= 0) \
83 return (type) __res; \
84errno = -__res; \
85return -1; \
86}
87
88...
89#endif /* __LIBRARY__ */
90...
91
92#endif
93```
94
95可以看到,Linux-0.11 上,封装的一般方法为:
96
97```c
98#define __LIBRARY__ // 一定要在unistd.h之前
99#include <unistd.h>
100#include <stdio.h>
101
102syscall0(int, fork); // 宏替换后这就是个名为fork的函数的具体实现了
103int main() {
104 if(fork() == 0) {
105 printf("Child!\n");
106 } else {
107 printf("Parent!\n");
108 }
109 return 0;
110}
111```
112
113但是无论如何,一般情况下不推荐手动封装,这不是 release 版该有的做法。
114
115此外,从汇编代码来看,Linux-0.11 所用的 80386 芯片,不提供专门的系统调用指令,因而该系统使用的是`int 0x80`中断指令,通过注册中断处理函数进行对应处理;而现代 x86 提供了专门的 syscall 指令,Linux 系统直接用该指令进行系统调用。
116
117## 系统调用中的进程与线程
118
119一般地,在 Linux 系统上,我们以 pid 指代进程号,而进程可以有多个线程。很显然,真正被调度执行的单元应该是线程,换言之,**是 thread 而非 process 真正地对应着内核中 tasks 表里的一个 task,而每个 task 才具有独一无二的 id**。
120
121### 常见系统调用的分析
122
123看看这个:
124
125```c
126extern int pthread_create (pthread_t *__restrict __newthread,
127 const pthread_attr_t *__restrict __attr,
128 void *(*__start_routine) (void *),
129 void *__restrict __arg) __THROWNL __nonnull ((1, 3));
130```
131
132`pthread_create`函数的第一个参数,就是一个 pthread_t 类型的指针,处理后将 task 的 id 写到指针指向的区域。
133
134让我们来看一段简单的代码:
135
136```c
137// test.c
138#include <stdio.h>
139#include <pthread.h>
140#include <sys/syscall.h>
141#include <sys/types.h>
142#include <unistd.h>
143
144void *test(void *args) {
145 printf("Hello, I'm %d\n", getpid());
146}
147
148int main() {
149 pthread_t pthid;
150 int pid;
151 pthread_create(&pthid, NULL, test, NULL);
152 printf("main: thread %ld\n", pthid);
153 pthread_join(pthid, NULL);
154 if ((pid = fork()) == 0) {
155 printf("Hello, I'm %d\n", getpid());
156 return 0;
157 }
158 printf("main: child process %d\n",pid);
159 if ((pid = syscall(SYS_fork)) == 0) {
160 printf("Hello, I'm %d\n", getpid());
161 return 0;
162 }
163 printf("main: child process %d\n",pid);
164 return 0;
165}
166```
167
168当我们使用`strace ./test`来查看上述代码时,会发现情况如下:
169
170```c
171clone(child_stack=0x7f3dd28bbff0, flags=CLONE_VM|CLONE_FS|CLONE_FILES|CLONE_SIGHAND|CLONE_THREAD|CLONE_SYSVSEM|CLONE_SETTLS|CLONE_PARENT_SETTID|CLONE_CHILD_CLEARTID, parent_tidptr=0x7f3dd28bc9d0, tls=0x7f3dd28bc700, child_tidptr=0x7f3dd28bc9d0) = 21756
172write(1, "main: thread 139903502108416\n", 29) = 29
173clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f3dd308e9d0) = 21757
174--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21757, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
175write(1, "main: child process 21757\n", 26) = 26
176fork() = 21758
177--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=21758, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
178write(1, "main: child process 21758\n", 26) = 26
179exit_group(0) = ?
180+++ exited with 0 +++
181```
182
183从这样的输出里,我们可以清晰地看到,无论是`pthread_create`还是`fork`(指库函数),本质上都是封装了`clone`系统调用,即使 Linux 本身提供了专门的 fork 系统调用。也许这是 glibc 和 Linux 都想在添加功能的基础上保证代码兼容性?花开两朵各表一枝了属于是。
184
185这一结论也可以从 glibc 的代码中得到验证:
186
187```c
188// 文件 glibc-2.18/nptl/sysdeps/unix/sysv/linux/pt-fork.c
189pid_t
190__fork (void)
191{
192 return __libc_fork ();
193}
194strong_alias (__fork, fork)
195
196
197// 文件 glibc-2.18/nptl/sysdeps/unix/sysv/linux/fork.c
198pid_t
199__libc_fork (void)
200{
201 ... // 一堆不知所云的代码
202#ifdef ARCH_FORK
203 pid = ARCH_FORK ();
204#else
205# error "ARCH_FORK must be defined so that the CLONE_SETTID flag is used"
206 pid = INLINE_SYSCALL (fork, 0);
207#endif
208 ... // 又是一堆不知所云的代码
209}
210
211// 文件 glibc-2.18/nptl/sysdeps/unix/sysv/linux/x86_64/fork.c
212#define ARCH_FORK() \
213 INLINE_SYSCALL (clone, 4, \
214 CLONE_CHILD_SETTID | CLONE_CHILD_CLEARTID | SIGCHLD, 0, \
215 NULL, &THREAD_SELF->tid)
216
217// 文件 glibc-2.18/sysdeps/unix/sysv/linux/x86_64/syscall.S
218
219/* Please consult the file sysdeps/unix/sysv/linux/x86-64/sysdep.h for
220 more information about the value -4095 used below. */
221 .text
222ENTRY (syscall)
223 movq %rdi, %rax /* Syscall number -> rax. */
224 movq %rsi, %rdi /* shift arg1 - arg5. */
225 movq %rdx, %rsi
226 movq %rcx, %rdx
227 movq %r8, %r10
228 movq %r9, %r8
229 movq 8(%rsp),%r9 /* arg6 is on the stack. */
230 syscall /* Do the system call. */
231 cmpq $-4095, %rax /* Check %rax for error. */
232 jae SYSCALL_ERROR_LABEL /* Jump to error handler if error. */
233 ret /* Return to caller. */
234
235PSEUDO_END (syscall)
236```
237
238可以看到,fork 库函数实际上是掉入了`__libc_fork`,在经过各种处理之后,如果 glibc 中该平台的相关代码里定义了 ARCH_FORK 宏,则调用之;否则会直接调用`INLINE_SYSCALL`(这是 glibc 各个平台的代码里都有的宏);而如果直接调用`syscall`函数手动封装系统调用,则调用什么就是什么。`syscall`函数调用过程涉及延迟绑定等问题,就不是这里的重点了,而且我也没太搞明白,有机会单开一篇吧。
239
240### 进程与线程
241
242对于一个进程而言,它有很多线程,每个线程有一个号,但整个进程都有主线程的号,称为 tgid,只有一个 tgid 能真正地代表一个进程,而 pid 事实上是 task 的编号。
243
244对于 netlink connector 而言,它听到的 fork 并不是 fork,而是 clone;对于 audit,也只能听到 clone 而听不到 fork。这是因为在内核中,fork 也是通过调用 clone 的处理函数来进行的。clone 创建的是一个 task,至于具体是进程还是线程,取决于用的 flag 参数,参见 manual 手册。
245
246因而,无论使用 connector 还是 audit,拿到的都是 pid,只不过 connector 可以直接拿到 tgid、据此确定是进程还是线程,而 audit 只能拿到 pid,需要从 clone 的参数里查看是进程还是线程,且拿不到 tgid。这也就是我在项目中选择使用 connector 听进程消息的原因。
247
248干巴巴说了这么多,其实就是想说,pid 也许在不同的语境下有不同含义。
249
250# docker 使用的技术
251
252## cgroup
253
254Linux 下用来控制进程资源的东西。没学明白,留缺。姑且抄点书上的内容来占个位置吧。
255
256cgroup 是 control group 的简写,是 Linux 内核提供的一个特性,用于限制和隔离一组进程对系统资源的使用,也即做进程的 QoS。控制的资源主要包括 cpu、内存、block IO、网络带宽等。该特性自 2.6.24 开始进入内核主线,目前各大发行版都默认打开了该特性。
257
258从实现角度,cgroup 实现了一个通用的进程分组框架,而不同类型资源的具体管理由各个 cgroup 子系统实现。截至内核 4.1,已经实现的子系统及其作用如下:
259
260| 子系统 | 作用 |
261| ---------- | ----------------------------------------- |
262| devices | 设备权限控制 |
263| cpuset | 分配指定的 cpu 和内存节点 |
264| cpu | 控制 cpu 占用率 |
265| cpuacct | 统计 cpu 使用情况 |
266| memory | 限制内存使用上限 |
267| freezer | 冻结暂停 cgroup 中的进程 |
268| net_cls | 配合 tc(traffic controller)限制网络带宽 |
269| net_prio | 设置进程网络流量优先级 |
270| huge_tlb | 限制 huge_tlb 的使用 |
271| perf_event | 允许 Perf 工具基于 cgroup 分组做性能监测 |
272
273cgroup 原生接口通过 cgroupfs 提供,类似于 procfs 和 sysfs,是一种虚拟文件系统。具体使用与分析参见《Docker 进阶与实战》。
274
275## namespace
276
277namespace 是将内核的全局资源做封装,使每个 namespace 拥有独立的资源,进程在各自的 namespace 中对相同资源的使用不会互相干扰。比如主机名 hostname 作为全局资源,执行 sethostname 系统调用会影响到其他进程;内核通过实现 UTS namespace,将不同进程分割在不同的 namespace 中,实现了隔离,一个 namespace 修改主机名不影响别的 namespace。
278
279目前内核实现了以下几种 namespace:
280
281| namespace | 作用 |
282| --------- | ----------------------------------- |
283| IPC | 隔离 System V IPC 和 POSIX 消息队列 |
284| Network | 隔离网络资源 |
285| Mount | 隔离文件系统挂载点 |
286| PID | 隔离进程 ID |
287| UTS | 隔离主机名和域名 |
288| User | 隔离用户 ID 与组 ID |
289
290对 namespace 的操作主要通过`clone/setns/unshare`三个系统调用来实现。详细的使用也不写了,没用过的东西就不全抄。记得读书和自己实验,补到这里。
291
292### 文件系统
293
294众所周知,docker 的文件系统是分层的,有镜像文件等一堆东西。文件系统分为若干层,在开启 docker 的时候会被联合挂载到同一个点下,作为 docker 的根目录。这叫做联合挂载,即将多个目录和文件系统挂载到同一个目录下,其中可能有覆盖等。
295
296docker 进程运行在宿主机的内核上,但是根文件系统又要用 docker 自己挂载的目录,且后来的进程也需要进入该目录。这里采用的技术是 pivot_root,该系统调用允许进程切换根目录。
297
298在根目录挂载完成之后,docker 拉起一个初始 shell(正如 Linux-0.11 启动的时候也会有一个 shell 干活),这是 docker 中第一个进程,它调用 pivot_root 切换根目录。在切换完成之后,当我们执行 docker exec 时,这是一个 docker 的新的进程,但该进程不再 pivot_root,而是打开第一个进程的 namespace,通过 setns 系统调用,将自己的 namespace 设置为与其相同。由于 mnt 的 namespace 的存在,进程的根目录也就与第一个进程一样了。
299
300# 书籍列表
301
302**毕业之前读完这些属实是有点难为人了,一个比一个硬,一次性啃完能给我门牙崩了;但是定点投放耗材市场之后,估计也不会有啥精力琢磨这些玩意了**。能读一点是一点吧。
303
304感觉自己现在已经染上班味了,绝症,没得治。
305
306- SRE:Google 运维解密
307- Linker and Loader
308- 有空自己解析一下 ELF?
309- Docker 进阶与实战
310- containerd 原理剖析与实战
311- Linux 内核源码情景分析
312- [LFS](https://www.linuxfromscratch.org/lfs/) 网站,自己从软件包开始搭建 Linux
313- 构建嵌入式 Linux 系统
314
315也许我应该把它们列入进阶版:
316
317- gcc 技术大全
318- 黑客调试技术大全