summaryrefslogtreecommitdiffstats
path: root/godo.go
diff options
context:
space:
mode:
Diffstat (limited to 'godo.go')
-rw-r--r--godo.go157
1 files changed, 113 insertions, 44 deletions
diff --git a/godo.go b/godo.go
index 2ba97d1..1ae336b 100644
--- a/godo.go
+++ b/godo.go
@@ -34,26 +34,27 @@ type Event struct {
34 pid, ppid int 34 pid, ppid int
35 syscall int 35 syscall int
36 argc int 36 argc int
37 args []string 37 argv []string
38 cwd string 38 cwd string
39} 39}
40 40
41type process struct { 41type process struct {
42 cmdline string 42 timestamp time.Time
43 argv []string 43 pid, ppid int
44 cwd string 44 argv []string
45 rootfs string 45 cwd string
46 children []int 46 rootfs string
47 children []int
47} 48}
48 49
49var pids map[int]*process //古希腊掌管进程的神 50var pids sync.Map // 古希腊掌管进程的神,int->*process
50var containers map[string]int // 古希腊掌管容器的神 51var wg sync.WaitGroup // 掌管协程
51var wg sync.WaitGroup // 掌管协程 52var rawChan chan interface{} // 从接收到整理的管道
52var rawChan chan interface{} // 从接收到整理的管道,这里不是原始数据类型,下文解释 53var cookedChan chan Event // 整理好的信息的管道
53var cookedChan chan Event // 整理好的信息的管道
54
55var syscallTable [500]string //记录一下系统调用 54var syscallTable [500]string //记录一下系统调用
56 55
56var containerdPid int
57
57func main() { 58func main() {
58 // 检查用户身份,并添加auditd规则,监听所有syscall 59 // 检查用户身份,并添加auditd规则,监听所有syscall
59 if os.Geteuid() != 0 { 60 if os.Geteuid() != 0 {
@@ -72,26 +73,42 @@ func main() {
72 auditCmd = exec.Command("auditctl", "-D") // 清空所有规则 73 auditCmd = exec.Command("auditctl", "-D") // 清空所有规则
73 auditCmd.Run() 74 auditCmd.Run()
74 // 设置监听规则 75 // 设置监听规则
75 for i := 0; i < 5; i++ { 76 for i := 0; i < len(syscall); i++ {
76 auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", syscall[i]) 77 auditCmd = exec.Command("auditctl", "-a", "exit,always", "-F", "arch=b64", "-S", syscall[i])
77 auditCmd.Run() 78 auditCmd.Run()
78 } 79 }
79 80
80 // 查找pid 81 // 查找pid
81 containerdPid, err := getPid() 82 containerdPid, err = getPid()
82 if err != nil { 83 if err != nil {
83 fmt.Printf("Error finding containerd: %v\n", err) 84 fmt.Printf("Error finding containerd: %v\n", err)
84 return 85 return
85 } 86 }
86 // 数据结构初始化 87 // 数据结构初始化
87 pids = make(map[int]*process) 88 // pids = make(map[int]*process)
88 containers = make(map[string]int) 89 // containers = make(map[string]int)
89 90
90 // 创世之神,1号进程 91 // 创世之神,1号进程
91 pids[1] = &process{rootfs: "/", children: make([]int, 0)} 92 // pids[1] = &process{rootfs: "/", children: make([]int, 0)}
92 pids[1].children = append(pids[1].children, containerdPid) 93 // pids[1].children = append(pids[1].children, containerdPid)
94 // 1号进程还是不要在进程树上直接出现了,不然它的小儿子们都会出现
95
93 // /usr/bin/containerd,也就是我们最关注的进程 96 // /usr/bin/containerd,也就是我们最关注的进程
94 pids[containerdPid] = &process{cmdline: "/usr/bin/cmdline", rootfs: "/", children: make([]int, 0)} 97 // pids[containerdPid] = &process{rootfs: "/", children: make([]int, 0)}
98 pids.Store(containerdPid, &process{
99 ppid: 1,
100 pid: containerdPid,
101 argv: make([]string, 0),
102 cwd: "/",
103 rootfs: "/",
104 children: make([]int, 0),
105 })
106 p, ok := pids.Load(containerdPid)
107 if !ok {
108 fmt.Printf("???\n")
109 return
110 }
111 p.(*process).argv = append(p.(*process).argv, "/usr/bin/containerd")
95 112
96 // 开始运行,解析命令行参数后监听 113 // 开始运行,解析命令行参数后监听
97 if err := fs.Parse(os.Args[1:]); err != nil { 114 if err := fs.Parse(os.Args[1:]); err != nil {
@@ -148,7 +165,7 @@ func getPid() (int, error) {
148 return pid, nil 165 return pid, nil
149 } 166 }
150 } 167 }
151 err = fmt.Errorf("Error: no containerd process found.\n") 168 err = fmt.Errorf("Error: no containerd process found.")
152 return 0, err 169 return 0, err
153} 170}
154 171
@@ -362,7 +379,7 @@ func orgnaze() {
362 ppid: event.ppid, 379 ppid: event.ppid,
363 pid: event.pid, 380 pid: event.pid,
364 argc: 0, 381 argc: 0,
365 args: make([]string, 0), 382 argv: make([]string, 0),
366 cwd: "", 383 cwd: "",
367 } 384 }
368 } 385 }
@@ -377,10 +394,9 @@ func orgnaze() {
377 if len(match[i][2]) == 0 { 394 if len(match[i][2]) == 0 {
378 // 代表着匹配到的是十六进制数 395 // 代表着匹配到的是十六进制数
379 str := hexToAscii(string(match[i][3])) 396 str := hexToAscii(string(match[i][3]))
380 eventTable[eventId].args = append(eventTable[eventId].args, str) 397 eventTable[eventId].argv = append(eventTable[eventId].argv, str)
381 fmt.Printf("Origin: \"%s\", Res: \"%s\"\n", match[i][3], str)
382 } else { 398 } else {
383 eventTable[eventId].args = append(eventTable[eventId].args, string(match[i][2])) 399 eventTable[eventId].argv = append(eventTable[eventId].argv, string(match[i][2]))
384 } 400 }
385 } 401 }
386 eventTable[eventId].argc = argc 402 eventTable[eventId].argc = argc
@@ -408,30 +424,21 @@ func orgnaze() {
408 } else { 424 } else {
409 cmdline = string(match[3]) 425 cmdline = string(match[3])
410 } 426 }
411 pEvent.args = strings.Split(cmdline, " ") 427 pEvent.argv = strings.Split(cmdline, " ")
412 pEvent.argc = len(eventTable[eventId].args) 428 pEvent.argc = len(eventTable[eventId].argv)
413 }
414 // 当读到proctitle的时候,而且是个新进程最好检查一下cwd,如果还为空,找proc
415 if pEvent.cwd == "" && (pEvent.syscall == 57 || pEvent.syscall == 58 || pEvent.syscall == 59) {
416 cwdFilePath := fmt.Sprintf("/proc/%d/cwd", pEvent.pid)
417 pEvent.cwd, err[1] = os.Readlink(cwdFilePath)
418 if err[1] != nil {
419 pEvent.cwd = ""
420 break
421 }
422 } 429 }
423 } 430 }
424 case auparse.AUDIT_EOE: 431 case auparse.AUDIT_EOE:
425 if eoeRegex.Match(rawEvent.Data) { 432 if eoeRegex.Match(rawEvent.Data) {
426 match := eoeRegex.FindSubmatch(rawEvent.Data) 433 match := eoeRegex.FindSubmatch(rawEvent.Data)
427 eventId, err[0] = strconv.Atoi(string(match[1])) 434 eventId, err[0] = strconv.Atoi(string(match[1]))
428 // TODO: 事件整理完毕,即刻发出,是否合理呢? 435 // ATTENTION: 事件整理完毕,即刻发出,是否合理呢?
429 cooked = *eventTable[eventId] // 应当采用深拷贝吗?有待实验 436 cooked = *eventTable[eventId] // 应当采用深拷贝吗?有待实验
430 cookedChan <- cooked 437 cookedChan <- cooked
431 delete(eventTable, eventId) //发出之后就从信息表扔掉,死人别占地 438 delete(eventTable, eventId) //发出之后就从信息表扔掉,死人别占地
432 } 439 }
433 default: 440 default:
434 // TODO: 这里也需要做防护 441 // ATTENTION: 这里也需要做防护
435 } 442 }
436 } 443 }
437} 444}
@@ -453,14 +460,76 @@ func deal() {
453 // args []string 460 // args []string
454 // cwd string 461 // cwd string
455 // } 462 // }
456 fmt.Printf("recv: %v syscall=%d, ppid=%d, pid=%d, cwd=\"%s\", argc=%d, ", cooked.timestamp, cooked.syscall, cooked.ppid, cooked.pid, cooked.cwd, cooked.argc) 463 // type process struct {
457 if len(cooked.args) != cooked.argc { 464 // timestamp time.Time
458 fmt.Printf("Fuck!\n") 465 // pid, ppid int
459 continue 466 // argv []string
467 // cwd string
468 // rootfs string
469 // children []int
470 // }
471 switch syscallTable[cooked.syscall] {
472 case "fork", "vfork", "clone":
473 ppid := cooked.ppid
474 pid := cooked.pid
475 parent, ok := pids.Load(ppid)
476 if !ok {
477 break
478 }
479 parent.(*process).children = append(parent.(*process).children, pid)
480 pids.Store(pid, &process{
481 timestamp: cooked.timestamp,
482 pid: cooked.pid,
483 ppid: cooked.ppid,
484 argv: cooked.argv,
485 cwd: cooked.cwd,
486 children: make([]int, 0),
487 })
488 fmt.Printf("%v syscall=%d, ppid=%d, pid=%d, cwd=\"%s\", argc=%d, ", cooked.timestamp, cooked.syscall, cooked.ppid, cooked.pid, cooked.cwd, cooked.argc)
489 for i := 0; i < cooked.argc; i++ {
490 fmt.Printf("arg[%d]=\"%s\", ", i, cooked.argv[i])
491 }
492 fmt.Printf("\n")
493 case "exit", "exit_group":
494 _, ok := pids.Load(cooked.pid)
495 if !ok {
496 break
497 }
498 go deletePid(cooked)
499 }
500 }
501}
502
503func deletePid(cooked Event) {
504 time.Sleep(1 * time.Second)
505 Process, ok := pids.Load(cooked.pid)
506 if !ok {
507 return
508 }
509 pProcess := Process.(*process)
510
511 // 先从爹那里注销户籍
512 parent, ok := pids.Load(pProcess.ppid)
513 if ok {
514 pParent := parent.(*process)
515 for i, child := range pParent.children {
516 if child == pProcess.pid {
517 pParent.children = append(pParent.children[:i], pParent.children[i+1:]...)
518 break
519 }
460 } 520 }
461 for i := 0; i < cooked.argc; i++ { 521 }
462 fmt.Printf("arg[%d]=\"%s\", ", i, cooked.args[i]) 522
523 // 子进程需要收容
524 for i := 0; i < len(pProcess.children); i++ {
525 child, ok := pids.Load(pProcess.children[i])
526 if ok {
527 child.(*process).ppid = 1
463 } 528 }
464 fmt.Printf("\n")
465 } 529 }
530
531 // 可以去死了
532 pids.Delete(cooked.pid)
533 _, ok = pids.Load(cooked.pid)
534 fmt.Printf("%v Goodbye, %d! ok = %v\n", time.Now(), cooked.pid, ok)
466} 535}