@@ -5,91 +5,30 @@ package guestagent
55
66import (
77 "context"
8- "errors"
98 "os"
109 "reflect"
11- "sync"
12- "syscall"
1310 "time"
1411
15- "github.com/elastic/go-libaudit/v2"
16- "github.com/elastic/go-libaudit/v2/auparse"
1712 "github.com/sirupsen/logrus"
1813 "google.golang.org/protobuf/types/known/timestamppb"
1914
2015 "github.com/lima-vm/lima/v2/pkg/guestagent/api"
21- "github.com/lima-vm/lima/v2/pkg/guestagent/iptables"
2216 "github.com/lima-vm/lima/v2/pkg/guestagent/kubernetesservice"
2317 "github.com/lima-vm/lima/v2/pkg/guestagent/sockets"
2418 "github.com/lima-vm/lima/v2/pkg/guestagent/ticker"
2519 "github.com/lima-vm/lima/v2/pkg/guestagent/timesync"
2620)
2721
28- func New (ctx context.Context , ticker ticker.Ticker , iptablesIdle time. Duration ) (Agent , error ) {
22+ func New (ctx context.Context , ticker ticker.Ticker ) (Agent , error ) {
2923 a := & agent {
3024 ticker : ticker ,
3125 kubernetesServiceWatcher : kubernetesservice .NewServiceWatcher (),
3226 }
3327
34- auditClient , err := libaudit .NewMulticastAuditClient (nil )
35- if err != nil {
36- // syscall.EPROTONOSUPPORT or syscall.EAFNOSUPPORT is returned when calling attempting to connect to NETLINK_AUDIT
37- // on a kernel built without auditing support.
38- // https://github.com/elastic/go-libaudit/blob/ec298e53a6841a1f7715abbc7122635622f349bd/audit.go#L112-L115
39- if ! errors .Is (err , syscall .EPROTONOSUPPORT ) && ! errors .Is (err , syscall .EAFNOSUPPORT ) {
40- return nil , err
41- }
42- logrus .Infof ("Auditing is not available: %s" , err )
43- return startGuestAgentRoutines (ctx , a , false ), nil
44- }
45-
46- auditStatus , err := auditClient .GetStatus ()
47- if err != nil {
48- // syscall.EPERM is returned when using audit from a non-initial namespace
49- // https://github.com/torvalds/linux/blob/633b47cb009d09dc8f4ba9cdb3a0ca138809c7c7/kernel/audit.c#L1054-L1057
50- if ! errors .Is (err , syscall .EPERM ) {
51- return nil , err
52- }
53- logrus .Infof ("Auditing is not permitted: %s" , err )
54- return startGuestAgentRoutines (ctx , a , false ), nil
55- }
56-
57- if auditStatus .Enabled == 0 {
58- logrus .Info ("Enabling auditing" )
59- if err = auditClient .SetEnabled (true , libaudit .WaitForReply ); err != nil {
60- return nil , err
61- }
62- auditStatus , err := auditClient .GetStatus ()
63- if err != nil {
64- return nil , err
65- }
66- if auditStatus .Enabled == 0 {
67- if err = auditClient .SetEnabled (true , libaudit .WaitForReply ); err != nil {
68- return nil , err
69- }
70- }
71- }
72-
73- a .worthCheckingIPTables = true // allow initial iptables scan
74- go a .setWorthCheckingIPTablesRoutine (auditClient , iptablesIdle )
75-
76- logrus .Infof ("Auditing enabled (%d)" , auditStatus .Enabled )
77- return startGuestAgentRoutines (ctx , a , true ), nil
78- }
79-
80- // startGuestAgentRoutines sets worthCheckingIPTables to true if auditing is not supported,
81- // instead of using setWorthCheckingIPTablesRoutine to dynamically set the value.
82- //
83- // Auditing is not supported in a kernels and is not currently supported outside of the initial namespace, so does not work
84- // from inside a container or WSL2 instance, for example.
85- func startGuestAgentRoutines (ctx context.Context , a * agent , supportsAuditing bool ) * agent {
86- if ! supportsAuditing {
87- a .worthCheckingIPTables = true
88- }
8928 go a .kubernetesServiceWatcher .Start (ctx )
9029 go a .fixSystemTimeSkew ()
9130
92- return a
31+ return a , nil
9332}
9433
9534type agent struct {
@@ -98,51 +37,9 @@ type agent struct {
9837 // reload /proc/net/tcp.
9938 ticker ticker.Ticker
10039
101- worthCheckingIPTables bool
102- worthCheckingIPTablesMu sync.RWMutex
103- latestIPTables []iptables.Entry
104- latestIPTablesMu sync.RWMutex
10540 kubernetesServiceWatcher * kubernetesservice.ServiceWatcher
10641}
10742
108- // setWorthCheckingIPTablesRoutine sets worthCheckingIPTables to be true
109- // when received NETFILTER_CFG audit message.
110- //
111- // setWorthCheckingIPTablesRoutine sets worthCheckingIPTables to be false
112- // when no NETFILTER_CFG audit message was received for the iptablesIdle time.
113- func (a * agent ) setWorthCheckingIPTablesRoutine (auditClient * libaudit.AuditClient , iptablesIdle time.Duration ) {
114- logrus .Info ("setWorthCheckingIPTablesRoutine(): monitoring netfilter audit events" )
115- // Initialize to now so the first sleeper loop does not immediately mark it false.
116- latestTrue := time .Now ()
117- go func () {
118- for {
119- time .Sleep (iptablesIdle )
120- a .worthCheckingIPTablesMu .Lock ()
121- // time is monotonic, see https://pkg.go.dev/time#hdr-Monotonic_Clocks
122- elapsedSinceLastTrue := time .Since (latestTrue )
123- if elapsedSinceLastTrue >= iptablesIdle {
124- logrus .Debug ("setWorthCheckingIPTablesRoutine(): setting to false" )
125- a .worthCheckingIPTables = false
126- }
127- a .worthCheckingIPTablesMu .Unlock ()
128- }
129- }()
130- for {
131- msg , err := auditClient .Receive (false )
132- if err != nil {
133- logrus .Error (err )
134- continue
135- }
136- if msg .Type == auparse .AUDIT_NETFILTER_CFG {
137- a .worthCheckingIPTablesMu .Lock ()
138- logrus .Debug ("setWorthCheckingIPTablesRoutine(): setting to true" )
139- a .worthCheckingIPTables = true
140- latestTrue = time .Now ()
141- a .worthCheckingIPTablesMu .Unlock ()
142- }
143- }
144- }
145-
14643type eventState struct {
14744 ports []* api.IPPort
14845}
@@ -220,7 +117,7 @@ func (a *agent) Events(ctx context.Context, ch chan *api.Event) {
220117 }
221118}
222119
223- func (a * agent ) LocalPorts (ctx context.Context ) ([]* api.IPPort , error ) {
120+ func (a * agent ) LocalPorts (_ context.Context ) ([]* api.IPPort , error ) {
224121 var res []* api.IPPort
225122 socketsList , err := sockets .List ()
226123 if err != nil {
@@ -252,47 +149,6 @@ func (a *agent) LocalPorts(ctx context.Context) ([]*api.IPPort, error) {
252149 }
253150 }
254151
255- a .worthCheckingIPTablesMu .RLock ()
256- worthCheckingIPTables := a .worthCheckingIPTables
257- a .worthCheckingIPTablesMu .RUnlock ()
258- logrus .Debugf ("LocalPorts(): worthCheckingIPTables=%v" , worthCheckingIPTables )
259-
260- var ipts []iptables.Entry
261- if a .worthCheckingIPTables {
262- ipts , err = iptables .GetPorts (ctx )
263- if err != nil {
264- return res , err
265- }
266- a .latestIPTablesMu .Lock ()
267- a .latestIPTables = ipts
268- a .latestIPTablesMu .Unlock ()
269- } else {
270- a .latestIPTablesMu .RLock ()
271- ipts = a .latestIPTables
272- a .latestIPTablesMu .RUnlock ()
273- }
274-
275- for _ , ipt := range ipts {
276- port := int32 (ipt .AddrPort .Port ())
277- // Make sure the port isn't already listed from sockets
278- found := false
279- for _ , re := range res {
280- if re .Port == port {
281- found = true
282- }
283- }
284- if ! found {
285- if ipt .TCP {
286- res = append (res ,
287- & api.IPPort {
288- Ip : ipt .AddrPort .Addr ().String (),
289- Port : port ,
290- Protocol : "tcp" ,
291- })
292- }
293- }
294- }
295-
296152 kubernetesEntries := a .kubernetesServiceWatcher .GetPorts ()
297153 for _ , entry := range kubernetesEntries {
298154 found := false
0 commit comments