|
8 | 8 |
|
9 | 9 | "github.com/evilsocket/opensnitch/daemon/firewall"
|
10 | 10 | "github.com/evilsocket/opensnitch/daemon/log"
|
| 11 | + "github.com/evilsocket/opensnitch/daemon/procmon" |
11 | 12 | "github.com/evilsocket/opensnitch/daemon/procmon/monitor"
|
12 | 13 | "github.com/evilsocket/opensnitch/daemon/rule"
|
13 | 14 | "github.com/evilsocket/opensnitch/daemon/ui/config"
|
@@ -55,86 +56,152 @@ func (c *Client) loadDiskConfiguration(reload bool) {
|
55 | 56 | return
|
56 | 57 | }
|
57 | 58 |
|
58 |
| - if ok := c.loadConfiguration(raw); ok { |
| 59 | + err = c.loadConfiguration(reload, raw) |
| 60 | + if err == nil { |
59 | 61 | if err := c.configWatcher.Add(configFile); err != nil {
|
60 | 62 | log.Error("Could not watch path: %s", err)
|
61 | 63 | return
|
62 | 64 | }
|
| 65 | + } else { |
| 66 | + log.Error("[client] error loading config file: %s", err.Error()) |
| 67 | + c.SendWarningAlert(err.Error()) |
63 | 68 | }
|
64 | 69 |
|
65 | 70 | if reload {
|
66 |
| - firewall.Reload( |
67 |
| - clientConfig.Firewall, |
68 |
| - clientConfig.FwOptions.ConfigPath, |
69 |
| - clientConfig.FwOptions.MonitorInterval, |
70 |
| - ) |
71 | 71 | return
|
72 | 72 | }
|
73 |
| - |
74 | 73 | go c.monitorConfigWorker()
|
75 | 74 | }
|
76 | 75 |
|
77 |
| -func (c *Client) loadConfiguration(rawConfig []byte) bool { |
| 76 | +func (c *Client) loadConfiguration(reload bool, rawConfig []byte) error { |
78 | 77 | var err error
|
79 |
| - clientConfig, err = config.Parse(rawConfig) |
| 78 | + newConfig, err := config.Parse(rawConfig) |
80 | 79 | if err != nil {
|
81 |
| - msg := fmt.Sprintf("Error parsing configuration %s: %s", configFile, err) |
82 |
| - log.Error(msg) |
83 |
| - c.SendWarningAlert(msg) |
84 |
| - return false |
| 80 | + return fmt.Errorf("parsing configuration %s: %s", configFile, err) |
85 | 81 | }
|
86 | 82 |
|
87 |
| - clientConfig.Lock() |
88 |
| - defer clientConfig.Unlock() |
| 83 | + if err := c.reloadConfiguration(reload, newConfig); err != nil { |
| 84 | + return fmt.Errorf("reloading configuration: %s", err.Msg) |
| 85 | + } |
| 86 | + clientConfig = newConfig |
| 87 | + return nil |
| 88 | +} |
| 89 | + |
| 90 | +func (c *Client) reloadConfiguration(reload bool, newConfig config.Config) *monitor.Error { |
89 | 91 |
|
90 | 92 | // firstly load config level, to detect further errors if any
|
91 |
| - if clientConfig.LogLevel != nil { |
92 |
| - log.SetLogLevel(int(*clientConfig.LogLevel)) |
| 93 | + if newConfig.LogLevel != nil { |
| 94 | + log.SetLogLevel(int(*newConfig.LogLevel)) |
93 | 95 | }
|
94 |
| - log.SetLogUTC(clientConfig.LogUTC) |
95 |
| - log.SetLogMicro(clientConfig.LogMicro) |
96 |
| - if clientConfig.Server.LogFile != "" { |
| 96 | + log.SetLogUTC(newConfig.LogUTC) |
| 97 | + log.SetLogMicro(newConfig.LogMicro) |
| 98 | + if newConfig.Server.LogFile != "" { |
| 99 | + log.Debug("[config] using config.server.logfile: %s", newConfig.Server.LogFile) |
97 | 100 | log.Close()
|
98 |
| - log.OpenFile(clientConfig.Server.LogFile) |
| 101 | + log.OpenFile(newConfig.Server.LogFile) |
99 | 102 | }
|
100 | 103 |
|
101 |
| - if clientConfig.Server.Address != "" { |
102 |
| - tempSocketPath := c.getSocketPath(clientConfig.Server.Address) |
| 104 | + reconnect := newConfig.Server.Authentication.Type != clientConfig.Server.Authentication.Type || |
| 105 | + newConfig.Server.Authentication.TLSOptions.CACert != clientConfig.Server.Authentication.TLSOptions.CACert || |
| 106 | + newConfig.Server.Authentication.TLSOptions.ServerCert != clientConfig.Server.Authentication.TLSOptions.ServerCert || |
| 107 | + newConfig.Server.Authentication.TLSOptions.ServerKey != clientConfig.Server.Authentication.TLSOptions.ServerKey || |
| 108 | + newConfig.Server.Authentication.TLSOptions.ClientCert != clientConfig.Server.Authentication.TLSOptions.ClientCert || |
| 109 | + newConfig.Server.Authentication.TLSOptions.ClientKey != clientConfig.Server.Authentication.TLSOptions.ClientKey || |
| 110 | + newConfig.Server.Authentication.TLSOptions.ClientAuthType != clientConfig.Server.Authentication.TLSOptions.ClientAuthType || |
| 111 | + newConfig.Server.Authentication.TLSOptions.SkipVerify != clientConfig.Server.Authentication.TLSOptions.SkipVerify |
| 112 | + |
| 113 | + if newConfig.Server.Address != "" { |
| 114 | + tempSocketPath := c.getSocketPath(newConfig.Server.Address) |
| 115 | + log.Debug("[config] using config.server.address: %s", newConfig.Server.Address) |
103 | 116 | if tempSocketPath != c.socketPath {
|
104 | 117 | // disconnect, and let the connection poller reconnect to the new address
|
105 |
| - c.disconnect() |
| 118 | + reconnect = true |
106 | 119 | }
|
107 | 120 | c.setSocketPath(tempSocketPath)
|
108 | 121 | }
|
109 |
| - if clientConfig.DefaultAction != "" { |
110 |
| - clientDisconnectedRule.Action = rule.Action(clientConfig.DefaultAction) |
111 |
| - clientErrorRule.Action = rule.Action(clientConfig.DefaultAction) |
| 122 | + |
| 123 | + if reconnect { |
| 124 | + log.Debug("[config] config.server.address.* changed, reconnecting") |
| 125 | + c.disconnect() |
| 126 | + } |
| 127 | + |
| 128 | + if newConfig.DefaultAction != "" { |
| 129 | + clientDisconnectedRule.Action = rule.Action(newConfig.DefaultAction) |
| 130 | + clientErrorRule.Action = rule.Action(newConfig.DefaultAction) |
112 | 131 | // TODO: reconfigure connected rule if changed, but not save it to disk.
|
113 |
| - //clientConnectedRule.Action = rule.Action(clientConfig.DefaultAction) |
114 |
| - } |
115 |
| - if clientConfig.DefaultDuration != "" { |
116 |
| - clientDisconnectedRule.Duration = rule.Duration(clientConfig.DefaultDuration) |
117 |
| - clientErrorRule.Duration = rule.Duration(clientConfig.DefaultDuration) |
118 |
| - } |
119 |
| - if clientConfig.ProcMonitorMethod != "" { |
120 |
| - err := monitor.ReconfigureMonitorMethod(clientConfig.ProcMonitorMethod, clientConfig.Ebpf.ModulesPath) |
121 |
| - if err != nil { |
122 |
| - msg := fmt.Sprintf("Unable to set new process monitor (%s) method from disk: %v", clientConfig.ProcMonitorMethod, err.Msg) |
123 |
| - log.Warning(msg) |
124 |
| - c.SendWarningAlert(msg) |
125 |
| - } |
| 132 | + //clientConnectedRule.Action = rule.Action(newConfig.DefaultAction) |
126 | 133 | }
|
127 | 134 |
|
128 |
| - if clientConfig.Internal.GCPercent > 0 { |
129 |
| - oldgcpercent := debug.SetGCPercent(clientConfig.Internal.GCPercent) |
130 |
| - log.Info("GC percent set to %d, previously was %d", clientConfig.Internal.GCPercent, oldgcpercent) |
| 135 | + if newConfig.DefaultDuration != "" { |
| 136 | + clientDisconnectedRule.Duration = rule.Duration(newConfig.DefaultDuration) |
| 137 | + clientErrorRule.Duration = rule.Duration(newConfig.DefaultDuration) |
131 | 138 | }
|
132 | 139 |
|
133 |
| - c.rules.EnableChecksums(clientConfig.Rules.EnableChecksums) |
| 140 | + if newConfig.Internal.GCPercent > 0 && newConfig.Internal.GCPercent != clientConfig.Internal.GCPercent { |
| 141 | + oldgcpercent := debug.SetGCPercent(newConfig.Internal.GCPercent) |
| 142 | + log.Debug("[config] GC percent set to %d, previously was %d", newConfig.Internal.GCPercent, oldgcpercent) |
| 143 | + } else { |
| 144 | + log.Debug("[config] config.internal.gcpercent not changed") |
| 145 | + } |
| 146 | + |
| 147 | + c.rules.EnableChecksums(newConfig.Rules.EnableChecksums) |
| 148 | + if clientConfig.Rules.Path != newConfig.Rules.Path { |
| 149 | + c.rules.Reload(newConfig.Rules.Path) |
| 150 | + log.Debug("[config] reloading config.rules.path: %s", newConfig.Rules.Path) |
| 151 | + } else { |
| 152 | + log.Debug("[config] config.rules.path not changed") |
| 153 | + } |
134 | 154 | // TODO:
|
135 | 155 | //c.stats.SetLimits(clientConfig.Stats)
|
136 |
| - //loggers.Load(clientConfig.Server.Loggers, clientConfig.Stats.Workers) |
137 |
| - //stats.SetLoggers(loggers) |
| 156 | + if reload { |
| 157 | + c.loggers.Stop() |
| 158 | + } |
| 159 | + c.loggers.Load(clientConfig.Server.Loggers, clientConfig.Stats.Workers) |
| 160 | + c.stats.SetLoggers(c.loggers) |
| 161 | + |
| 162 | + if reload && c.GetFirewallType() != newConfig.Firewall || |
| 163 | + newConfig.FwOptions.ConfigPath != clientConfig.FwOptions.ConfigPath || |
| 164 | + newConfig.FwOptions.MonitorInterval != clientConfig.FwOptions.MonitorInterval { |
| 165 | + log.Debug("[config] reloading config.firewall") |
| 166 | + |
| 167 | + firewall.Reload( |
| 168 | + newConfig.Firewall, |
| 169 | + newConfig.FwOptions.ConfigPath, |
| 170 | + newConfig.FwOptions.MonitorInterval, |
| 171 | + ) |
| 172 | + } else { |
| 173 | + log.Debug("[config] config.firewall not changed") |
| 174 | + } |
| 175 | + |
| 176 | + reloadProc := false |
| 177 | + if clientConfig.ProcMonitorMethod == "" || |
| 178 | + newConfig.ProcMonitorMethod != clientConfig.ProcMonitorMethod { |
| 179 | + log.Debug("[config] reloading config.ProcMonMethod, old: %s -> new: %s", clientConfig.ProcMonitorMethod, newConfig.ProcMonitorMethod) |
| 180 | + reloadProc = true |
| 181 | + } else { |
| 182 | + log.Debug("[config] config.ProcMonMethod not changed") |
| 183 | + } |
| 184 | + |
| 185 | + if reload && procmon.MethodIsEbpf() && newConfig.Ebpf.ModulesPath != "" && clientConfig.Ebpf.ModulesPath != newConfig.Ebpf.ModulesPath { |
| 186 | + log.Debug("[config] reloading config.Ebpf.ModulesPath: %s", newConfig.Ebpf.ModulesPath) |
| 187 | + reloadProc = true |
| 188 | + } else { |
| 189 | + log.Debug("[config] config.Ebpf.ModulesPath not changed") |
| 190 | + } |
| 191 | + if reloadProc { |
| 192 | + monitor.End() |
| 193 | + procmon.SetMonitorMethod(newConfig.ProcMonitorMethod) |
| 194 | + clientConfig.ProcMonitorMethod = newConfig.ProcMonitorMethod |
| 195 | + err := monitor.Init(newConfig.Ebpf.ModulesPath) |
| 196 | + if err.What > monitor.NoError { |
| 197 | + log.Error("[config] config.procmon error: %s", err.Msg) |
| 198 | + procmon.SetMonitorMethod(clientConfig.ProcMonitorMethod) |
| 199 | + monitor.Init(clientConfig.Ebpf.ModulesPath) |
| 200 | + return err |
| 201 | + } |
| 202 | + } else { |
| 203 | + log.Debug("[config] config.procmon not changed") |
| 204 | + } |
138 | 205 |
|
139 |
| - return true |
| 206 | + return nil |
140 | 207 | }
|
0 commit comments