diff options
Diffstat (limited to 'src/godo.go')
-rw-r--r-- | src/godo.go | 82 |
1 files changed, 81 insertions, 1 deletions
diff --git a/src/godo.go b/src/godo.go index 0edcc9f..c332c86 100644 --- a/src/godo.go +++ b/src/godo.go | |||
@@ -1,11 +1,15 @@ | |||
1 | package main | 1 | package main |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "bufio" | ||
4 | "flag" | 5 | "flag" |
5 | "fmt" | 6 | "fmt" |
6 | "log" | 7 | "log" |
8 | "netlink" | ||
7 | "os" | 9 | "os" |
8 | "os/exec" | 10 | "os/exec" |
11 | "strings" | ||
12 | "syscall" | ||
9 | "time" | 13 | "time" |
10 | 14 | ||
11 | "github.com/elastic/go-libaudit/v2" | 15 | "github.com/elastic/go-libaudit/v2" |
@@ -37,7 +41,8 @@ func main() { | |||
37 | auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 | 41 | auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 |
38 | auditCmd.Run() | 42 | auditCmd.Run() |
39 | 43 | ||
40 | pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} | 44 | pidSyscall := []string{"execve"} |
45 | // pidSyscall := []string{"fork", "vfork", "clone", "execve", "exit", "exit_group"} | ||
41 | // 设置监听规则 | 46 | // 设置监听规则 |
42 | for i := 0; i < len(pidSyscall); i++ { | 47 | for i := 0; i < len(pidSyscall); i++ { |
43 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) | 48 | auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", pidSyscall[i]) |
@@ -77,6 +82,10 @@ func coroutine(client *libaudit.AuditClient) { | |||
77 | // 各协程至此开始 | 82 | // 各协程至此开始 |
78 | rawChan = make(chan interface{}) | 83 | rawChan = make(chan interface{}) |
79 | cookedChan = make(chan Event) | 84 | cookedChan = make(chan Event) |
85 | |||
86 | wg.Add(1) | ||
87 | go procWatch() | ||
88 | |||
80 | wg.Add(1) | 89 | wg.Add(1) |
81 | go receive(client) | 90 | go receive(client) |
82 | wg.Add(1) | 91 | wg.Add(1) |
@@ -87,3 +96,74 @@ func coroutine(client *libaudit.AuditClient) { | |||
87 | wg.Wait() | 96 | wg.Wait() |
88 | time.Sleep(2 * time.Second) | 97 | time.Sleep(2 * time.Second) |
89 | } | 98 | } |
99 | |||
100 | func procWatch() error { | ||
101 | ns, err := netlink.NewNetlinkSocket(syscall.NETLINK_CONNECTOR, 12345) | ||
102 | if err != nil { | ||
103 | fmt.Printf("Error creating socket: %v\n", err) | ||
104 | return err | ||
105 | } | ||
106 | defer ns.Close() | ||
107 | for { | ||
108 | res, err := ns.Receive() | ||
109 | if err != nil { | ||
110 | fmt.Printf("Error recv: %v\n", err) | ||
111 | continue | ||
112 | } | ||
113 | for i := 0; i < len(res); i++ { | ||
114 | procEvent := netlink.ParseProcEvent(res[i].Data) | ||
115 | switch procEvent.What { | ||
116 | case netlink.PROC_EVENT_FORK: | ||
117 | data := procEvent.Data.(netlink.ProcEventFork) | ||
118 | cooked := Event{ | ||
119 | tag: NEWPID, | ||
120 | ppid: int(data.ParentTgid), | ||
121 | pid: int(data.ChildPid), | ||
122 | timestamp: time.Now(), | ||
123 | } | ||
124 | checkProc(&cooked) | ||
125 | if data.ChildPid != data.ChildTgid { | ||
126 | cooked.ppid = int(data.ChildTgid) | ||
127 | cooked.pid = int(data.ChildPid) | ||
128 | } | ||
129 | cookedChan <- cooked | ||
130 | case netlink.PROC_EVENT_EXIT: | ||
131 | data := procEvent.Data.(netlink.ProcEventExit) | ||
132 | cooked := Event{ | ||
133 | tag: PIDEXIT, | ||
134 | timestamp: time.Now(), | ||
135 | pid: int(data.ProcessPid), | ||
136 | exit_code: uint64(data.ExitCode), | ||
137 | exit_signal: int(data.ExitSignal), | ||
138 | } | ||
139 | cookedChan <- cooked | ||
140 | default: | ||
141 | } | ||
142 | } | ||
143 | } | ||
144 | } | ||
145 | |||
146 | func checkProc(pCooked *Event) { | ||
147 | fileName := fmt.Sprintf("/proc/%d/cmdline", pCooked.pid) | ||
148 | fd, err := os.Open(fileName) | ||
149 | if err != nil { | ||
150 | fmt.Printf("Err opening file %s: %v\n", fileName, err) | ||
151 | return | ||
152 | } | ||
153 | |||
154 | scanner := bufio.NewScanner(fd) | ||
155 | scanner.Split(bufio.ScanLines) | ||
156 | for scanner.Scan() { | ||
157 | line := scanner.Text() | ||
158 | pCooked.argv = append(pCooked.argv, strings.Split(line, "\x00")...) | ||
159 | } | ||
160 | pCooked.argc = len(pCooked.argv) | ||
161 | fd.Close() | ||
162 | |||
163 | fileName = fmt.Sprintf("/proc/%d/cwd", pCooked.pid) | ||
164 | pCooked.cwd, err = os.Readlink(fileName) | ||
165 | if err != nil { | ||
166 | fmt.Printf("Err readlink %s: %v\n", fileName, err) | ||
167 | pCooked.cwd = "" | ||
168 | } | ||
169 | } | ||