aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
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