diff options
author | We-unite <3205135446@qq.com> | 2024-08-09 13:56:37 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-08-12 14:16:51 +0800 |
commit | 3e49a044d22635157916651f0acb5a062397b34b (patch) | |
tree | 254cd9a2605fa003f4579e7c5510e6e2aea19375 /listener/deal.go | |
parent | ea32e017e579f168d87732893335c38d539ac2f1 (diff) | |
download | godo-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 | ||
19 | var pidCol, fdCol, fileCol mongoClient | 19 | var pidCol, fdCol, fileCol mongoClient |
20 | |||
21 | var docRes []bson.M | ||
22 | var err error | 20 | var err error |
23 | 21 | ||
24 | func deal() { | 22 | func 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 | ||
83 | func deletePid(cooked Event) { | 80 | func 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 | ||
105 | func dealNewPid(cooked Event) { | 96 | func 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 | ||
151 | func dealExecve(cooked Event) { | 149 | func 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 | ||
190 | func fileOpen(cooked Event) { | 188 | func 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 | ||
221 | func fileWrite(cooked Event) { | 222 | func 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 | ||
240 | func pivotRoot(cooked Event) { | 244 | func 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 | } |