summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--src/deal.go226
-rw-r--r--src/global.go3
-rw-r--r--src/organize.go47
4 files changed, 156 insertions, 122 deletions
diff --git a/.gitignore b/.gitignore
index 9fe8ea9..bfe22fb 100644
--- a/.gitignore
+++ b/.gitignore
@@ -8,3 +8,5 @@ old/go.*
8*/*.log 8*/*.log
9*/*.json 9*/*.json
10!logs/*.log 10!logs/*.log
11
12__debug_bin*
diff --git a/src/deal.go b/src/deal.go
index db6fc26..a9861a5 100644
--- a/src/deal.go
+++ b/src/deal.go
@@ -16,32 +16,18 @@ const (
16var mongoMutex sync.Mutex 16var mongoMutex sync.Mutex
17var pidCol mongoClient 17var pidCol mongoClient
18 18
19var docRes []bson.M
20var err error
21
19func deal() { 22func deal() {
20 defer wg.Done() 23 defer wg.Done()
21 var cooked Event 24 var cooked Event
22 var ok bool 25 var ok bool
23 26
24 var err error 27 if err = initMongo(); err != nil {
25 var res []bson.M 28 fmt.Printf("Error while initing the mongodb: %v\n", err)
26
27 if err = pidCol.Connect(dbName, pidColName); err != nil {
28 fmt.Printf("Error connecting the mongodb: %v\n", err)
29 }
30 if err = pidCol.Drop(); err != nil {
31 fmt.Printf("Error drop the mongodb: %v\n", err)
32 }
33
34 err = pidCol.InsertOne(bson.M{
35 "ppid": 1,
36 "pid": containerdPid,
37 "cwd": "/",
38 "children": bson.M{},
39 })
40 if err != nil {
41 fmt.Printf("Err containerd: %v", err)
42 return 29 return
43 } 30 }
44 fmt.Printf("Containerd: %d\n", containerdPid)
45 defer pidCol.Disconnect() 31 defer pidCol.Disconnect()
46 32
47 for { 33 for {
@@ -50,91 +36,12 @@ func deal() {
50 break 36 break
51 } 37 }
52 38
53 switch syscallTable[cooked.syscall] { 39 switch cooked.tag {
54 case "clone": 40 case NEWPID:
55 // 有无父进程在观察中 41 dealNewPid(cooked)
56 res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid}) 42 case EXECVE:
57 if err != nil || len(res) != 1 { 43 dealExecve(cooked)
58 break 44 case PIDEXIT:
59 }
60
61 // 自身是否已经记录
62 res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
63 if err != nil {
64 fmt.Printf("Err finding: %v\n", err)
65 break
66 }
67 mongoMutex.Lock()
68 if len(res) != 0 {
69 // 进程原本就存在,换言之别的消息先到了
70 // 所有先行抵达的消息必须保留execve/children字段
71 // 此处不再更新
72 // 以防把原有信息更没了
73 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
74 "start_timestamp": cooked.timestamp,
75 "ppid": cooked.ppid,
76 "pid": cooked.pid,
77 "cwd": cooked.cwd,
78 // "execve": []bson.M{},
79 "args": cooked.argv,
80 // "children": []bson.M{},
81 })
82 } else {
83 // 这进程本是新修的
84 pidCol.InsertOne(bson.M{
85 "start_timestamp": cooked.timestamp,
86 "ppid": cooked.ppid,
87 "pid": cooked.pid,
88 "cwd": cooked.cwd,
89 "execve": []bson.M{},
90 "args": cooked.argv,
91 "children": []bson.M{},
92 })
93 }
94
95 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
96 "$push": bson.M{
97 "children": cooked.pid,
98 },
99 })
100 mongoMutex.Unlock()
101 case "execve":
102 // 父进程在不在?不在扔
103 res, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
104 if err != nil || len(res) != 1 {
105 break
106 }
107
108 // 首先检查进程是否存在,如不存在则为之创建
109 res, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
110 if err != nil {
111 break
112 }
113 mongoMutex.Lock()
114 if len(res) == 1 {
115 // 自身已在,直接记录
116 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
117 "$push": bson.M{
118 "execve": bson.M{
119 "timestamp": cooked.timestamp,
120 "args": cooked.argv,
121 },
122 },
123 })
124 } else {
125 // 先fork抵达,插入
126 pidCol.InsertOne(bson.M{
127 "children": []bson.M{},
128 "exe_args": []bson.M{
129 {
130 "timestamp": cooked.timestamp,
131 "execve": cooked.argv,
132 },
133 },
134 })
135 }
136 mongoMutex.Unlock()
137 case "exit", "exit_group":
138 go deletePid(cooked) 45 go deletePid(cooked)
139 } 46 }
140 } 47 }
@@ -163,3 +70,114 @@ func deletePid(cooked Event) {
163 }) 70 })
164 mongoMutex.Unlock() 71 mongoMutex.Unlock()
165} 72}
73
74func initMongo() error {
75 var err error
76 if err = pidCol.Connect(dbName, pidColName); err != nil {
77 return err
78 }
79 if err = pidCol.Drop(); err != nil {
80 return err
81 }
82
83 err = pidCol.InsertOne(bson.M{
84 "ppid": 1,
85 "pid": containerdPid,
86 "cwd": "/",
87 "children": bson.M{},
88 })
89 if err != nil {
90 return err
91 }
92 fmt.Printf("Containerd: %d\n", containerdPid)
93 return nil
94}
95
96func dealNewPid(cooked Event) {
97 // 有无父进程在观察中
98 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
99 if err != nil || len(docRes) != 1 {
100 return
101 }
102
103 // 自身是否已经记录
104 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
105 if err != nil {
106 fmt.Printf("Err finding: %v\n", err)
107 return
108 }
109 mongoMutex.Lock()
110 if len(docRes) != 0 {
111 // 进程原本就存在,换言之别的消息先到了
112 // 所有先行抵达的消息必须保留execve/children字段
113 // 此处不再更新
114 // 以防把原有信息更没了
115 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
116 "start_timestamp": cooked.timestamp,
117 "ppid": cooked.ppid,
118 "pid": cooked.pid,
119 "cwd": cooked.cwd,
120 // "execve": []bson.M{},
121 "args": cooked.argv,
122 // "children": []bson.M{},
123 })
124 } else {
125 // 这进程本是新修的
126 pidCol.InsertOne(bson.M{
127 "start_timestamp": cooked.timestamp,
128 "ppid": cooked.ppid,
129 "pid": cooked.pid,
130 "cwd": cooked.cwd,
131 "execve": []bson.M{},
132 "args": cooked.argv,
133 "children": []bson.M{},
134 })
135 }
136
137 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
138 "$push": bson.M{
139 "children": cooked.pid,
140 },
141 })
142 mongoMutex.Unlock()
143}
144
145func dealExecve(cooked Event) {
146 // 父进程在不在?不在扔
147 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.ppid})
148 if err != nil || len(docRes) != 1 {
149 return
150 }
151
152 // 首先检查进程是否存在,如不存在则为之创建
153 docRes, err = pidCol.Finddoc(bson.M{"pid": cooked.pid})
154 if err != nil {
155 return
156 }
157 mongoMutex.Lock()
158 if len(docRes) == 1 {
159 // 自身已在,直接记录
160 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
161 "$push": bson.M{
162 "execve": bson.M{
163 "timestamp": cooked.timestamp,
164 "execArgs": cooked.argv,
165 },
166 },
167 })
168 } else {
169 // 先fork抵达,插入
170 pidCol.InsertOne(bson.M{
171 "ppid": cooked.ppid,
172 "pid": cooked.pid,
173 "children": []bson.M{},
174 "execve": []bson.M{
175 {
176 "timestamp": cooked.timestamp,
177 "execArgs": cooked.argv,
178 },
179 },
180 })
181 }
182 mongoMutex.Unlock()
183}
diff --git a/src/global.go b/src/global.go
index 3ddbc79..7401dc5 100644
--- a/src/global.go
+++ b/src/global.go
@@ -10,6 +10,7 @@ type eventType int
10const ( 10const (
11 NEWPID eventType = iota 11 NEWPID eventType = iota
12 PIDEXIT 12 PIDEXIT
13 EXECVE
13 FILEOPEN 14 FILEOPEN
14 FILEWRITE 15 FILEWRITE
15 TYPENUM 16 TYPENUM
@@ -29,7 +30,7 @@ type Event struct {
29} 30}
30 31
31func (et eventType) String() string { 32func (et eventType) String() string {
32 names := []string{"newPid", "pidExit", "open", "write", "typeNum"} 33 names := []string{"NEWPID", "PIDEXIT", "EXECVE", "FILEOPEN", "FILEWRITE", "TYPENUM"}
33 if et < NEWPID || et > TYPENUM { 34 if et < NEWPID || et > TYPENUM {
34 return "Unknown" 35 return "Unknown"
35 } 36 }
diff --git a/src/organize.go b/src/organize.go
index 679f361..2489961 100644
--- a/src/organize.go
+++ b/src/organize.go
@@ -21,11 +21,11 @@ var ok bool
21var event Event 21var event Event
22var pEvent *Event 22var pEvent *Event
23var eventId, argc int 23var eventId, argc int
24var err [6]error 24var errs [6]error
25 25
26// 要用的正则匹配列表 26// 要用的正则匹配列表
27var ( 27var (
28 syscallRegex = regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+).*?(exit=([-+]?\d+))?.*?ppid=(\d+) pid=(\d+).*?$`) 28 syscallRegex = regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+)(?:.*?exit=([-+]?\d+))?.*?ppid=(\d+) pid=(\d+).*?$`)
29 execveRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) 29 execveRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`)
30 argsRegex = regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) 30 argsRegex = regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`)
31 pathRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\):.*?name="(.*?)"`) 31 pathRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\):.*?name="(.*?)"`)
@@ -76,17 +76,17 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
76 var a [4]uint64 76 var a [4]uint64
77 // 捕获基础信息 77 // 捕获基础信息
78 match := syscallRegex.FindSubmatch(rawEvent.Data) 78 match := syscallRegex.FindSubmatch(rawEvent.Data)
79 event.timestamp, err[0] = getTimeFromStr(string(match[1])) 79 event.timestamp, errs[0] = getTimeFromStr(string(match[1]))
80 eventId, err[1] = strconv.Atoi(string(match[2])) 80 eventId, errs[1] = strconv.Atoi(string(match[2]))
81 event.syscall, err[2] = strconv.Atoi(string(match[3])) 81 event.syscall, errs[2] = strconv.Atoi(string(match[3]))
82 if string(match[5]) == "" { 82 if string(match[4]) == "" {
83 // exit没捕获到 83 // exit没捕获到
84 exit = 0 84 exit = 0
85 } else { 85 } else {
86 exit, err[3] = strconv.Atoi(string(match[5])) 86 exit, errs[3] = strconv.Atoi(string(match[4]))
87 } 87 }
88 event.ppid, err[4] = strconv.Atoi(string(match[6])) 88 event.ppid, errs[4] = strconv.Atoi(string(match[5]))
89 event.pid, err[5] = strconv.Atoi(string(match[7])) 89 event.pid, errs[5] = strconv.Atoi(string(match[6]))
90 90
91 // 捕获参数 91 // 捕获参数
92 if !argsRegex.Match(rawEvent.Data) { 92 if !argsRegex.Match(rawEvent.Data) {
@@ -95,7 +95,7 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
95 } 95 }
96 argsMatch := argsRegex.FindAllSubmatch(rawEvent.Data, -1) 96 argsMatch := argsRegex.FindAllSubmatch(rawEvent.Data, -1)
97 for i := 0; i < 4; i++ { 97 for i := 0; i < 4; i++ {
98 a[i], err[0] = strconv.ParseUint(string(argsMatch[i][2]), 16, 64) 98 a[i], errs[0] = strconv.ParseUint(string(argsMatch[i][2]), 16, 64)
99 } 99 }
100 100
101 switch syscallTable[event.syscall] { 101 switch syscallTable[event.syscall] {
@@ -136,6 +136,18 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
136 syscallParam: a, 136 syscallParam: a,
137 pathName: "", 137 pathName: "",
138 }) 138 })
139 case "execve":
140 eventTable.Store(eventId, &Event{
141 tag: EXECVE,
142 timestamp: event.timestamp,
143 syscall: event.syscall,
144 exit_code: a[0],
145 ppid: event.ppid,
146 pid: event.pid,
147 argc: 0,
148 argv: make([]string, 0),
149 cwd: "",
150 })
139 case "exit", "exit_group": 151 case "exit", "exit_group":
140 eventTable.Store(eventId, &Event{ 152 eventTable.Store(eventId, &Event{
141 tag: PIDEXIT, 153 tag: PIDEXIT,
@@ -157,14 +169,14 @@ func execve(rawEvent libaudit.RawAuditMessage) {
157 } 169 }
158 170
159 match := execveRegex.FindSubmatch(rawEvent.Data) 171 match := execveRegex.FindSubmatch(rawEvent.Data)
160 eventId, err[0] = strconv.Atoi(string(match[1])) 172 eventId, errs[0] = strconv.Atoi(string(match[1]))
161 argc, err[1] = strconv.Atoi(string(match[2])) 173 argc, errs[1] = strconv.Atoi(string(match[2]))
162 tmp, ok = eventTable.Load(eventId) 174 tmp, ok = eventTable.Load(eventId)
163 if !ok { 175 if !ok {
164 return 176 return
165 } 177 }
166 pEvent = tmp.(*Event) 178 pEvent = tmp.(*Event)
167 if err[0] == nil && err[1] == nil && argsRegex.Match(rawEvent.Data) { 179 if errs[0] == nil && errs[1] == nil && argsRegex.Match(rawEvent.Data) {
168 match := argsRegex.FindAllSubmatch(rawEvent.Data, -1) 180 match := argsRegex.FindAllSubmatch(rawEvent.Data, -1)
169 for i := 0; i < argc; i++ { 181 for i := 0; i < argc; i++ {
170 if len(match[i][2]) == 0 { 182 if len(match[i][2]) == 0 {
@@ -185,7 +197,7 @@ func cwd(rawEvent libaudit.RawAuditMessage) {
185 } 197 }
186 198
187 match := cwdRegex.FindSubmatch(rawEvent.Data) 199 match := cwdRegex.FindSubmatch(rawEvent.Data)
188 eventId, err[0] = strconv.Atoi(string(match[1])) 200 eventId, errs[0] = strconv.Atoi(string(match[1]))
189 tmp, ok = eventTable.Load(eventId) 201 tmp, ok = eventTable.Load(eventId)
190 if !ok { 202 if !ok {
191 return 203 return
@@ -200,7 +212,7 @@ func proctitle(rawEvent libaudit.RawAuditMessage) {
200 212
201 var cmdline string 213 var cmdline string
202 match := proctitleRegex.FindSubmatch(rawEvent.Data) 214 match := proctitleRegex.FindSubmatch(rawEvent.Data)
203 eventId, err[0] = strconv.Atoi(string(match[1])) 215 eventId, errs[0] = strconv.Atoi(string(match[1]))
204 tmp, ok = eventTable.Load(eventId) 216 tmp, ok = eventTable.Load(eventId)
205 if !ok { 217 if !ok {
206 return 218 return
@@ -225,13 +237,14 @@ func eoe(rawEvent libaudit.RawAuditMessage) {
225 } 237 }
226 238
227 match := eoeRegex.FindSubmatch(rawEvent.Data) 239 match := eoeRegex.FindSubmatch(rawEvent.Data)
228 eventId, err[0] = strconv.Atoi(string(match[1])) 240 eventId, errs[0] = strconv.Atoi(string(match[1]))
229 tmp, ok = eventTable.Load(eventId) 241 tmp, ok = eventTable.Load(eventId)
230 if !ok { 242 if !ok {
231 return 243 return
232 } 244 }
233 cooked := *(tmp.(*Event)) 245 cooked := *(tmp.(*Event))
234 cookedChan <- cooked 246 cookedChan <- cooked
247 fmt.Printf("Send: %10d\t%v\t%7d\t%7d\n", eventId, cooked.tag, cooked.ppid, cooked.pid)
235 eventTable.Delete(eventId) // 死人别占地 248 eventTable.Delete(eventId) // 死人别占地
236} 249}
237 250
@@ -240,7 +253,7 @@ func path(rawEvent libaudit.RawAuditMessage) {
240 return 253 return
241 } 254 }
242 match := pathRegex.FindSubmatch(rawEvent.Data) 255 match := pathRegex.FindSubmatch(rawEvent.Data)
243 eventId, err[0] = strconv.Atoi(string(match[1])) 256 eventId, errs[0] = strconv.Atoi(string(match[1]))
244 name := string(match[2]) 257 name := string(match[2])
245 258
246 tmp, ok = eventTable.Load(eventId) 259 tmp, ok = eventTable.Load(eventId)