aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWe-unite <3205135446@qq.com>2024-08-09 13:56:37 +0800
committerWe-unite <3205135446@qq.com>2024-08-12 14:16:51 +0800
commit3e49a044d22635157916651f0acb5a062397b34b (patch)
tree254cd9a2605fa003f4579e7c5510e6e2aea19375
parentea32e017e579f168d87732893335c38d539ac2f1 (diff)
downloadgodo-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--.gitignore1
-rw-r--r--.gitmodules2
-rw-r--r--filter/filter.go118
-rw-r--r--filter/go.mod18
-rw-r--r--filter/go.sum50
-rw-r--r--listener/audit.go (renamed from src/audit.go)0
-rw-r--r--listener/basefunc.go (renamed from src/basefunc.go)0
-rw-r--r--listener/deal.go (renamed from src/deal.go)200
-rw-r--r--listener/global.go84
-rw-r--r--listener/go.mod (renamed from src/go.mod)0
-rw-r--r--listener/go.sum (renamed from src/go.sum)0
-rw-r--r--listener/go.work (renamed from src/go.work)0
-rw-r--r--listener/go.work.sum (renamed from src/go.work.sum)0
-rw-r--r--listener/godo.go (renamed from src/godo.go)22
-rw-r--r--listener/mongo.go (renamed from src/mongo.go)36
m---------listener/netlink (renamed from src/netlink)0
-rw-r--r--listener/organize.go (renamed from src/organize.go)32
-rw-r--r--listener/receive.go (renamed from src/receive.go)0
-rw-r--r--src/global.go49
19 files changed, 437 insertions, 175 deletions
diff --git a/.gitignore b/.gitignore
index b9f0a38..336d320 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,7 @@
1.vscode/* 1.vscode/*
2*/godo 2*/godo
3*/hello 3*/hello
4*/filter
4 5
5old/* 6old/*
6!old/*.* 7!old/*.*
diff --git a/.gitmodules b/.gitmodules
index 6a63c7b..16e998b 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +1,3 @@
1[submodule "src/netlink"] 1[submodule "src/netlink"]
2 path = src/netlink 2 path = listener/netlink
3 url = https://github.com/We-unite/netlink 3 url = https://github.com/We-unite/netlink
diff --git a/filter/filter.go b/filter/filter.go
new file mode 100644
index 0000000..c83fb13
--- /dev/null
+++ b/filter/filter.go
@@ -0,0 +1,118 @@
1package main
2
3import (
4 "context"
5 "fmt"
6 "log"
7 "os"
8 "time"
9
10 "go.mongodb.org/mongo-driver/bson"
11 "go.mongodb.org/mongo-driver/mongo"
12 "go.mongodb.org/mongo-driver/mongo/options"
13 "go.mongodb.org/mongo-driver/mongo/readpref"
14)
15
16type Exec struct {
17 timestamp time.Time `bson:"timestamp"`
18 execArgs []string `bson:"execArgs"`
19}
20
21type Process struct {
22 timestamp time.Time `bson:"start_timestamp"`
23 ppid int `bson:"ppid"`
24 parentTgid int `bson:"parentTgid"`
25 pid int `bson:"pid"`
26 tgid int `bson:"tgid"`
27 args []string `bson:"args"`
28 comm string `bson:"comm"`
29 cwd string `bson:"cwd"`
30 execve []Exec `bson:"execve"`
31 exit_code int `bson:"exit_code"`
32 exit_signal int `bson:"exit_signal"`
33 exit_timestamp time.Time `bson:"exit_timestamp"`
34}
35
36func (p Process) String() string {
37 var res string
38 res = ""
39 res += fmt.Sprintf("timestamp\t%v\n", p.timestamp)
40 res += fmt.Sprintf("ppid\t%d\nparentTgid\t%d\n", p.ppid, p.parentTgid)
41 res += fmt.Sprintf("pid\t%d\ntgid\t%d\nargs: ", p.pid, p.tgid)
42 for i := 0; i < len(p.args); i++ {
43 res += fmt.Sprintf("%s ", p.args[i])
44 }
45 res += fmt.Sprintf("\ncomm\t%s\ncwd\t%s\n", p.comm, p.cwd)
46 return res
47}
48
49// type Process struct {
50// StartTimestamp time.Time `bson:"start_timestamp"`
51// Ppid *int `bson:"ppid"`
52// ParentTgid *int `bson:"parentTgid"`
53// Pid int `bson:"pid"`
54// Tgid int `bson:"tgid"`
55// Args []string `bson:"args"`
56// Comm *string `bson:"comm"`
57// Cwd *string `bson:"cwd"`
58// Execve []Exec `bson:"execve"`
59// ExitCode *int `bson:"exit_code"`
60// ExitSignal *int `bson:"exit_signal"`
61// ExitTimestamp *time.Time `bson:"exit_timestamp"`
62// }
63
64// func (p Process) String() string {
65// var res string
66// res = ""
67// res += fmt.Sprintf("timestamp\t%v\n", p.StartTimestamp)
68// if p.Ppid != nil && p.ParentTgid != nil {
69// res += fmt.Sprintf("ppid\t%d\nparentTgid\t%d\n", *(p.Ppid), *(p.ParentTgid))
70// }
71// res += fmt.Sprintf("pid\t%d\ntgid\t%d\nargs: ", p.Pid, p.Tgid)
72// for i := 0; i < len(p.Args); i++ {
73// res += fmt.Sprintf("%s ", p.Args[i])
74// }
75// if p.Comm != nil && p.Cwd != nil {
76// res += fmt.Sprintf("\ncomm\t%s\ncwd\t%s\n", *(p.Comm), *(p.Cwd))
77// }
78// return res
79// }
80
81func main() {
82 client, err := mongo.Connect(context.TODO(), options.Client().ApplyURI("mongodb://localhost:27017"))
83 if err != nil {
84 fmt.Fprintf(os.Stderr, "Err connecting mongodb: %v\n", err)
85 }
86 defer client.Disconnect(context.TODO())
87
88 // 检查连接
89 err = client.Ping(context.TODO(), readpref.Primary())
90 if err != nil {
91 log.Fatal(err)
92 }
93
94 pidCol := client.Database("test").Collection("pids")
95 cur, err := pidCol.Find(context.TODO(), bson.M{}) // 查询所有文档
96 if err != nil {
97 log.Fatal(err)
98 }
99 defer cur.Close(context.TODO()) // 确保游标被关闭
100
101 var res []Process
102 for cur.Next(context.TODO()) {
103 var tmp Process
104 // 解码到Process结构体
105 if err := cur.Decode(&tmp); err != nil {
106 log.Fatal(err)
107 }
108 res = append(res, tmp)
109 }
110
111 if err := cur.Err(); err != nil {
112 log.Fatal(err)
113 }
114
115 for i := 0; i < len(res); i++ {
116 fmt.Printf("------\n%v\n", res[i])
117 }
118}
diff --git a/filter/go.mod b/filter/go.mod
new file mode 100644
index 0000000..4e9c553
--- /dev/null
+++ b/filter/go.mod
@@ -0,0 +1,18 @@
1module filter
2
3go 1.21.5
4
5require go.mongodb.org/mongo-driver v1.16.1
6
7require (
8 github.com/golang/snappy v0.0.4 // indirect
9 github.com/klauspost/compress v1.13.6 // indirect
10 github.com/montanaflynn/stats v0.7.1 // indirect
11 github.com/xdg-go/pbkdf2 v1.0.0 // indirect
12 github.com/xdg-go/scram v1.1.2 // indirect
13 github.com/xdg-go/stringprep v1.0.4 // indirect
14 github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d // indirect
15 golang.org/x/crypto v0.22.0 // indirect
16 golang.org/x/sync v0.7.0 // indirect
17 golang.org/x/text v0.14.0 // indirect
18)
diff --git a/filter/go.sum b/filter/go.sum
new file mode 100644
index 0000000..3bc8cc9
--- /dev/null
+++ b/filter/go.sum
@@ -0,0 +1,50 @@
1github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
2github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
3github.com/golang/snappy v0.0.4 h1:yAGX7huGHXlcLOEtBnF4w7FQwA26wojNCwOYAEhLjQM=
4github.com/golang/snappy v0.0.4/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
5github.com/google/go-cmp v0.6.0 h1:ofyhxvXcZhMsU5ulbFiLKl/XBFqE1GSq7atu8tAmTRI=
6github.com/google/go-cmp v0.6.0/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY=
7github.com/klauspost/compress v1.13.6 h1:P76CopJELS0TiO2mebmnzgWaajssP/EszplttgQxcgc=
8github.com/klauspost/compress v1.13.6/go.mod h1:/3/Vjq9QcHkK5uEr5lBEmyoZ1iFhe47etQ6QUkpK6sk=
9github.com/montanaflynn/stats v0.7.1 h1:etflOAAHORrCC44V+aR6Ftzort912ZU+YLiSTuV8eaE=
10github.com/montanaflynn/stats v0.7.1/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow=
11github.com/xdg-go/pbkdf2 v1.0.0 h1:Su7DPu48wXMwC3bs7MCNG+z4FhcyEuz5dlvchbq0B0c=
12github.com/xdg-go/pbkdf2 v1.0.0/go.mod h1:jrpuAogTd400dnrH08LKmI/xc1MbPOebTwRqcT5RDeI=
13github.com/xdg-go/scram v1.1.2 h1:FHX5I5B4i4hKRVRBCFRxq1iQRej7WO3hhBuJf+UUySY=
14github.com/xdg-go/scram v1.1.2/go.mod h1:RT/sEzTbU5y00aCK8UOx6R7YryM0iF1N2MOmC3kKLN4=
15github.com/xdg-go/stringprep v1.0.4 h1:XLI/Ng3O1Atzq0oBs3TWm+5ZVgkq2aqdlvP9JtoZ6c8=
16github.com/xdg-go/stringprep v1.0.4/go.mod h1:mPGuuIYwz7CmR2bT9j4GbQqutWS1zV24gijq1dTyGkM=
17github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d h1:splanxYIlg+5LfHAM6xpdFEAYOk8iySO56hMFq6uLyA=
18github.com/youmark/pkcs8 v0.0.0-20181117223130-1be2e3e5546d/go.mod h1:rHwXgn7JulP+udvsHwJoVG1YGAP6VLg4y9I5dyZdqmA=
19github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
20go.mongodb.org/mongo-driver v1.16.1 h1:rIVLL3q0IHM39dvE+z2ulZLp9ENZKThVfuvN/IiN4l8=
21go.mongodb.org/mongo-driver v1.16.1/go.mod h1:oB6AhJQvFQL4LEHyXi6aJzQJtBiTQHiAd83l0GdFaiw=
22golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
23golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
24golang.org/x/crypto v0.22.0 h1:g1v0xeRhjcugydODzvb3mEM9SQ0HGp9s/nh3COQ/C30=
25golang.org/x/crypto v0.22.0/go.mod h1:vr6Su+7cTlO45qkww3VDJlzDn0ctJvRgYbC2NvXHt+M=
26golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
27golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
28golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg=
29golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
30golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
31golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
32golang.org/x/sync v0.7.0 h1:YsImfSBoP9QPYL0xyKJPq0gcaJdG3rInoqxTWbfQu9M=
33golang.org/x/sync v0.7.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk=
34golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
35golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
36golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
37golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
38golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
39golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
40golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
41golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
42golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
43golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
44golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ=
45golang.org/x/text v0.14.0 h1:ScX5w1eTa3QqT8oi6+ziP7dTV1S2+ALU0bI+0zXKWiQ=
46golang.org/x/text v0.14.0/go.mod h1:18ZOQIKpY8NJVqYksKHtTdi31H5itFRjB5/qKTNYzSU=
47golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
48golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
49golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
50golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
diff --git a/src/audit.go b/listener/audit.go
index ed48691..ed48691 100644
--- a/src/audit.go
+++ b/listener/audit.go
diff --git a/src/basefunc.go b/listener/basefunc.go
index 2f39507..2f39507 100644
--- a/src/basefunc.go
+++ b/listener/basefunc.go
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
19var pidCol, fdCol, fileCol mongoClient 19var pidCol, fdCol, fileCol mongoClient
20
21var docRes []bson.M
22var err error 20var err error
23 21
24func deal() { 22func 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
83func deletePid(cooked Event) { 80func 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
105func dealNewPid(cooked Event) { 96func 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
151func dealExecve(cooked Event) { 149func 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
190func fileOpen(cooked Event) { 188func 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
221func fileWrite(cooked Event) { 222func 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
240func pivotRoot(cooked Event) { 244func 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 }
diff --git a/listener/global.go b/listener/global.go
new file mode 100644
index 0000000..11b18bf
--- /dev/null
+++ b/listener/global.go
@@ -0,0 +1,84 @@
1package main
2
3import (
4 "sync"
5 "time"
6)
7
8type eventType int
9
10const (
11 NEWPID eventType = iota
12 PIDEXIT
13 EXECVE
14 FILEOPEN
15 FILECLOSE
16 FILEWRITE
17 PIVOTROOT
18 TYPENUM
19)
20
21func (et eventType) String() string {
22 names := []string{"NEWPID", "PIDEXIT", "EXECVE", "FILEOPEN", "FILECLOSE", "FILEWRITE", "PIVOTROOT", "TYPENUM"}
23 if et < NEWPID || et > TYPENUM {
24 return "Unknown"
25 }
26 return names[et]
27}
28
29type Event struct {
30 tag eventType
31 timestamp time.Time
32 pid, tgid int
33 ppid, parentTgid int
34 syscall int
35 syscallParam [4]uint64
36 argc int
37 argv []string
38 comm string
39 cwd string
40 exit_code int
41 exit_signal int
42 srcPath string
43 destPath string
44}
45
46var wg sync.WaitGroup // 掌管协程
47var rawChan chan interface{} // 从接收到整理的管道
48var cookedChan chan Event // 整理好的信息的管道
49var syscallTable [500]string //记录一下系统调用
50var containerdPid int
51
52// 插入到数据库的结构
53type Exec struct {
54 Timestamp time.Time `bson:"timestamp"`
55 ExecArgs []string `bson:"execArgs"`
56}
57
58type Process struct {
59 Star bool `bson:"star"`
60 StartTimestamp time.Time `bson:"start_timestamp"`
61 Ppid int `bson:"ppid"`
62 ParentTgid int `bson:"parentTgid"`
63 Pid int `bson:"pid"`
64 Tgid int `bson:"tgid"`
65 Args []string `bson:"args"`
66 Comm string `bson:"comm"`
67 RootFS string `bson:"rootfs"`
68 Cwd string `bson:"cwd"`
69 Children []int `bson:"children"`
70 Execve []Exec `bson:"execve"`
71 ExitCode int `bson:"exit_code"`
72 ExitSignal int `bson:"exit_signal"`
73 ExitTimestamp time.Time `bson:"exit_timestamp"`
74}
75
76type File struct {
77 OpenTimestamp time.Time `bson:"timestamp"`
78 FileName string `bson:"fileName"`
79 Pid int `bson:"pid"`
80 Fd int `bson:"fd"`
81 Flags [4]uint64 `bson:"flags"`
82 Written []time.Time `bson:"written"`
83 CloseTimestamp time.Time `bson:"close_timestamp"`
84}
diff --git a/src/go.mod b/listener/go.mod
index ed40331..ed40331 100644
--- a/src/go.mod
+++ b/listener/go.mod
diff --git a/src/go.sum b/listener/go.sum
index 9164cd3..9164cd3 100644
--- a/src/go.sum
+++ b/listener/go.sum
diff --git a/src/go.work b/listener/go.work
index 5b6c957..5b6c957 100644
--- a/src/go.work
+++ b/listener/go.work
diff --git a/src/go.work.sum b/listener/go.work.sum
index 8201e39..8201e39 100644
--- a/src/go.work.sum
+++ b/listener/go.work.sum
diff --git a/src/godo.go b/listener/godo.go
index a30aa88..efe9585 100644
--- a/src/godo.go
+++ b/listener/godo.go
@@ -128,7 +128,7 @@ func procWatch() error {
128 tag: PIDEXIT, 128 tag: PIDEXIT,
129 timestamp: time.Now(), 129 timestamp: time.Now(),
130 pid: int(data.ProcessPid), 130 pid: int(data.ProcessPid),
131 exit_code: uint64(data.ExitCode), 131 exit_code: int(data.ExitCode),
132 exit_signal: int(data.ExitSignal), 132 exit_signal: int(data.ExitSignal),
133 } 133 }
134 cookedChan <- cooked 134 cookedChan <- cooked
@@ -139,8 +139,8 @@ func procWatch() error {
139} 139}
140 140
141func checkProc(pCooked *Event) { 141func checkProc(pCooked *Event) {
142 fileName := fmt.Sprintf("/proc/%d/task/%d/cmdline", pCooked.tgid, pCooked.pid) 142 fileName := fmt.Sprintf("/proc/%d/task/%d/", pCooked.tgid, pCooked.pid)
143 fd, err := os.Open(fileName) 143 fd, err := os.Open(fileName + "cmdline")
144 if err != nil { 144 if err != nil {
145 fmt.Fprintf(os.Stderr, "Err: %v\n", err) 145 fmt.Fprintf(os.Stderr, "Err: %v\n", err)
146 return 146 return
@@ -155,8 +155,20 @@ func checkProc(pCooked *Event) {
155 pCooked.argc = len(pCooked.argv) 155 pCooked.argc = len(pCooked.argv)
156 fd.Close() 156 fd.Close()
157 157
158 fileName = fmt.Sprintf("/proc/%d/task/%d/cwd", pCooked.tgid, pCooked.pid) 158 fd, err = os.Open(fileName + "comm")
159 pCooked.cwd, err = os.Readlink(fileName) 159 if err != nil {
160 fmt.Fprintf(os.Stderr, "Err: %v\n", err)
161 return
162 }
163 scanner = bufio.NewScanner(fd)
164 scanner.Split(bufio.ScanLines)
165 for scanner.Scan() {
166 line := scanner.Text()
167 pCooked.comm = line
168 }
169 fd.Close()
170
171 pCooked.cwd, err = os.Readlink(fileName + "cwd")
160 if err != nil { 172 if err != nil {
161 fmt.Fprintf(os.Stderr, "Err: %v\n", err) 173 fmt.Fprintf(os.Stderr, "Err: %v\n", err)
162 pCooked.cwd = "" 174 pCooked.cwd = ""
diff --git a/src/mongo.go b/listener/mongo.go
index 1d9f74f..a51350e 100644
--- a/src/mongo.go
+++ b/listener/mongo.go
@@ -2,6 +2,8 @@ package main
2 2
3import ( 3import (
4 "context" 4 "context"
5 "fmt"
6 "reflect"
5 "time" 7 "time"
6 8
7 "go.mongodb.org/mongo-driver/bson" 9 "go.mongodb.org/mongo-driver/bson"
@@ -62,16 +64,38 @@ func (mc *mongoClient) UpdateMany(filter, update interface{}) error {
62 return err 64 return err
63} 65}
64 66
65func (mc *mongoClient) Finddoc(filter bson.M) ([]bson.M, error) { 67func (mc *mongoClient) ReplaceOne(filter, new interface{}) error {
66 cur, err := mc.col.Find(context.Background(), filter) 68 _, err := mc.col.ReplaceOne(context.Background(), filter, new)
69 return err
70}
71
72func (mc *mongoClient) Finddoc(filter bson.M, results interface{}) error {
73 sliceValue := reflect.ValueOf(results)
74
75 if sliceValue.Kind() != reflect.Ptr || sliceValue.Elem().Kind() != reflect.Slice {
76 return fmt.Errorf("Error: result argument must be pointer to slice")
77 }
78 cur, err := mc.col.Find(context.TODO(), filter)
67 if err != nil { 79 if err != nil {
68 return nil, err 80 return err
69 } 81 }
82 defer cur.Close(context.TODO())
83
84 elemType := sliceValue.Elem().Type().Elem()
70 85
71 var results []bson.M 86 sliceValue = sliceValue.Elem()
72 err = cur.All(context.Background(), &results)
73 87
74 return results, err 88 for cur.Next(context.TODO()) {
89 elem := reflect.New(elemType).Interface()
90 err := cur.Decode(elem)
91 if err != nil {
92 return err
93 }
94 sliceValue = reflect.Append(sliceValue, reflect.ValueOf(elem).Elem())
95 }
96
97 reflect.ValueOf(results).Elem().Set(sliceValue)
98 return nil
75} 99}
76 100
77func (mc *mongoClient) FindOneAndDelete(filter bson.M) (bson.M, error) { 101func (mc *mongoClient) FindOneAndDelete(filter bson.M) (bson.M, error) {
diff --git a/src/netlink b/listener/netlink
Subproject e53c2724725c5991cdd9ea088c26832c5c9fcf0 Subproject e53c2724725c5991cdd9ea088c26832c5c9fcf0
diff --git a/src/organize.go b/listener/organize.go
index 293371b..0c05eb4 100644
--- a/src/organize.go
+++ b/listener/organize.go
@@ -23,14 +23,12 @@ var event Event
23var pEvent *Event 23var pEvent *Event
24var eventId, argc int 24var eventId, argc int
25 25
26// var errs [6]error
27
28// 要用的正则匹配列表 26// 要用的正则匹配列表
29var ( 27var (
30 syscallRegex = regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+)(?:.*?exit=([-+]?\d+))?.*?ppid=(\d+) pid=(\d+).*?subj=(.*?):(.*?):(.*?):(.*?) .*?$`) 28 syscallRegex = regexp.MustCompile(`audit\((\d+\.\d+):(\d+)\).*?syscall=(\d+)(?:.*?exit=([-+]?\d+))?.*?ppid=(\d+) pid=(\d+).*?subj=(.*?):(.*?):(.*?):(.*?) .*?$`)
31 execveRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`) 29 execveRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): argc=(\d+)`)
32 argsRegex = regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`) 30 argsRegex = regexp.MustCompile(`a\d+=("(.*?)"|([0-9a-fA-F]+))`)
33 pathRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): item=(\d+) name="(.*?)"`) 31 pathRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): item=(\d+) name="(.*?)" .*objtype=([A-Z]+) `)
34 cwdRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`) 32 cwdRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): cwd="(.*?)"`)
35 proctitleRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`) 33 proctitleRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\): proctitle=("(.*?)"|([0-9a-fA-F]+))$`)
36 eoeRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`) 34 eoeRegex = regexp.MustCompile(`audit\(\d+\.\d+:(\d+)\)`)
@@ -112,12 +110,12 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
112 tag: EXECVE, 110 tag: EXECVE,
113 timestamp: event.timestamp, 111 timestamp: event.timestamp,
114 syscall: event.syscall, 112 syscall: event.syscall,
115 exit_code: a[0], 113 // exit_code: a[0], // 为啥这么写?
116 ppid: event.ppid, 114 ppid: event.ppid,
117 pid: event.pid, 115 pid: event.pid,
118 argc: 0, 116 argc: 0,
119 argv: make([]string, 0), 117 argv: make([]string, 0),
120 cwd: "", 118 cwd: "",
121 }) 119 })
122 case "open": 120 case "open":
123 // 检查打开的权限 121 // 检查打开的权限
@@ -129,7 +127,7 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
129 tag: FILEOPEN, 127 tag: FILEOPEN,
130 timestamp: event.timestamp, 128 timestamp: event.timestamp,
131 syscall: event.syscall, 129 syscall: event.syscall,
132 exit_code: uint64(exit), 130 exit_code: exit,
133 ppid: event.ppid, 131 ppid: event.ppid,
134 pid: event.pid, 132 pid: event.pid,
135 argc: 0, 133 argc: 0,
@@ -143,7 +141,7 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
143 tag: FILEWRITE, 141 tag: FILEWRITE,
144 timestamp: event.timestamp, 142 timestamp: event.timestamp,
145 syscall: event.syscall, 143 syscall: event.syscall,
146 exit_code: uint64(exit), 144 exit_code: exit,
147 ppid: event.ppid, 145 ppid: event.ppid,
148 pid: event.pid, 146 pid: event.pid,
149 argc: 0, 147 argc: 0,
@@ -157,7 +155,7 @@ func syscallRaw(rawEvent libaudit.RawAuditMessage) {
157 tag: FILECLOSE, 155 tag: FILECLOSE,
158 timestamp: event.timestamp, 156 timestamp: event.timestamp,
159 syscall: event.syscall, 157 syscall: event.syscall,
160 exit_code: uint64(exit), 158 exit_code: exit,
161 ppid: event.ppid, 159 ppid: event.ppid,
162 pid: event.pid, 160 pid: event.pid,
163 argc: 0, 161 argc: 0,
@@ -271,6 +269,7 @@ func path(rawEvent libaudit.RawAuditMessage) {
271 eventId, _ = strconv.Atoi(string(match[1])) 269 eventId, _ = strconv.Atoi(string(match[1]))
272 // item, _ := strconv.Atoi(string(match[2])) 270 // item, _ := strconv.Atoi(string(match[2]))
273 name := string(match[3]) 271 name := string(match[3])
272 objtype := string(match[4])
274 273
275 tmp, ok = eventTable.Load(eventId) 274 tmp, ok = eventTable.Load(eventId)
276 if !ok { 275 if !ok {
@@ -278,14 +277,15 @@ func path(rawEvent libaudit.RawAuditMessage) {
278 } 277 }
279 pEvent = tmp.(*Event) 278 pEvent = tmp.(*Event)
280 279
281 // 先看看是不是文件操作 280 // 先看看是不是文件操作,再看是不是所在目录
282 if pEvent.tag != FILEOPEN { 281 if pEvent.tag != FILEOPEN || objtype == "PARENT" {
283 return 282 return
284 } 283 }
285 284
286 if name[0] == '/' { 285 if pEvent.cwd == "/" || name[0] == '/' {
287 pEvent.srcPath = name 286 pEvent.srcPath = name
288 } else { 287 } else {
289 pEvent.srcPath += "/" + name 288 pEvent.srcPath = pEvent.cwd + "/" + name
290 } 289 }
290 // ATTENTION: 这里需要做路径简化,留给过滤清洗流程吧
291} 291}
diff --git a/src/receive.go b/listener/receive.go
index c0dea00..c0dea00 100644
--- a/src/receive.go
+++ b/listener/receive.go
diff --git a/src/global.go b/src/global.go
deleted file mode 100644
index 349ba6c..0000000
--- a/src/global.go
+++ /dev/null
@@ -1,49 +0,0 @@
1package main
2
3import (
4 "sync"
5 "time"
6)
7
8type eventType int
9
10const (
11 NEWPID eventType = iota
12 PIDEXIT
13 EXECVE
14 FILEOPEN
15 FILECLOSE
16 FILEWRITE
17 PIVOTROOT
18 TYPENUM
19)
20
21func (et eventType) String() string {
22 names := []string{"NEWPID", "PIDEXIT", "EXECVE", "FILEOPEN", "FILECLOSE", "FILEWRITE", "PIVOTROOT", "TYPENUM"}
23 if et < NEWPID || et > TYPENUM {
24 return "Unknown"
25 }
26 return names[et]
27}
28
29type Event struct {
30 tag eventType
31 timestamp time.Time
32 pid, tgid int
33 ppid, parentTgid int
34 syscall int
35 syscallParam [4]uint64
36 argc int
37 argv []string
38 cwd string
39 exit_code uint64
40 exit_signal int
41 srcPath string
42 destPath string
43}
44
45var wg sync.WaitGroup // 掌管协程
46var rawChan chan interface{} // 从接收到整理的管道
47var cookedChan chan Event // 整理好的信息的管道
48var syscallTable [500]string //记录一下系统调用
49var containerdPid int