Skip to content

Commit

Permalink
allow to configure rules and config file paths
Browse files Browse the repository at this point in the history
 - Added cli option -config-file to specify an alternate path to the
   config file.
 - Allow to configure rules path from the configuration file (cli option
   takes precedence).
 - Default options are now /etc/opensnitchd/rules and
   /etc/opensnitchd/default-config.json. Previously the default rules
   directory was "rules" (relative path).

Closes #449

(cherry picked from commit 211c864)
  • Loading branch information
gustavo-iniguez-goya committed Jan 8, 2024
1 parent 1608ab7 commit 6bd1fe8
Show file tree
Hide file tree
Showing 4 changed files with 54 additions and 9 deletions.
42 changes: 39 additions & 3 deletions daemon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,7 @@ import (
"github.com/evilsocket/opensnitch/daemon/rule"
"github.com/evilsocket/opensnitch/daemon/statistics"
"github.com/evilsocket/opensnitch/daemon/ui"
"github.com/evilsocket/opensnitch/daemon/ui/config"
"github.com/evilsocket/opensnitch/daemon/ui/protocol"
)

Expand All @@ -60,7 +61,8 @@ var (
logFile = ""
logUTC = true
logMicro = false
rulesPath = "rules"
rulesPath = "/etc/opensnitchd/rules/"
configFile = "/etc/opensnitchd/default-config.json"
noLiveReload = false
queueNum = 0
repeatQueueNum int //will be set later to queueNum + 1
Expand Down Expand Up @@ -102,6 +104,7 @@ func init() {
flag.IntVar(&workers, "workers", workers, "Number of concurrent workers.")
flag.BoolVar(&noLiveReload, "no-live-reload", debug, "Disable rules live reloading.")

flag.StringVar(&configFile, "config-file", configFile, "Path to the daemon configuration file.")
flag.StringVar(&logFile, "log-file", logFile, "Write logs to this file instead of the standard output.")
flag.BoolVar(&logUTC, "log-utc", logUTC, "Write logs output with UTC timezone (enabled by default).")
flag.BoolVar(&logMicro, "log-micro", logMicro, "Write logs output with microsecond timestamp (disabled by default).")
Expand All @@ -114,6 +117,27 @@ func init() {
flag.StringVar(&memProfile, "mem-profile", memProfile, "Write memory profile to this file.")
}

// Load configuration file from disk, by default from /etc/opensnitchd/default-config.json,
// or from the path specified by configFile.
// This configuration will be loaded again by uiClient(), in order to monitor it for changes.
func loadDiskConfiguration() (*config.Config, error) {
if configFile == "" {
return nil, fmt.Errorf("Configuration file cannot be empty")
}

raw, err := config.Load(configFile)
if err != nil || len(raw) == 0 {
return nil, fmt.Errorf("Error loading configuration %s: %s", configFile, err)
}
clientConfig, err := config.Parse(raw)
if err != nil {
return nil, fmt.Errorf("Error parsing configuration %s: %s", configFile, err)
}

log.Info("Loading configuration file %s ...", configFile)
return &clientConfig, nil
}

func overwriteLogging() bool {
return debug || warning || important || errorlog || logFile != "" || logMicro
}
Expand Down Expand Up @@ -482,6 +506,17 @@ func main() {

log.Important("Starting %s v%s", core.Name, core.Version)

cfg, err := loadDiskConfiguration()
if err != nil {
log.Fatal("%s", err)
}
if err == nil && cfg.Rules.Path != "" {
rulesPath = cfg.Rules.Path
}
if rulesPath == "" {
log.Fatal("rules path cannot be empty")
}

rulesPath, err := core.ExpandPath(rulesPath)
if err != nil {
log.Fatal("Error accessing rules path (does it exist?): %s", err)
Expand All @@ -490,14 +525,15 @@ func main() {
setupSignals()

log.Info("Loading rules from %s ...", rulesPath)
if rules, err = rule.NewLoader(!noLiveReload); err != nil {
rules, err = rule.NewLoader(!noLiveReload)
if err != nil {
log.Fatal("%s", err)
} else if err = rules.Load(rulesPath); err != nil {
log.Fatal("%s", err)
}
stats = statistics.New(rules)
loggerMgr = loggers.NewLoggerManager()
uiClient = ui.NewClient(uiSocket, stats, rules, loggerMgr)
uiClient = ui.NewClient(uiSocket, configFile, stats, rules, loggerMgr)

// prepare the queue
setupWorkers()
Expand Down
4 changes: 2 additions & 2 deletions daemon/rule/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ func (l *Loader) GetAll() map[string]*Rule {
// Load loads rules files from disk.
func (l *Loader) Load(path string) error {
if core.Exists(path) == false {
return fmt.Errorf("Path '%s' does not exist\nCreate it in if you want to save rules to disk", path)
return fmt.Errorf("Path '%s' does not exist\nCreate it if you want to save rules to disk", path)
}
path, err := core.ExpandPath(path)
if err != nil {
return fmt.Errorf("Error accessing rules path: %s.\nCreate it in if you want to save rules to disk", err)
return fmt.Errorf("Error accessing rules path: %s.\nCreate it if you want to save rules to disk", err)
}

expr := filepath.Join(path, "*.json")
Expand Down
5 changes: 4 additions & 1 deletion daemon/ui/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,10 @@ type Client struct {
}

// NewClient creates and configures a new client.
func NewClient(socketPath string, stats *statistics.Statistics, rules *rule.Loader, loggers *loggers.LoggerManager) *Client {
func NewClient(socketPath, localConfigFile string, stats *statistics.Statistics, rules *rule.Loader, loggers *loggers.LoggerManager) *Client {
if localConfigFile != "" {
configFile = localConfigFile
}
c := &Client{
stats: stats,
rules: rules,
Expand Down
12 changes: 9 additions & 3 deletions daemon/ui/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,19 +44,25 @@ type serverConfig struct {
Loggers []loggers.LoggerConfig `json:"Loggers"`
}

type rulesOptions struct {
Path string `json:"Path"`
EnableChecksums bool `json:"EnableChecksums"`
}

// Config holds the values loaded from configFile
type Config struct {
sync.RWMutex
Server serverConfig `json:"Server"`
Stats statistics.StatsConfig `json:"Stats"`
Rules rulesOptions `json:"Rules"`
DefaultAction string `json:"DefaultAction"`
DefaultDuration string `json:"DefaultDuration"`
InterceptUnknown bool `json:"InterceptUnknown"`
ProcMonitorMethod string `json:"ProcMonitorMethod"`
Firewall string `json:"Firewall"`
LogLevel *uint32 `json:"LogLevel"`
InterceptUnknown bool `json:"InterceptUnknown"`
LogUTC bool `json:"LogUTC"`
LogMicro bool `json:"LogMicro"`
Firewall string `json:"Firewall"`
Stats statistics.StatsConfig `json:"Stats"`
}

// Parse determines if the given configuration is ok.
Expand Down

0 comments on commit 6bd1fe8

Please sign in to comment.