summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-08-06 14:31:31 +0800
committerWe-unite <3205135446@qq.com>2024-08-06 14:31:31 +0800
commitf4655e64a1461c22ad7a3871375269915a743f40 (patch)
tree535e8d77431337bc431df85cfc2b675464395879
parent78de56b9f2d862bbdac8a02a72dd95500b7ef83e (diff)
downloadgodo-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.go45
-rw-r--r--src/godo.go6
-rw-r--r--src/mongo.go14
m---------src/netlink0
-rw-r--r--src/organize.go13
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
79func deletePid(cooked Event) { 79func 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
104func dealNewPid(cooked Event) { 106func 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
155func dealExecve(cooked Event) { 163func 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
217func fileClose(cooked Event) { 226func 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
236func fileWrite(cooked Event) { 237func 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
81func (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
81func (mc *mongoClient) Drop() error { 88func (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
97func (mc *mongoClient) GetLock() { 104func (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 }