diff options
Diffstat (limited to 'src/godo.go')
-rw-r--r-- | src/godo.go | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/src/godo.go b/src/godo.go new file mode 100644 index 0000000..6f73893 --- /dev/null +++ b/src/godo.go | |||
@@ -0,0 +1,116 @@ | |||
1 | package main | ||
2 | |||
3 | import ( | ||
4 | "flag" | ||
5 | "fmt" | ||
6 | "log" | ||
7 | "os" | ||
8 | "os/exec" | ||
9 | "time" | ||
10 | |||
11 | "github.com/elastic/go-libaudit/v2" | ||
12 | ) | ||
13 | |||
14 | var ( | ||
15 | fs = flag.NewFlagSet("audit", flag.ExitOnError) | ||
16 | diag = fs.String("diag", "", "dump raw information from kernel to file") | ||
17 | rate = fs.Uint("rate", 0, "rate limit in kernel (default 0, no rate limit)") | ||
18 | backlog = fs.Uint("backlog", 8192, "backlog limit") | ||
19 | immutable = fs.Bool("immutable", false, "make kernel audit settings immutable (requires reboot to undo)") | ||
20 | receiveOnly = fs.Bool("ro", false, "receive only using multicast, requires kernel 3.16+") | ||
21 | ) | ||
22 | |||
23 | type Event struct { | ||
24 | timestamp time.Time | ||
25 | pid, ppid int | ||
26 | syscall int | ||
27 | argc int | ||
28 | argv []string | ||
29 | cwd string | ||
30 | } | ||
31 | |||
32 | type process struct { | ||
33 | timestamp time.Time | ||
34 | pid, ppid int | ||
35 | argv []string | ||
36 | cwd string | ||
37 | rootfs string | ||
38 | children []int | ||
39 | } | ||
40 | |||
41 | func main() { | ||
42 | // 检查用户身份,并添加auditd规则,监听所有syscall | ||
43 | if os.Geteuid() != 0 { | ||
44 | fmt.Printf("Err: Please run me as root, %d!\n", os.Getegid()) | ||
45 | return | ||
46 | } | ||
47 | |||
48 | // 所有的系统调用号与名称的关系 | ||
49 | err := figureOutSyscalls() | ||
50 | if err != nil { | ||
51 | fmt.Printf("Error figuring out syscall numbers: %v\n", err) | ||
52 | } | ||
53 | |||
54 | syscall := [6]string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} | ||
55 | var auditCmd *exec.Cmd | ||
56 | auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 | ||
57 | auditCmd.Run() | ||
58 | // 设置监听规则 | ||
59 | for i := 0; i < len(syscall); i++ { | ||
60 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", syscall[i]) | ||
61 | auditCmd.Run() | ||
62 | } | ||
63 | |||
64 | // 查找pid | ||
65 | containerdPid, err = getPid() | ||
66 | if err != nil { | ||
67 | fmt.Printf("Error finding containerd: %v\n", err) | ||
68 | return | ||
69 | } | ||
70 | |||
71 | // 创世之神,1号进程 | ||
72 | // pids[1] = &process{rootfs: "/", children: make([]int, 0)} | ||
73 | // pids[1].children = append(pids[1].children, containerdPid) | ||
74 | // 1号进程还是不要在进程树上直接出现了,不然它的小儿子们都会出现 | ||
75 | |||
76 | // /usr/bin/containerd,也就是我们最关注的进程 | ||
77 | // pids[containerdPid] = &process{rootfs: "/", children: make([]int, 0)} | ||
78 | pids.Store(containerdPid, &process{ | ||
79 | ppid: 1, | ||
80 | pid: containerdPid, | ||
81 | argv: make([]string, 0), | ||
82 | cwd: "/", | ||
83 | rootfs: "/", | ||
84 | children: make([]int, 0), | ||
85 | }) | ||
86 | p, ok := pids.Load(containerdPid) | ||
87 | if !ok { | ||
88 | fmt.Printf("???\n") | ||
89 | return | ||
90 | } | ||
91 | p.(*process).argv = append(p.(*process).argv, "/usr/bin/containerd") | ||
92 | |||
93 | // 开始运行,解析命令行参数后监听 | ||
94 | if err := fs.Parse(os.Args[1:]); err != nil { | ||
95 | log.Fatal(err) | ||
96 | } | ||
97 | |||
98 | if err := read(); err != nil { | ||
99 | log.Fatalf("error: %v", err) | ||
100 | } | ||
101 | } | ||
102 | |||
103 | func coroutine(client *libaudit.AuditClient) { | ||
104 | // 各协程至此开始 | ||
105 | rawChan = make(chan interface{}) | ||
106 | cookedChan = make(chan Event) | ||
107 | wg.Add(1) | ||
108 | go receive(client) | ||
109 | wg.Add(1) | ||
110 | go orgnaze() | ||
111 | wg.Add(1) | ||
112 | go deal() | ||
113 | |||
114 | wg.Wait() | ||
115 | time.Sleep(2 * time.Second) | ||
116 | } | ||