aboutsummaryrefslogtreecommitdiffstats
path: root/listener/deal.go
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-08-09 13:56:37 +0800
committerWe-unite <3205135446@qq.com>2024-08-12 14:16:51 +0800
commit3e49a044d22635157916651f0acb5a062397b34b (patch)
tree254cd9a2605fa003f4579e7c5510e6e2aea19375 /listener/deal.go
parentea32e017e579f168d87732893335c38d539ac2f1 (diff)
downloadgodo-3e49a044d22635157916651f0acb5a062397b34b.tar.gz
godo-3e49a044d22635157916651f0acb5a062397b34b.zip
Add db structure, fix filePath, start filtering
This commit I made several changes: - Use structure instead of simple bson.M(interface{}). bson.M has some shortcomings: 1) It makes the database in chaos and hard to read, but this's not important; 2) Some entrys may has more or less content than others, which makes it hard to decode and filt. So I design new data structure to encode and decode. Hopes that there's no bugs. - Fix the way to calculate file path. The original method is to add all the PATH entries together, that's totally wrong! PATH entry has several types, as it shows in "objtype". I can't find it in the kernel src code, so what i know is just "PARENT" means the dir the file is in, while the filename itself has the path, so we whould ignore all "PARENT"s. When the src code is found, we should check it again. - Fix bugs in updating. The update function of mongodb is set to required to has a '$' such as 'set'/'push', so when we update a whole doc, we should use replace but not update function. And, we should never ignore the error infomation it gives us. Hope that there's no more bugs for this Big Change. Now its' time to write filter as well as viewer. Best wishes with NO BUGS!
Diffstat (limited to '')
-rw-r--r--listener/deal.go (renamed from src/deal.go)200
1 files changed, 102 insertions, 98 deletions
diff --git a/src/deal.go b/listener/deal.go
index e553174..8f77431 100644
--- a/src/deal.go
+++ b/listener/deal.go
@@ -4,6 +4,7 @@ import (
4 "fmt" 4 "fmt"
5 "os" 5 "os"
6 "syscall" 6 "syscall"
7 "time"
7 8
8 "go.mongodb.org/mongo-driver/bson" 9 "go.mongodb.org/mongo-driver/bson"
9) 10)
@@ -15,10 +16,7 @@ const (
15 fileColName string = "files" 16 fileColName string = "files"
16) 17)
17 18
18// var mongoMutex sync.Mutex
19var pidCol, fdCol, fileCol mongoClient 19var pidCol, fdCol, fileCol mongoClient
20
21var docRes []bson.M
22var err error 20var err error
23 21
24func deal() { 22func deal() {
@@ -30,12 +28,12 @@ func deal() {
30 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) 28 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
31 return 29 return
32 } 30 }
33 err = pidCol.InsertOne(bson.M{ 31 err = pidCol.InsertOne(Process{
34 "ppid": 1, 32 Ppid: 1,
35 "pid": containerdPid, 33 Pid: containerdPid,
36 "cwd": "/", 34 Cwd: "/",
37 "children": []bson.M{}, 35 Children: make([]int, 0),
38 "daemon": true, 36 Star: true,
39 }) 37 })
40 if err != nil { 38 if err != nil {
41 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) 39 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
@@ -50,7 +48,6 @@ func deal() {
50 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) 48 fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err)
51 } 49 }
52 50
53 fmt.Printf("Containerd: %d\n", containerdPid)
54 defer pidCol.Disconnect() 51 defer pidCol.Disconnect()
55 defer fdCol.Disconnect() 52 defer fdCol.Disconnect()
56 defer fileCol.Disconnect() 53 defer fileCol.Disconnect()
@@ -81,30 +78,25 @@ func deal() {
81} 78}
82 79
83func deletePid(cooked Event) { 80func deletePid(cooked Event) {
84 // 先从老爹那里销户
85 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
86 "$pull": bson.M{
87 "children": cooked.pid,
88 },
89 })
90
91 // 在这套逻辑里,孩子是不需要收容的,因为我们根本就不看ppid来工作 81 // 在这套逻辑里,孩子是不需要收容的,因为我们根本就不看ppid来工作
92 82 // 父节点那里也不需要销户
93 // 83 // 理论上这里需要闭所有文件述符,为了处理效率,留流程
94 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ 84 err := pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
95 "$set": bson.M{ 85 "$set": bson.M{
96 "exit_timestamp": cooked.timestamp, 86 "exit_timestamp": cooked.timestamp,
97 "exit_code": cooked.exit_code, 87 "exit_code": cooked.exit_code,
98 "exit_signal": cooked.exit_signal, 88 "exit_signal": cooked.exit_signal,
99 }, 89 },
100 }) 90 })
101 91 if err != nil {
102 // 理论上这里需要关闭所有文件描述符,但为了处理效率,留给后续流程 92 fmt.Fprintf(os.Stderr, "Err updating: %v\n", err)
93 }
103} 94}
104 95
105func dealNewPid(cooked Event) { 96func dealNewPid(cooked Event) {
106 // 自身是否已经记录 97 // 自身是否已经记录
107 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) 98 var docRes []Process
99 err = pidCol.Finddoc(bson.M{"pid": cooked.pid}, &docRes)
108 if err != nil { 100 if err != nil {
109 fmt.Fprintf(os.Stderr, "Err finding: %v\n", err) 101 fmt.Fprintf(os.Stderr, "Err finding: %v\n", err)
110 return 102 return
@@ -113,97 +105,104 @@ func dealNewPid(cooked Event) {
113 if len(docRes) != 0 { 105 if len(docRes) != 0 {
114 // 进程原本就存在,换言之别的消息先到了 106 // 进程原本就存在,换言之别的消息先到了
115 // 所有先行抵达的消息必须保留execve/children字段 107 // 所有先行抵达的消息必须保留execve/children字段
116 // 此处不再更新 108 docRes[0].Ppid = cooked.ppid
117 // 以防把原有信息更没了 109 docRes[0].ParentTgid = cooked.parentTgid
118 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ 110 docRes[0].Pid = cooked.pid
119 "start_timestamp": cooked.timestamp, 111 docRes[0].Tgid = cooked.tgid
120 "ppid": cooked.ppid, 112 docRes[0].Cwd = cooked.cwd
121 "parentTgid": cooked.parentTgid, 113 docRes[0].Comm = cooked.comm
122 "pid": cooked.pid, 114 docRes[0].Args = cooked.argv
123 "tgid": cooked.tgid, 115
124 "cwd": cooked.cwd, 116 err := pidCol.ReplaceOne(bson.M{"pid": cooked.pid}, docRes[0])
125 // "execve": []bson.M{}, 117 if err != nil {
126 "args": cooked.argv, 118 fmt.Fprintf(os.Stderr, "Err replaceing: %v\n", err)
127 // "children": []bson.M{}, 119 }
128 })
129 } else { 120 } else {
130 // 这进程本是新修的 121 // 这进程本是新修的
131 pidCol.InsertOne(bson.M{ 122 err := pidCol.InsertOne(Process{
132 "start_timestamp": cooked.timestamp, 123 StartTimestamp: cooked.timestamp,
133 "ppid": cooked.ppid, 124 Ppid: cooked.ppid,
134 "parentTgid": cooked.parentTgid, 125 ParentTgid: cooked.parentTgid,
135 "pid": cooked.pid, 126 Pid: cooked.pid,
136 "tgid": cooked.tgid, 127 Tgid: cooked.tgid,
137 "cwd": cooked.cwd, 128 Args: cooked.argv,
138 "execve": []bson.M{}, 129 Comm: cooked.comm,
139 "args": cooked.argv, 130 Cwd: cooked.cwd,
140 "children": []bson.M{}, 131 Execve: make([]Exec, 0),
132 Children: make([]int, 0),
141 }) 133 })
134 if err != nil {
135 fmt.Fprintf(os.Stderr, "Err inserting: %v\n", err)
136 }
142 } 137 }
143 138
144 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ 139 err := pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
145 "$push": bson.M{ 140 "$push": bson.M{
146 "children": cooked.pid, 141 "children": cooked.pid,
147 }, 142 },
148 }) 143 })
144 if err != nil {
145 fmt.Fprintf(os.Stderr, "Err updating: %v\n", err)
146 }
149} 147}
150 148
151func dealExecve(cooked Event) { 149func dealExecve(cooked Event) {
152 // 父进程在不在?不在扔 150 var docRes []Process
153 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
154 if err != nil || len(docRes) != 1 {
155 return
156 }
157
158 // 首先检查进程是否存在,如不存在则为之创建 151 // 首先检查进程是否存在,如不存在则为之创建
159 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid}) 152 err = pidCol.Finddoc(bson.M{"pid": cooked.pid}, &docRes)
160 if err != nil { 153 if err != nil {
161 return 154 return
162 } 155 }
163 156
164 if len(docRes) == 1 { 157 if len(docRes) == 1 {
165 // 自身已在,直接记录 158 // 自身已在,直接记录
166 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ 159 docRes[0].Execve = append(docRes[0].Execve, Exec{
167 "$push": bson.M{ 160 Timestamp: cooked.timestamp,
168 "execve": bson.M{ 161 ExecArgs: cooked.argv,
169 "timestamp": cooked.timestamp,
170 "execArgs": cooked.argv,
171 },
172 },
173 }) 162 })
163
164 err := pidCol.ReplaceOne(bson.M{"pid": cooked.pid}, docRes[0])
165 if err != nil {
166 fmt.Fprintf(os.Stderr, "Err replacing: %v\n", err)
167 }
174 } else { 168 } else {
175 // 先fork抵达,插入 169 // 先fork抵达,插入
176 pidCol.InsertOne(bson.M{ 170 process := Process{
177 "ppid": cooked.ppid, 171 Ppid: cooked.ppid,
178 "pid": cooked.pid, 172 Pid: cooked.pid,
179 "children": []bson.M{}, 173 Execve: make([]Exec, 0),
180 "execve": []bson.M{ 174 Children: make([]int, 0),
181 { 175 }
182 "timestamp": cooked.timestamp, 176 process.Execve = append(process.Execve, Exec{
183 "execArgs": cooked.argv, 177 Timestamp: cooked.timestamp,
184 }, 178 ExecArgs: cooked.argv,
185 },
186 }) 179 })
180
181 err := pidCol.InsertOne(process)
182 if err != nil {
183 fmt.Fprintf(os.Stderr, "Err inserting: %v\n", err)
184 }
187 } 185 }
188} 186}
189 187
190func fileOpen(cooked Event) { 188func fileOpen(cooked Event) {
191 // 权限检查过了,不必再查 189 // 权限检查过了,不必再查
192 fdCol.InsertOne(bson.M{ 190 file := File{
193 "timestamp": cooked.timestamp, 191 OpenTimestamp: cooked.timestamp,
194 "fileName": cooked.srcPath, 192 FileName: cooked.srcPath,
195 "pid": cooked.pid, 193 Pid: cooked.pid,
196 "fd": cooked.exit_code, 194 Fd: cooked.exit_code,
197 "flags": cooked.syscallParam, 195 Flags: cooked.syscallParam,
198 "written": []bson.M{}, 196 Written: make([]time.Time, 0),
199 }) 197 }
200
201 if cooked.syscallParam[1]&syscall.O_TRUNC != 0 { 198 if cooked.syscallParam[1]&syscall.O_TRUNC != 0 {
202 fdCol.UpdateOne(bson.M{"pid": cooked.pid, "fd": cooked.exit_code}, bson.M{ 199 // 文件以清空方式打开
203 "$push": bson.M{ 200 file.Written = append(file.Written, cooked.timestamp)
204 "written": cooked.timestamp, 201 }
205 }, 202
206 }) 203 err := fdCol.InsertOne(file)
204 if err != nil {
205 fmt.Fprintf(os.Stderr, "Err inserting: %v\n", err)
207 } 206 }
208} 207}
209 208
@@ -213,33 +212,39 @@ func fileClose(cooked Event) {
213 return 212 return
214 } 213 }
215 res["close_timestamp"] = cooked.timestamp 214 res["close_timestamp"] = cooked.timestamp
216 if err := fileCol.InsertOne(res); err != nil { 215
216 err = fileCol.InsertOne(res)
217 if err != nil {
217 fmt.Fprintf(os.Stderr, "Err inserting files: %v\n", err) 218 fmt.Fprintf(os.Stderr, "Err inserting files: %v\n", err)
218 } 219 }
219} 220}
220 221
221func fileWrite(cooked Event) { 222func fileWrite(cooked Event) {
222 res, err := fdCol.Finddoc(bson.M{ 223 var res []File
223 "pid": cooked.pid, 224 err := fdCol.Finddoc(bson.M{
224 "fd": cooked.syscallParam[0], 225 "pid": cooked.pid,
225 "close_timestamp": bson.M{"$exists": false}, 226 "fd": cooked.syscallParam[0],
226 }) 227 }, &res)
227 if err != nil { 228 if err != nil {
228 fmt.Fprintf(os.Stderr, "Err closing fd %d of pid %d: %v\n", cooked.syscallParam[0], cooked.pid, err) 229 fmt.Fprintf(os.Stderr, "Err closing fd %d of pid %d: %v\n", cooked.syscallParam[0], cooked.pid, err)
229 } 230 }
230 if len(res) == 0 { 231 if len(res) == 0 {
231 return 232 return
232 } 233 }
233 fdCol.UpdateOne(bson.M{ 234
234 "pid": cooked.pid, 235 err = fdCol.UpdateOne(bson.M{
235 "fd": cooked.syscallParam[0], 236 "pid": cooked.pid,
236 "close_timestamp": bson.M{"$exists": false}, 237 "fd": cooked.syscallParam[0],
237 }, bson.M{"$push": bson.M{"written": cooked.timestamp}}) 238 }, bson.M{"$push": bson.M{"written": cooked.timestamp}})
239 if err != nil {
240 fmt.Fprintf(os.Stderr, "Err updating: %v\n", err)
241 }
238} 242}
239 243
240func pivotRoot(cooked Event) { 244func pivotRoot(cooked Event) {
245 var docRes []Process
241 // docker的根目录信息,记录 246 // docker的根目录信息,记录
242 docRes, err := pidCol.Finddoc(bson.M{"pid": cooked.pid}) 247 err := pidCol.Finddoc(bson.M{"pid": cooked.pid}, &docRes)
243 if err != nil { 248 if err != nil {
244 fmt.Fprintf(os.Stderr, "Err finding: %v\n", err) 249 fmt.Fprintf(os.Stderr, "Err finding: %v\n", err)
245 return 250 return
@@ -255,10 +260,9 @@ func pivotRoot(cooked Event) {
255 }) 260 })
256 } else { 261 } else {
257 // 读取已有的工作目录 262 // 读取已有的工作目录
258 cwd := docRes[0]["cwd"]
259 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ 263 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
260 "$set": bson.M{ 264 "$set": bson.M{
261 "rootfs": cwd, 265 "rootfs": docRes[0].Cwd,
262 }, 266 },
263 }) 267 })
264 } 268 }