summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/deal.go48
-rw-r--r--src/global.go59
-rw-r--r--src/godo.go21
-rw-r--r--src/mongo.go13
-rw-r--r--src/organize.go1
5 files changed, 57 insertions, 85 deletions
diff --git a/src/deal.go b/src/deal.go
index 871b7ff..483d4d2 100644
--- a/src/deal.go
+++ b/src/deal.go
@@ -2,20 +2,20 @@ package main
2 2
3import ( 3import (
4 "fmt" 4 "fmt"
5 "sync"
6 "syscall" 5 "syscall"
7 6
8 "go.mongodb.org/mongo-driver/bson" 7 "go.mongodb.org/mongo-driver/bson"
9) 8)
10 9
11const ( 10const (
12 dbName string = "test" 11 dbName string = "test"
13 pidColName string = "pids" 12 pidColName string = "pids"
14 fdColName string = "fds" 13 fdColName string = "fds"
14 fileColName string = "files"
15) 15)
16 16
17var mongoMutex sync.Mutex 17// var mongoMutex sync.Mutex
18var pidCol, fdCol mongoClient 18var pidCol, fdCol, fileCol mongoClient
19 19
20var docRes []bson.M 20var docRes []bson.M
21var err error 21var err error
@@ -44,10 +44,14 @@ func deal() {
44 fmt.Printf("Error while initing the mongodb: %v\n", err) 44 fmt.Printf("Error while initing the mongodb: %v\n", err)
45 return 45 return
46 } 46 }
47 if err = fileCol.init(dbName, fileColName); err != nil {
48 fmt.Printf("Error while initing the mongodb: %v\n", err)
49 }
47 50
48 fmt.Printf("Containerd: %d\n", containerdPid) 51 fmt.Printf("Containerd: %d\n", containerdPid)
49 defer pidCol.Disconnect() 52 defer pidCol.Disconnect()
50 defer fdCol.Disconnect() 53 defer fdCol.Disconnect()
54 defer fileCol.Disconnect()
51 55
52 for { 56 for {
53 cooked, ok = <-cookedChan 57 cooked, ok = <-cookedChan
@@ -57,11 +61,11 @@ func deal() {
57 61
58 switch cooked.tag { 62 switch cooked.tag {
59 case NEWPID: 63 case NEWPID:
60 dealNewPid(cooked) 64 go dealNewPid(cooked)
61 case EXECVE: 65 case EXECVE:
62 dealExecve(cooked) 66 go dealExecve(cooked)
63 case PIDEXIT: 67 case PIDEXIT:
64 deletePid(cooked) 68 go deletePid(cooked)
65 case FILEOPEN: 69 case FILEOPEN:
66 fileOpen(cooked) 70 fileOpen(cooked)
67 case FILEWRITE: 71 case FILEWRITE:
@@ -73,9 +77,7 @@ func deal() {
73} 77}
74 78
75func deletePid(cooked Event) { 79func deletePid(cooked Event) {
76 // TODO: 是否还需要延时? 80 pidCol.GetLock()
77 // time.Sleep(1 * time.Second)
78 mongoMutex.Lock()
79 // 先从老爹那里销户 81 // 先从老爹那里销户
80 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{ 82 pidCol.UpdateOne(bson.M{"pid": cooked.ppid}, bson.M{
81 "$pull": bson.M{ 83 "$pull": bson.M{
@@ -85,7 +87,8 @@ func deletePid(cooked Event) {
85 87
86 // 孩子们需要收容 88 // 孩子们需要收容
87 // 不必到children里一个个找,直接看ppid即可 89 // 不必到children里一个个找,直接看ppid即可
88 pidCol.UpdateMany(bson.M{"ppid": cooked.pid}, bson.M{"ppid": 1}) 90 // pidCol.UpdateMany(bson.M{"ppid": cooked.pid}, bson.M{"ppid": 1})
91 // 在这套逻辑里,孩子是不需要收容的,因为我们根本就不看ppid来工作
89 92
90 // 可以去死了 93 // 可以去死了
91 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ 94 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
@@ -95,8 +98,7 @@ func deletePid(cooked Event) {
95 "exit_signal": cooked.exit_signal, 98 "exit_signal": cooked.exit_signal,
96 }, 99 },
97 }) 100 })
98 mongoMutex.Unlock() 101 pidCol.Mutex.Unlock()
99 fmt.Printf("Exit: %v\t%6d\t%6d\n", cooked.timestamp, cooked.pid, cooked.exit_code)
100} 102}
101 103
102func dealNewPid(cooked Event) { 104func dealNewPid(cooked Event) {
@@ -113,7 +115,8 @@ func dealNewPid(cooked Event) {
113 fmt.Printf("Err finding: %v\n", err) 115 fmt.Printf("Err finding: %v\n", err)
114 return 116 return
115 } 117 }
116 mongoMutex.Lock() 118
119 pidCol.GetLock()
117 if len(docRes) != 0 { 120 if len(docRes) != 0 {
118 // 进程原本就存在,换言之别的消息先到了 121 // 进程原本就存在,换言之别的消息先到了
119 // 所有先行抵达的消息必须保留execve/children字段 122 // 所有先行抵达的消息必须保留execve/children字段
@@ -146,7 +149,7 @@ func dealNewPid(cooked Event) {
146 "children": cooked.pid, 149 "children": cooked.pid,
147 }, 150 },
148 }) 151 })
149 mongoMutex.Unlock() 152 pidCol.Mutex.Unlock()
150} 153}
151 154
152func dealExecve(cooked Event) { 155func dealExecve(cooked Event) {
@@ -162,7 +165,8 @@ func dealExecve(cooked Event) {
162 if err != nil { 165 if err != nil {
163 return 166 return
164 } 167 }
165 mongoMutex.Lock() 168
169 pidCol.GetLock()
166 if len(docRes) == 1 { 170 if len(docRes) == 1 {
167 // 自身已在,直接记录 171 // 自身已在,直接记录
168 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{ 172 pidCol.UpdateOne(bson.M{"pid": cooked.pid}, bson.M{
@@ -187,12 +191,10 @@ func dealExecve(cooked Event) {
187 }, 191 },
188 }) 192 })
189 } 193 }
190 mongoMutex.Unlock() 194 pidCol.Mutex.Unlock()
191} 195}
192 196
193func fileOpen(cooked Event) { 197func fileOpen(cooked Event) {
194 // fmt.Printf("Open: %6d\t%6d\t%s\n", cooked.ppid, cooked.pid, cooked.pathName)
195
196 // 权限检查过了,不必再查 198 // 权限检查过了,不必再查
197 fdCol.InsertOne(bson.M{ 199 fdCol.InsertOne(bson.M{
198 "timestamp": cooked.timestamp, 200 "timestamp": cooked.timestamp,
@@ -213,8 +215,6 @@ func fileOpen(cooked Event) {
213} 215}
214 216
215func fileClose(cooked Event) { 217func fileClose(cooked Event) {
216 // fmt.Printf("Close: %6d\t%6d\t%s\n", cooked.ppid, cooked.pid, cooked.pathName)
217 // 直接看文件表有无记录
218 res, err := fdCol.Finddoc(bson.M{ 218 res, err := fdCol.Finddoc(bson.M{
219 "pid": cooked.pid, 219 "pid": cooked.pid,
220 "fd": cooked.syscallParam[0], 220 "fd": cooked.syscallParam[0],
@@ -234,8 +234,6 @@ func fileClose(cooked Event) {
234} 234}
235 235
236func fileWrite(cooked Event) { 236func fileWrite(cooked Event) {
237 // fmt.Printf("Write: %6d\t%6d\t%s\n", cooked.ppid, cooked.pid, cooked.pathName)
238 // 直接看文件表有无记录
239 res, err := fdCol.Finddoc(bson.M{ 237 res, err := fdCol.Finddoc(bson.M{
240 "pid": cooked.pid, 238 "pid": cooked.pid,
241 "fd": cooked.syscallParam[0], 239 "fd": cooked.syscallParam[0],
diff --git a/src/global.go b/src/global.go
index a266b1b..b6635c9 100644
--- a/src/global.go
+++ b/src/global.go
@@ -1,11 +1,8 @@
1package main 1package main
2 2
3import ( 3import (
4 "fmt"
5 "sync" 4 "sync"
6 "time" 5 "time"
7
8 "go.mongodb.org/mongo-driver/bson/primitive"
9) 6)
10 7
11type eventType int 8type eventType int
@@ -29,50 +26,18 @@ func (et eventType) String() string {
29} 26}
30 27
31type Event struct { 28type Event struct {
32 tag eventType 29 tag eventType
33 timestamp time.Time 30 timestamp time.Time
34 pid, ppid int 31 pid, tgid int
35 syscall int 32 ppid, parentTgid int
36 syscallParam [4]uint64 33 syscall int
37 pathName string 34 syscallParam [4]uint64
38 argc int 35 pathName string
39 argv []string 36 argc int
40 cwd string 37 argv []string
41 exit_code uint64 38 cwd string
42 exit_signal int 39 exit_code uint64
43} 40 exit_signal int
44
45func (event Event) String() string {
46 var res string
47 res = fmt.Sprintf("tag: %v\ntimestamp: %v\nppid: %d\npid: %d\n", event.tag, event.timestamp.Local(), event.ppid, event.pid)
48 res += fmt.Sprintf("syscall: %s\nexit_code: %d\nargs: \n", syscallTable[event.syscall], event.exit_code)
49 for i := 0; i < len(event.argv); i++ {
50 res += fmt.Sprintf("\t\"%s\"\n", event.argv[i])
51 }
52 res += "syscallParam: "
53 for i := 0; i < len(event.syscallParam); i++ {
54 res += fmt.Sprintf("\t\"%d\"\n", event.syscallParam[i])
55 }
56 res += "pathName: \"" + event.pathName + "\"\n------\n"
57 return res
58}
59
60type pidExec struct {
61 timestamp time.Time `bson:"timestamp"`
62 execArgs []string `bson:"execArgs"`
63}
64
65type pid struct {
66 ID primitive.ObjectID `bson:"_id,ometempty"`
67 start_timestamp time.Time `bson:"start_timestamp"`
68 ppid int `bson:"ppid"`
69 pid int `bson:"pid"`
70 cwd string `bson:"cwd"`
71 args []string `bson:"args"`
72 execve []pidExec `bson:"execve"`
73 children []int `bson:"children"`
74 exit_timestamp time.Time `bson:"exit_timestamp"`
75 exit_code uint64 `bson:"exit_code"`
76} 41}
77 42
78var wg sync.WaitGroup // 掌管协程 43var wg sync.WaitGroup // 掌管协程
diff --git a/src/godo.go b/src/godo.go
index 2ba32d6..77e677c 100644
--- a/src/godo.go
+++ b/src/godo.go
@@ -44,7 +44,6 @@ func main() {
44 var auditCmd *exec.Cmd 44 var auditCmd *exec.Cmd
45 45
46 pidSyscall := []string{"execve"} 46 pidSyscall := []string{"execve"}
47 // pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"}
48 // 设置监听规则 47 // 设置监听规则
49 for i := 0; i < len(pidSyscall); i++ { 48 for i := 0; i < len(pidSyscall); i++ {
50 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])
@@ -52,7 +51,7 @@ func main() {
52 } 51 }
53 52
54 // 监听文件的消息 53 // 监听文件的消息
55 fileSyscall := []string{"open"} 54 fileSyscall := []string{"open", "write", "close"}
56 // 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"}
57 for i := 0; i < len(fileSyscall); i++ { 56 for i := 0; i < len(fileSyscall); i++ {
58 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])
@@ -118,16 +117,14 @@ func procWatch() error {
118 case netlink.PROC_EVENT_FORK: 117 case netlink.PROC_EVENT_FORK:
119 data := procEvent.Data.(netlink.ProcEventFork) 118 data := procEvent.Data.(netlink.ProcEventFork)
120 cooked := Event{ 119 cooked := Event{
121 tag: NEWPID, 120 tag: NEWPID,
122 ppid: int(data.ParentTgid), 121 timestamp: time.Now(),
123 pid: int(data.ChildPid), 122 pid: int(data.ChildPid),
124 timestamp: time.Now(), 123 tgid: int(data.ChildTgid),
124 ppid: int(data.ParentPid),
125 parentTgid: int(data.ParentTgid),
125 } 126 }
126 checkProc(&cooked) 127 checkProc(&cooked)
127 if data.ChildPid != data.ChildTgid {
128 cooked.ppid = int(data.ChildTgid)
129 cooked.pid = int(data.ChildPid)
130 }
131 cookedChan <- cooked 128 cookedChan <- cooked
132 case netlink.PROC_EVENT_EXIT: 129 case netlink.PROC_EVENT_EXIT:
133 data := procEvent.Data.(netlink.ProcEventExit) 130 data := procEvent.Data.(netlink.ProcEventExit)
@@ -146,7 +143,7 @@ func procWatch() error {
146} 143}
147 144
148func checkProc(pCooked *Event) { 145func checkProc(pCooked *Event) {
149 fileName := fmt.Sprintf("/proc/%d/cmdline", pCooked.pid) 146 fileName := fmt.Sprintf("/proc/%d/task/%d/cmdline", pCooked.tgid, pCooked.pid)
150 fd, err := os.Open(fileName) 147 fd, err := os.Open(fileName)
151 if err != nil { 148 if err != nil {
152 fmt.Printf("Err: %v\n", err) 149 fmt.Printf("Err: %v\n", err)
@@ -162,7 +159,7 @@ func checkProc(pCooked *Event) {
162 pCooked.argc = len(pCooked.argv) 159 pCooked.argc = len(pCooked.argv)
163 fd.Close() 160 fd.Close()
164 161
165 fileName = fmt.Sprintf("/proc/%d/cwd", pCooked.pid) 162 fileName = fmt.Sprintf("/proc/%d/task/%d/cwd", pCooked.tgid, pCooked.pid)
166 pCooked.cwd, err = os.Readlink(fileName) 163 pCooked.cwd, err = os.Readlink(fileName)
167 if err != nil { 164 if err != nil {
168 fmt.Printf("Err readlink %s: %v\n", fileName, err) 165 fmt.Printf("Err readlink %s: %v\n", fileName, err)
diff --git a/src/mongo.go b/src/mongo.go
index 54f9533..3a23131 100644
--- a/src/mongo.go
+++ b/src/mongo.go
@@ -2,6 +2,8 @@ package main
2 2
3import ( 3import (
4 "context" 4 "context"
5 "fmt"
6 "sync"
5 "time" 7 "time"
6 8
7 "go.mongodb.org/mongo-driver/bson" 9 "go.mongodb.org/mongo-driver/bson"
@@ -13,6 +15,8 @@ type mongoClient struct {
13 dbName, colName string 15 dbName, colName string
14 client *mongo.Client 16 client *mongo.Client
15 col *mongo.Collection 17 col *mongo.Collection
18 Mutex sync.Mutex
19 // Attention: 这把锁是否有必要?
16} 20}
17 21
18func (mc *mongoClient) init(dbName, colName string) error { 22func (mc *mongoClient) init(dbName, colName string) error {
@@ -89,3 +93,12 @@ func (mc *mongoClient) Disconnect() error {
89 mc.colName = "" 93 mc.colName = ""
90 return nil 94 return nil
91} 95}
96
97func (mc *mongoClient) GetLock() {
98 for i := 0; i < 20000; {
99 if !mc.Mutex.TryLock() {
100 i++
101 }
102 }
103 fmt.Printf("Die...\n")
104}
diff --git a/src/organize.go b/src/organize.go
index 8deba53..238509f 100644
--- a/src/organize.go
+++ b/src/organize.go
@@ -47,7 +47,6 @@ 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)
51 50
52 switch rawEvent.Type { 51 switch rawEvent.Type {
53 case auparse.AUDIT_SYSCALL: 52 case auparse.AUDIT_SYSCALL: