diff --git a/daemon/default-config.json b/daemon/default-config.json index c695b0636a..4c32844853 100644 --- a/daemon/default-config.json +++ b/daemon/default-config.json @@ -1,4 +1,9 @@ { + "Server": + { + "Address":"unix:///tmp/osui.sock", + "LogFile":"/var/log/opensnitchd.log" + }, "DefaultAction": "allow", "DefaultDuration": "once", "InterceptUnknown": false, diff --git a/daemon/main.go b/daemon/main.go index 36271831d1..15d81343a3 100644 --- a/daemon/main.go +++ b/daemon/main.go @@ -38,7 +38,7 @@ var ( important = false errorlog = false - uiSocket = "unix:///tmp/osui.sock" + uiSocket = "" uiClient = (*ui.Client)(nil) cpuProfile = "" @@ -89,8 +89,8 @@ func setupLogging() { } if logFile != "" { - if log.Output, err = os.OpenFile(logFile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err != nil { - panic(err) + if err := log.OpenFile(logFile); err != nil { + log.Error("Error opening user defined log: ", logFile, err) } } } diff --git a/daemon/opensnitchd.service b/daemon/opensnitchd.service index 0a005d2628..6c3e6dfc27 100644 --- a/daemon/opensnitchd.service +++ b/daemon/opensnitchd.service @@ -8,7 +8,7 @@ After=network.target Type=simple PermissionsStartOnly=true ExecStartPre=/bin/mkdir -p /etc/opensnitchd/rules -ExecStart=/usr/local/bin/opensnitchd -log-file /var/log/opensnitchd.log -rules-path /etc/opensnitchd/rules -ui-socket unix:///tmp/osui.sock +ExecStart=/usr/local/bin/opensnitchd -rules-path /etc/opensnitchd/rules Restart=always RestartSec=30 diff --git a/daemon/ui/client.go b/daemon/ui/client.go index 325082bca6..eeca4620fe 100644 --- a/daemon/ui/client.go +++ b/daemon/ui/client.go @@ -3,7 +3,6 @@ package ui import ( "fmt" "net" - "strings" "sync" "time" @@ -27,14 +26,20 @@ var ( config Config ) +type serverConfig struct { + Address string `json:"Address"` + LogFile string `json:"LogFile"` +} + // Config holds the values loaded from configFile type Config struct { sync.RWMutex - DefaultAction string - DefaultDuration string - InterceptUnknown bool - ProcMonitorMethod string - LogLevel *uint32 + Server serverConfig `json:"Server"` + DefaultAction string `json:"DefaultAction"` + DefaultDuration string `json:"DefaultDuration"` + InterceptUnknown bool `json:"InterceptUnknown"` + ProcMonitorMethod string `json:"ProcMonitorMethod"` + LogLevel *uint32 `json:"LogLevel"` } // Client holds the connection information of a client. @@ -54,9 +59,8 @@ type Client struct { } // NewClient creates and configures a new client. -func NewClient(path string, stats *statistics.Statistics, rules *rule.Loader) *Client { +func NewClient(socketPath string, stats *statistics.Statistics, rules *rule.Loader) *Client { c := &Client{ - socketPath: path, stats: stats, rules: rules, isUnixSocket: false, @@ -66,11 +70,12 @@ func NewClient(path string, stats *statistics.Statistics, rules *rule.Loader) *C if watcher, err := fsnotify.NewWatcher(); err == nil { c.configWatcher = watcher } - if strings.HasPrefix(c.socketPath, "unix://") == true { - c.isUnixSocket = true - c.socketPath = c.socketPath[7:] - } c.loadDiskConfiguration(false) + if socketPath != "" { + c.socketPath = socketPath + } + + c.socketPath = c.getSocketPath(c.socketPath) go c.poller() return c @@ -123,6 +128,7 @@ func (c *Client) poller() { for { select { case <-c.clientCtx.Done(): + log.Info("Client.poller() exit, Done()") goto Exit default: isConnected := c.Connected() @@ -157,8 +163,7 @@ func (c *Client) onStatusChange(connected bool) { go c.Subscribe() } else { log.Error("Connection to the UI service lost.") - c.client = nil - c.con.Close() + c.disconnect() } } @@ -171,8 +176,7 @@ func (c *Client) connect() (err error) { if c.con != nil { if c.con.GetState() == connectivity.TransientFailure || c.con.GetState() == connectivity.Shutdown { - c.client = nil - c.con.Close() + c.disconnect() } else { return } @@ -188,11 +192,7 @@ func (c *Client) connect() (err error) { } if err != nil { - if c.con != nil { - c.con.Close() - } - c.con = nil - c.client = nil + c.disconnect() return err } @@ -202,6 +202,15 @@ func (c *Client) connect() (err error) { return nil } +func (c *Client) disconnect() { + c.client = nil + if c.con != nil { + c.con.Close() + c.con = nil + } + log.Debug("client.disconnect()") +} + func (c *Client) ping(ts time.Time) (err error) { if c.Connected() == false { return fmt.Errorf("service is not connected") diff --git a/daemon/ui/config.go b/daemon/ui/config.go index 189f4576a9..3320ca9fb7 100644 --- a/daemon/ui/config.go +++ b/daemon/ui/config.go @@ -4,12 +4,23 @@ import ( "encoding/json" "fmt" "io/ioutil" + "strings" "github.com/gustavo-iniguez-goya/opensnitch/daemon/log" "github.com/gustavo-iniguez-goya/opensnitch/daemon/procmon" "github.com/gustavo-iniguez-goya/opensnitch/daemon/rule" ) +func (c *Client) getSocketPath(socketPath string) string { + if strings.HasPrefix(socketPath, "unix://") == true { + c.isUnixSocket = true + return socketPath[7:] + } + + c.isUnixSocket = false + return socketPath +} + func (c *Client) isProcMonitorEqual(newMonitorMethod string) bool { config.RLock() defer config.RUnlock() @@ -50,6 +61,24 @@ func (c *Client) loadConfiguration(rawConfig []byte) bool { fmt.Errorf("Error parsing configuration %s: %s", configFile, err) return false } + // firstly load config level, to detect further errors if any + if config.LogLevel != nil { + log.SetLogLevel(int(*config.LogLevel)) + } + + if config.Server.Address != "" { + tempSocketPath := c.getSocketPath(config.Server.Address) + if tempSocketPath != c.socketPath { + // disconnect, and let the connection poller reconnect to the new address + c.disconnect() + } + c.socketPath = tempSocketPath + } + if config.Server.LogFile != "" { + if err := log.OpenFile(config.Server.LogFile); err != nil { + log.Warning("Error opening log file: ", err) + } + } if config.DefaultAction != "" { clientDisconnectedRule.Action = rule.Action(config.DefaultAction) @@ -59,9 +88,6 @@ func (c *Client) loadConfiguration(rawConfig []byte) bool { clientDisconnectedRule.Duration = rule.Duration(config.DefaultDuration) clientErrorRule.Duration = rule.Duration(config.DefaultDuration) } - if config.LogLevel != nil { - log.SetLogLevel(int(*config.LogLevel)) - } if config.ProcMonitorMethod != "" { procmon.SetMonitorMethod(config.ProcMonitorMethod) }