File: init.go

package info (click to toggle)
opensnitch 1.6.9-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 5,980 kB
  • sloc: python: 12,604; ansic: 1,965; sh: 435; makefile: 239; xml: 50; sql: 3
file content (112 lines) | stat: -rw-r--r-- 2,933 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
package monitor

import (
	"github.com/evilsocket/opensnitch/daemon/log"
	"github.com/evilsocket/opensnitch/daemon/procmon"
	"github.com/evilsocket/opensnitch/daemon/procmon/audit"
	"github.com/evilsocket/opensnitch/daemon/procmon/ebpf"
)

var (
	cacheMonitorsRunning = false
)

// List of errors that this package may return.
const (
	NoError = iota
	ProcFsErr
	AuditdErr
	EbpfErr
	EbpfEventsErr
)

// Error wraps the type of error with its message
type Error struct {
	What int
	Msg  error
}

// ReconfigureMonitorMethod configures a new method for parsing connections.
func ReconfigureMonitorMethod(newMonitorMethod, ebpfModulesPath string) *Error {
	if procmon.GetMonitorMethod() == newMonitorMethod {
		return nil
	}

	oldMethod := procmon.GetMonitorMethod()
	if oldMethod == "" {
		oldMethod = procmon.MethodProc
	}
	End()
	procmon.SetMonitorMethod(newMonitorMethod)
	// if the new monitor method fails to start, rollback the change and exit
	// without saving the configuration. Otherwise we can end up with the wrong
	// monitor method configured and saved to file.
	err := Init(ebpfModulesPath)
	if err.What > NoError {
		log.Error("Reconf() -> Init() error: %v", err)
		procmon.SetMonitorMethod(oldMethod)
		return err
	}

	return nil
}

// End stops the way of parsing new connections.
func End() {
	if procmon.MethodIsAudit() {
		audit.Stop()
	} else if procmon.MethodIsEbpf() {
		ebpf.Stop()
	}
}

// Init starts parsing connections using the method specified.
func Init(ebpfModulesPath string) (errm *Error) {
	errm = &Error{}

	if cacheMonitorsRunning == false {
		go procmon.MonitorActivePids()
		go procmon.CacheCleanerTask()
		cacheMonitorsRunning = true
	}

	if procmon.MethodIsEbpf() {
		err := ebpf.Start(ebpfModulesPath)
		if err == nil {
			log.Info("Process monitor method ebpf")
			return errm
		}
		// ebpf main module loaded, we can use ebpf

		// XXX: this will have to be rewritten when we'll have more events (bind, listen, etc)
		if err.What == ebpf.EventsNotAvailable {
			log.Info("Process monitor method ebpf")
			log.Warning("opensnitch-procs.o not available: %s", err.Msg)

			return errm
		}

		// we need to stop this method even if it has failed to start, in order to clean up the kprobes
		// It helps with the error "cannot write...kprobe_events: file exists".
		ebpf.Stop()
		errm.What = err.What
		errm.Msg = err.Msg
		log.Warning("error starting ebpf monitor method: %v", err)

	} else if procmon.MethodIsAudit() {
		auditConn, err := audit.Start()
		if err == nil {
			log.Info("Process monitor method audit")
			go audit.Reader(auditConn, (chan<- audit.Event)(audit.EventChan))
			return &Error{AuditdErr, err}
		}
		errm.What = AuditdErr
		errm.Msg = err
		log.Warning("error starting audit monitor method: %v", err)
	}

	// if any of the above methods have failed, fallback to proc
	log.Info("Process monitor method /proc")
	procmon.SetMonitorMethod(procmon.MethodProc)
	return errm
}