diff options
author | We-unite <3205135446@qq.com> | 2024-08-06 14:31:31 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-08-06 14:31:31 +0800 |
commit | f4655e64a1461c22ad7a3871375269915a743f40 (patch) | |
tree | 535e8d77431337bc431df85cfc2b675464395879 | |
parent | 78de56b9f2d862bbdac8a02a72dd95500b7ef83e (diff) | |
download | godo-f4655e64a1461c22ad7a3871375269915a743f40.tar.gz godo-f4655e64a1461c22ad7a3871375269915a743f40.zip |
Expand connector buffer, put all file info into db
This commit I make several changes, reasons are as follows:
- Expand netlink connector buffer size. Originally it uses only one
page of mem, but sometimes it causes "no enough buffer" errno, or
the socket is blocked long time. Now it's 20 pages.
- All file infos are thrown into database. As the last commit co-
mment, There's 2 tables, "fds" and "files". When a file discriptor
is closed, the info in fds will be found, delete, and put into the
"file" table with its close time.
Left questions:
- The netlink connector is always found blocked without any reasons.
Fix it, or replace the golang-coded connector with C program? The
key is why it's blocked. Maybe it's in the kernel src code.
- sometimes audit still losts info(not too much). For instance, I
use vim in the docker to change hello.c, the hello.c may be opened
but no close info recvd. Or, the swap file of vim, such as
.hello.c.swp or .hello.c.swx is not closed. What's more, the hello.c
is never written, but swap files are. May vim write to swap files,
and replace the origin file? Let's check it.
- Besides, when a pid exits, we should check its file discriptors
and close them all.
-rw-r--r-- | src/deal.go | 45 | ||||
-rw-r--r-- | src/godo.go | 6 | ||||
-rw-r--r-- | src/mongo.go | 14 | ||||
m--------- | src/netlink | 0 | ||||
-rw-r--r-- | src/organize.go | 13 |
5 files changed, 45 insertions, 33 deletions
diff --git a/src/deal.go b/src/deal.go index 483d4d2..1dd309c 100644 --- a/src/deal.go +++ b/src/deal.go | |||
@@ -67,17 +67,19 @@ func deal() { | |||
67 | case PIDEXIT: | 67 | case PIDEXIT: |
68 | go deletePid(cooked) | 68 | go deletePid(cooked) |
69 | case FILEOPEN: | 69 | case FILEOPEN: |
70 | fileOpen(cooked) | 70 | go fileOpen(cooked) |
71 | case FILEWRITE: | 71 | case FILEWRITE: |
72 | fileWrite(cooked) | 72 | go fileWrite(cooked) |
73 | case FILECLOSE: | 73 | case FILECLOSE: |
74 | fileClose(cooked) | 74 | go fileClose(cooked) |
75 | } | 75 | } |
76 | } | 76 | } |
77 | } | 77 | } |
78 | 78 | ||
79 | func deletePid(cooked Event) { | 79 | func deletePid(cooked Event) { |
80 | pidCol.GetLock() | 80 | if !pidCol.GetLock() { |
81 | return | ||
82 | } | ||
81 | // 先从老爹那里销户 | 83 | // 先从老爹那里销户 |
82 | pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ | 84 | pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ |
83 | "$pull": bson.M{ | 85 | "$pull": bson.M{ |
@@ -102,9 +104,9 @@ func deletePid(cooked Event) { | |||
102 | } | 104 | } |
103 | 105 | ||
104 | func dealNewPid(cooked Event) { | 106 | func dealNewPid(cooked Event) { |
105 | fmt.Printf("Fork: %v\t%6d\t%6d\n", cooked.timestamp, cooked.ppid, cooked.pid) | 107 | fmt.Printf("Fork\t%6d\t%6d\t%6d\t%6d\n", cooked.ppid, cooked.parentTgid, cooked.pid, cooked.tgid) |
106 | // 有无父进程在观察中 | 108 | // 有无父进程在观察中 |
107 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) | 109 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.parentTgid}) |
108 | if err != nil || len(docRes) != 1 { | 110 | if err != nil || len(docRes) != 1 { |
109 | return | 111 | return |
110 | } | 112 | } |
@@ -116,7 +118,9 @@ func dealNewPid(cooked Event) { | |||
116 | return | 118 | return |
117 | } | 119 | } |
118 | 120 | ||
119 | pidCol.GetLock() | 121 | if !pidCol.GetLock() { |
122 | return | ||
123 | } | ||
120 | if len(docRes) != 0 { | 124 | if len(docRes) != 0 { |
121 | // 进程原本就存在,换言之别的消息先到了 | 125 | // 进程原本就存在,换言之别的消息先到了 |
122 | // 所有先行抵达的消息必须保留execve/children字段 | 126 | // 所有先行抵达的消息必须保留execve/children字段 |
@@ -125,7 +129,9 @@ func dealNewPid(cooked Event) { | |||
125 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | 129 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ |
126 | "start_timestamp": cooked.timestamp, | 130 | "start_timestamp": cooked.timestamp, |
127 | "ppid": cooked.ppid, | 131 | "ppid": cooked.ppid, |
132 | "parentTgid": cooked.parentTgid, | ||
128 | "pid": cooked.pid, | 133 | "pid": cooked.pid, |
134 | "tgid": cooked.tgid, | ||
129 | "cwd": cooked.cwd, | 135 | "cwd": cooked.cwd, |
130 | // "execve": []bson.M{}, | 136 | // "execve": []bson.M{}, |
131 | "args": cooked.argv, | 137 | "args": cooked.argv, |
@@ -136,7 +142,9 @@ func dealNewPid(cooked Event) { | |||
136 | pidCol.InsertOne(bson.M{ | 142 | pidCol.InsertOne(bson.M{ |
137 | "start_timestamp": cooked.timestamp, | 143 | "start_timestamp": cooked.timestamp, |
138 | "ppid": cooked.ppid, | 144 | "ppid": cooked.ppid, |
145 | "parentTgid": cooked.parentTgid, | ||
139 | "pid": cooked.pid, | 146 | "pid": cooked.pid, |
147 | "tgid": cooked.tgid, | ||
140 | "cwd": cooked.cwd, | 148 | "cwd": cooked.cwd, |
141 | "execve": []bson.M{}, | 149 | "execve": []bson.M{}, |
142 | "args": cooked.argv, | 150 | "args": cooked.argv, |
@@ -153,7 +161,6 @@ func dealNewPid(cooked Event) { | |||
153 | } | 161 | } |
154 | 162 | ||
155 | func dealExecve(cooked Event) { | 163 | func dealExecve(cooked Event) { |
156 | fmt.Printf("EXEC: %6d\t%6d\n", cooked.ppid, cooked.pid) | ||
157 | // 父进程在不在?不在扔 | 164 | // 父进程在不在?不在扔 |
158 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) | 165 | docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) |
159 | if err != nil || len(docRes) != 1 { | 166 | if err != nil || len(docRes) != 1 { |
@@ -166,7 +173,9 @@ func dealExecve(cooked Event) { | |||
166 | return | 173 | return |
167 | } | 174 | } |
168 | 175 | ||
169 | pidCol.GetLock() | 176 | if !pidCol.GetLock() { |
177 | return | ||
178 | } | ||
170 | if len(docRes) == 1 { | 179 | if len(docRes) == 1 { |
171 | // 自身已在,直接记录 | 180 | // 自身已在,直接记录 |
172 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ | 181 | pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ |
@@ -215,22 +224,14 @@ func fileOpen(cooked Event) { | |||
215 | } | 224 | } |
216 | 225 | ||
217 | func fileClose(cooked Event) { | 226 | func fileClose(cooked Event) { |
218 | res, err := fdCol.Finddoc(bson.M{ | 227 | res, err := fdCol.FindOneAndDelete(bson.M{"pid": cooked.pid, "fd": cooked.syscallParam[0]}) |
219 | "pid": cooked.pid, | ||
220 | "fd": cooked.syscallParam[0], | ||
221 | "close_timestamp": bson.M{"$exists": false}, | ||
222 | }) | ||
223 | if err != nil { | 228 | if err != nil { |
224 | fmt.Printf("Err closing fd %d of pid %d: %v\n", cooked.syscallParam[0], cooked.pid, err) | ||
225 | } | ||
226 | if len(res) == 0 { | ||
227 | return | 229 | return |
228 | } | 230 | } |
229 | fdCol.UpdateOne(bson.M{ | 231 | res["close_timestamp"] = cooked.timestamp |
230 | "pid": cooked.pid, | 232 | if err := fileCol.InsertOne(res); err != nil { |
231 | "fd": cooked.syscallParam[0], | 233 | fmt.Printf("Err inserting files: %v\n", err) |
232 | "close_timestamp": bson.M{"$exists": false}, | 234 | } |
233 | }, bson.M{"$set": bson.M{"close_timestamp": cooked.timestamp}}) | ||
234 | } | 235 | } |
235 | 236 | ||
236 | func fileWrite(cooked Event) { | 237 | func fileWrite(cooked Event) { |
diff --git a/src/godo.go b/src/godo.go index 77e677c..923ef85 100644 --- a/src/godo.go +++ b/src/godo.go | |||
@@ -44,14 +44,14 @@ func main() { | |||
44 | var auditCmd *exec.Cmd | 44 | var auditCmd *exec.Cmd |
45 | 45 | ||
46 | pidSyscall := []string{"execve"} | 46 | pidSyscall := []string{"execve"} |
47 | // 设置监听规则 | 47 | // // 设置监听规则 |
48 | for i := 0; i < len(pidSyscall); i++ { | 48 | for i := 0; i < len(pidSyscall); i++ { |
49 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) | 49 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) |
50 | auditCmd.Run() | 50 | auditCmd.Run() |
51 | } | 51 | } |
52 | 52 | ||
53 | // 监听文件的消息 | 53 | // 监听文件的消息 |
54 | fileSyscall := []string{"open", "write", "close"} | 54 | fileSyscall := []string{"open", "close", "write"} |
55 | // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"} | 55 | // fileSyscall := []string{"open", "write", "creat", "unlink", "opendir", "mkdir", "rmdir", "chmod", "fchmod", "chown", "fchown", "lchown", "flock"} |
56 | for i := 0; i < len(fileSyscall); i++ { | 56 | for i := 0; i < len(fileSyscall); i++ { |
57 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", fileSyscall[i]) | 57 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", fileSyscall[i]) |
@@ -106,7 +106,7 @@ func procWatch() error { | |||
106 | } | 106 | } |
107 | defer ns.Close() | 107 | defer ns.Close() |
108 | for { | 108 | for { |
109 | res, err := ns.Receive() | 109 | res, err := ns.Receive(20) |
110 | if err != nil { | 110 | if err != nil { |
111 | fmt.Printf("Error recv: %v\n", err) | 111 | fmt.Printf("Error recv: %v\n", err) |
112 | continue | 112 | continue |
diff --git a/src/mongo.go b/src/mongo.go index 3a23131..764f877 100644 --- a/src/mongo.go +++ b/src/mongo.go | |||
@@ -78,6 +78,13 @@ func (mc *mongoClient) Finddoc(filter bson.M) ([]bson.M, error) { | |||
78 | return results, err | 78 | return results, err |
79 | } | 79 | } |
80 | 80 | ||
81 | func (mc *mongoClient) FindOneAndDelete(filter bson.M) (bson.M, error) { | ||
82 | res := mc.col.FindOneAndDelete(context.Background(), filter) | ||
83 | var result bson.M | ||
84 | err := res.Decode(&result) | ||
85 | return result, err | ||
86 | } | ||
87 | |||
81 | func (mc *mongoClient) Drop() error { | 88 | func (mc *mongoClient) Drop() error { |
82 | return mc.col.Drop(context.Background()) | 89 | return mc.col.Drop(context.Background()) |
83 | } | 90 | } |
@@ -94,11 +101,14 @@ func (mc *mongoClient) Disconnect() error { | |||
94 | return nil | 101 | return nil |
95 | } | 102 | } |
96 | 103 | ||
97 | func (mc *mongoClient) GetLock() { | 104 | func (mc *mongoClient) GetLock() bool { |
98 | for i := 0; i < 20000; { | 105 | for i := 0; i < 200000; { |
99 | if !mc.Mutex.TryLock() { | 106 | if !mc.Mutex.TryLock() { |
100 | i++ | 107 | i++ |
108 | } else { | ||
109 | return true | ||
101 | } | 110 | } |
102 | } | 111 | } |
103 | fmt.Printf("Die...\n") | 112 | fmt.Printf("Die...\n") |
113 | return false | ||
104 | } | 114 | } |
diff --git a/src/netlink b/src/netlink | |||
Subproject 10d3ea361f0bcafb9b92054440984d32421aeb7 | Subproject e53c2724725c5991cdd9ea088c26832c5c9fcf0 | ||
diff --git a/src/organize.go b/src/organize.go index 238509f..5268a90 100644 --- a/src/organize.go +++ b/src/organize.go | |||
@@ -47,20 +47,21 @@ func orgnaze() { | |||
47 | break | 47 | break |
48 | } | 48 | } |
49 | rawEvent = raw.(libaudit.RawAuditMessage) | 49 | rawEvent = raw.(libaudit.RawAuditMessage) |
50 | fmt.Printf("type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) | ||
50 | 51 | ||
51 | switch rawEvent.Type { | 52 | switch rawEvent.Type { |
52 | case auparse.AUDIT_SYSCALL: | 53 | case auparse.AUDIT_SYSCALL: |
53 | syscallRaw(rawEvent) | 54 | go syscallRaw(rawEvent) |
54 | case auparse.AUDIT_EXECVE: | 55 | case auparse.AUDIT_EXECVE: |
55 | execve(rawEvent) | 56 | go execve(rawEvent) |
56 | case auparse.AUDIT_CWD: | 57 | case auparse.AUDIT_CWD: |
57 | cwd(rawEvent) | 58 | go cwd(rawEvent) |
58 | case auparse.AUDIT_PATH: | 59 | case auparse.AUDIT_PATH: |
59 | path(rawEvent) | 60 | go path(rawEvent) |
60 | case auparse.AUDIT_PROCTITLE: | 61 | case auparse.AUDIT_PROCTITLE: |
61 | proctitle(rawEvent) | 62 | go proctitle(rawEvent) |
62 | case auparse.AUDIT_EOE: | 63 | case auparse.AUDIT_EOE: |
63 | eoe(rawEvent) | 64 | go eoe(rawEvent) |
64 | default: | 65 | default: |
65 | // ATTENTION: 这里也需要做防护 | 66 | // ATTENTION: 这里也需要做防护 |
66 | } | 67 | } |