diff options
author | We-unite <3205135446@qq.com> | 2024-08-19 19:41:01 +0800 |
---|---|---|
committer | We-unite <3205135446@qq.com> | 2024-08-22 14:12:01 +0800 |
commit | f9f8f35ccd8b505a827d40f95c52ed039512b79d (patch) | |
tree | 241c393f6b865958191df802cd112f26d40dddc4 /listener | |
parent | ae4957b41156d576e849ec0424edd4d89d8d49f2 (diff) | |
download | godo-f9f8f35ccd8b505a827d40f95c52ed039512b79d.tar.gz godo-f9f8f35ccd8b505a827d40f95c52ed039512b79d.zip |
Write documents of the program.
Add README.md on the design of the whole program, and how its every
part(listener, filter) works, finally how to compile and use them.
Besides, notes.md records the things and technology learned in this
program, such as how to read kernel src, how the pthread_create/fork/
clone syscall works on processes and threads, the techs used to make
docker container works well, and books to be read. Good good study,
day day up.
Diffstat (limited to 'listener')
-rw-r--r-- | listener/audit.go | 16 | ||||
-rw-r--r-- | listener/deal.go | 35 | ||||
-rw-r--r-- | listener/global.go | 20 | ||||
-rw-r--r-- | listener/godo.go | 37 | ||||
-rw-r--r-- | listener/mongo.go | 15 | ||||
-rw-r--r-- | listener/organize.go | 20 |
6 files changed, 86 insertions, 57 deletions
diff --git a/listener/audit.go b/listener/audit.go index ed48691..148378c 100644 --- a/listener/audit.go +++ b/listener/audit.go | |||
@@ -13,14 +13,14 @@ func read() error { | |||
13 | // Write netlink response to a file for further analysis or for writing | 13 | // Write netlink response to a file for further analysis or for writing |
14 | // tests cases. | 14 | // tests cases. |
15 | var diagWriter io.Writer | 15 | var diagWriter io.Writer |
16 | if *diag != "" { | 16 | // if *diag != "" { |
17 | f, err := os.OpenFile(*diag, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o600) | 17 | // f, err := os.OpenFile(*diag, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o664) |
18 | if err != nil { | 18 | // if err != nil { |
19 | return err | 19 | // return err |
20 | } | 20 | // } |
21 | defer f.Close() | 21 | // defer f.Close() |
22 | diagWriter = f | 22 | // diagWriter = f |
23 | } | 23 | // } |
24 | 24 | ||
25 | log.Println("starting netlink client") | 25 | log.Println("starting netlink client") |
26 | 26 | ||
diff --git a/listener/deal.go b/listener/deal.go index 70c2827..af65ff8 100644 --- a/listener/deal.go +++ b/listener/deal.go | |||
@@ -10,17 +10,8 @@ import ( | |||
10 | "go.mongodb.org/mongo-driver/bson" | 10 | "go.mongodb.org/mongo-driver/bson" |
11 | ) | 11 | ) |
12 | 12 | ||
13 | const ( | ||
14 | dbName string = "test" | ||
15 | pidColName string = "pids" | ||
16 | fdColName string = "fds" | ||
17 | fileColName string = "files" | ||
18 | ) | ||
19 | |||
20 | var pidCol, fdCol, fileCol mongoClient | ||
21 | |||
22 | func initPidCol() (err error) { | 13 | func initPidCol() (err error) { |
23 | // TODO: 这里是否需要补全一下进程信息? | 14 | // 这里是否需要补全一下进程信息? |
24 | dirs, err := os.ReadDir(fmt.Sprintf("/proc/%d/task", containerdPid)) | 15 | dirs, err := os.ReadDir(fmt.Sprintf("/proc/%d/task", containerdPid)) |
25 | if err != nil { | 16 | if err != nil { |
26 | return err | 17 | return err |
@@ -41,6 +32,9 @@ func initPidCol() (err error) { | |||
41 | process.Star = true | 32 | process.Star = true |
42 | } | 33 | } |
43 | err = pidCol.InsertOne(process) | 34 | err = pidCol.InsertOne(process) |
35 | if err != nil { | ||
36 | return err | ||
37 | } | ||
44 | } | 38 | } |
45 | return nil | 39 | return nil |
46 | } | 40 | } |
@@ -49,27 +43,6 @@ func deal() { | |||
49 | defer wg.Done() | 43 | defer wg.Done() |
50 | var cooked Event | 44 | var cooked Event |
51 | var ok bool | 45 | var ok bool |
52 | var err error | ||
53 | |||
54 | if err = pidCol.init(dbName, pidColName); err != nil { | ||
55 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
56 | return | ||
57 | } | ||
58 | if err = initPidCol(); err != nil { | ||
59 | fmt.Fprintf(os.Stderr, "Err while initing pidcol: %v\n", err) | ||
60 | } | ||
61 | |||
62 | if err = fdCol.init(dbName, fdColName); err != nil { | ||
63 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
64 | return | ||
65 | } | ||
66 | if err = fileCol.init(dbName, fileColName); err != nil { | ||
67 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
68 | } | ||
69 | |||
70 | defer pidCol.Disconnect() | ||
71 | defer fdCol.Disconnect() | ||
72 | defer fileCol.Disconnect() | ||
73 | 46 | ||
74 | for { | 47 | for { |
75 | cooked, ok = <-cookedChan | 48 | cooked, ok = <-cookedChan |
diff --git a/listener/global.go b/listener/global.go index b782284..49d6e94 100644 --- a/listener/global.go +++ b/listener/global.go | |||
@@ -44,12 +44,6 @@ type Event struct { | |||
44 | destPath string | 44 | destPath string |
45 | } | 45 | } |
46 | 46 | ||
47 | var wg sync.WaitGroup // 掌管协程 | ||
48 | var rawChan chan interface{} // 从接收到整理的管道 | ||
49 | var cookedChan chan Event // 整理好的信息的管道 | ||
50 | var syscallTable [500]string //记录一下系统调用 | ||
51 | var containerdPid int | ||
52 | |||
53 | // 插入到数据库的结构 | 47 | // 插入到数据库的结构 |
54 | type Exec struct { | 48 | type Exec struct { |
55 | Timestamp time.Time `bson:"timestamp"` | 49 | Timestamp time.Time `bson:"timestamp"` |
@@ -84,3 +78,17 @@ type File struct { | |||
84 | Written []time.Time `bson:"written"` | 78 | Written []time.Time `bson:"written"` |
85 | CloseTimestamp time.Time `bson:"close_timestamp"` | 79 | CloseTimestamp time.Time `bson:"close_timestamp"` |
86 | } | 80 | } |
81 | |||
82 | const ( | ||
83 | dbName string = "test" | ||
84 | pidColName string = "pids" | ||
85 | fdColName string = "fds" | ||
86 | fileColName string = "files" | ||
87 | ) | ||
88 | |||
89 | var wg sync.WaitGroup // 掌管协程 | ||
90 | var rawChan chan interface{} // 从接收到整理的管道 | ||
91 | var cookedChan chan Event // 整理好的信息的管道 | ||
92 | var syscallTable [500]string //记录一下系统调用 | ||
93 | var containerdPid int // 容器守护进程进程号 | ||
94 | var pidCol, fdCol, fileCol mongoClient // 数据库集合 | ||
diff --git a/listener/godo.go b/listener/godo.go index 8d82231..0e1dc73 100644 --- a/listener/godo.go +++ b/listener/godo.go | |||
@@ -18,14 +18,15 @@ import ( | |||
18 | 18 | ||
19 | var ( | 19 | var ( |
20 | fs = flag.NewFlagSet("audit", flag.ExitOnError) | 20 | fs = flag.NewFlagSet("audit", flag.ExitOnError) |
21 | diag = fs.String("diag", "", "dump raw information from kernel to file") | 21 | diag = fs.String("diag", "godo.log", "dump raw information from kernel to file") |
22 | rate = fs.Uint("rate", 0, "rate limit in kernel (default 0, no rate limit)") | 22 | rate = fs.Uint("rate", 0, "rate limit in kernel (default 0, no rate limit)") |
23 | backlog = fs.Uint("backlog", 8192, "backlog limit") | 23 | backlog = fs.Uint("backlog", 1<<30, "backlog limit") |
24 | immutable = fs.Bool("immutable", false, "make kernel audit settings immutable (requires reboot to undo)") | 24 | immutable = fs.Bool("immutable", false, "make kernel audit settings immutable (requires reboot to undo)") |
25 | receiveOnly = fs.Bool("ro", false, "receive only using multicast, requires kernel 3.16+") | 25 | receiveOnly = fs.Bool("ro", false, "receive only using multicast, requires kernel 3.16+") |
26 | mongoURI = fs.String("mongo", "localhost:27017", "mongo database uri") | ||
26 | ) | 27 | ) |
27 | 28 | ||
28 | const bufferPages = 100 | 29 | const bufferPages = 1000 |
29 | 30 | ||
30 | func main() { | 31 | func main() { |
31 | // 检查用户身份,并添加auditd规则,监听所有syscall | 32 | // 检查用户身份,并添加auditd规则,监听所有syscall |
@@ -41,7 +42,6 @@ func main() { | |||
41 | } | 42 | } |
42 | 43 | ||
43 | exec.Command("auditctl", "-D").Run() | 44 | exec.Command("auditctl", "-D").Run() |
44 | exec.Command("auditctl", "-b", "1000000000").Run() | ||
45 | exec.Command("auditctl", "--reset-lost").Run() | 45 | exec.Command("auditctl", "--reset-lost").Run() |
46 | 46 | ||
47 | var auditCmd *exec.Cmd | 47 | var auditCmd *exec.Cmd |
@@ -78,24 +78,45 @@ func main() { | |||
78 | } | 78 | } |
79 | } | 79 | } |
80 | 80 | ||
81 | func coroutine(client *libaudit.AuditClient) { | 81 | func coroutine(client *libaudit.AuditClient) error { |
82 | // 各协程至此开始 | 82 | // 各协程至此开始 |
83 | bufferSize := bufferPages * syscall.Getpagesize() | 83 | bufferSize := bufferPages * syscall.Getpagesize() |
84 | rawChan = make(chan interface{}, bufferSize) | 84 | rawChan = make(chan interface{}, bufferSize) |
85 | cookedChan = make(chan Event, bufferSize) | 85 | cookedChan = make(chan Event, bufferSize) |
86 | 86 | ||
87 | var err error | ||
88 | if err = pidCol.init(dbName, pidColName); err != nil { | ||
89 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
90 | return err | ||
91 | } | ||
92 | if err = initPidCol(); err != nil { | ||
93 | fmt.Fprintf(os.Stderr, "Err while initing pidcol: %v\n", err) | ||
94 | } | ||
95 | |||
96 | if err = fdCol.init(dbName, fdColName); err != nil { | ||
97 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
98 | return err | ||
99 | } | ||
100 | if err = fileCol.init(dbName, fileColName); err != nil { | ||
101 | fmt.Fprintf(os.Stderr, "Error while initing the mongodb: %v\n", err) | ||
102 | } | ||
103 | |||
104 | defer pidCol.Disconnect() | ||
105 | defer fdCol.Disconnect() | ||
106 | defer fileCol.Disconnect() | ||
107 | |||
108 | wg.Add(1) | ||
109 | go deal() | ||
87 | wg.Add(1) | 110 | wg.Add(1) |
88 | go procWatch() | 111 | go procWatch() |
89 | |||
90 | wg.Add(1) | 112 | wg.Add(1) |
91 | go receive(client) | 113 | go receive(client) |
92 | wg.Add(1) | 114 | wg.Add(1) |
93 | go orgnaze() | 115 | go orgnaze() |
94 | wg.Add(1) | ||
95 | go deal() | ||
96 | 116 | ||
97 | wg.Wait() | 117 | wg.Wait() |
98 | time.Sleep(2 * time.Second) | 118 | time.Sleep(2 * time.Second) |
119 | return nil | ||
99 | } | 120 | } |
100 | 121 | ||
101 | func procWatch() error { | 122 | func procWatch() error { |
diff --git a/listener/mongo.go b/listener/mongo.go index a51350e..36c471c 100644 --- a/listener/mongo.go +++ b/listener/mongo.go | |||
@@ -31,18 +31,27 @@ func (mc *mongoClient) init(dbName, colName string) error { | |||
31 | 31 | ||
32 | func (mc *mongoClient) Connect(dbName, colName string) error { | 32 | func (mc *mongoClient) Connect(dbName, colName string) error { |
33 | var err error | 33 | var err error |
34 | mc.client, err = mongo.NewClient(options.Client().ApplyURI("mongodb://localhost:27017")) | 34 | // 设置连接MongoDB的参数 |
35 | clientOptions := options.Client().ApplyURI("mongodb://" + *mongoURI) | ||
35 | 36 | ||
37 | // 创建一个带有超时的上下文 | ||
38 | ctx, cancel := context.WithTimeout(context.Background(), 5*time.Second) | ||
39 | defer cancel() // 确保在函数退出时取消上下文 | ||
40 | |||
41 | // 使用带超时的上下文连接到MongoDB | ||
42 | mc.client, err = mongo.Connect(ctx, clientOptions) | ||
36 | if err != nil { | 43 | if err != nil { |
37 | return err | 44 | return err |
38 | } | 45 | } |
39 | 46 | ||
40 | ctx, _ := context.WithTimeout(context.Background(), 10*time.Second) | 47 | // 尝试ping数据库以检查连接是否成功 |
41 | err = mc.client.Connect(ctx) | 48 | err = mc.client.Ping(ctx, nil) |
42 | if err != nil { | 49 | if err != nil { |
43 | return err | 50 | return err |
44 | } | 51 | } |
45 | 52 | ||
53 | fmt.Println("Connected to MongoDB!") | ||
54 | |||
46 | mc.col = mc.client.Database(dbName).Collection(colName) | 55 | mc.col = mc.client.Database(dbName).Collection(colName) |
47 | mc.dbName = dbName | 56 | mc.dbName = dbName |
48 | mc.colName = colName | 57 | mc.colName = colName |
diff --git a/listener/organize.go b/listener/organize.go index 0c05eb4..cf6dad3 100644 --- a/listener/organize.go +++ b/listener/organize.go | |||
@@ -2,6 +2,7 @@ package main | |||
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "fmt" | 4 | "fmt" |
5 | "io" | ||
5 | "os" | 6 | "os" |
6 | "regexp" | 7 | "regexp" |
7 | "strconv" | 8 | "strconv" |
@@ -41,13 +42,30 @@ func orgnaze() { | |||
41 | var raw interface{} | 42 | var raw interface{} |
42 | var rawEvent libaudit.RawAuditMessage | 43 | var rawEvent libaudit.RawAuditMessage |
43 | 44 | ||
45 | var diagWriter io.Writer | ||
46 | var f *os.File | ||
47 | var err error | ||
48 | var fileName string | ||
49 | if *diag != "" { | ||
50 | fileName = *diag | ||
51 | } else { | ||
52 | fileName = "godo.log" | ||
53 | } | ||
54 | |||
55 | f, err = os.OpenFile(fileName, os.O_CREATE|os.O_RDWR|os.O_TRUNC, 0o664) | ||
56 | if err != nil { | ||
57 | f = nil | ||
58 | } | ||
59 | defer f.Close() | ||
60 | diagWriter = f | ||
61 | |||
44 | for { | 62 | for { |
45 | raw, ok = <-rawChan | 63 | raw, ok = <-rawChan |
46 | if !ok { | 64 | if !ok { |
47 | break | 65 | break |
48 | } | 66 | } |
49 | rawEvent = raw.(libaudit.RawAuditMessage) | 67 | rawEvent = raw.(libaudit.RawAuditMessage) |
50 | // fmt.Printf("type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) | 68 | fmt.Fprintf(diagWriter, "type=%v msg=%s\n", rawEvent.Type, rawEvent.Data) |
51 | 69 | ||
52 | switch rawEvent.Type { | 70 | switch rawEvent.Type { |
53 | case auparse.AUDIT_SYSCALL: | 71 | case auparse.AUDIT_SYSCALL: |