From a782f744aa580188d95bdcc6d65aff7a4a44f516 Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Mon, 28 Jun 2021 21:02:21 +0200 Subject: [PATCH 1/2] disable ids logs by default --- pkg/netconf/configurator.go | 34 +++++++++++++----------- pkg/netconf/suricata_config.go | 10 +++++-- pkg/netconf/tpl/suricata_config.yaml.tpl | 4 +++ 3 files changed, 31 insertions(+), 17 deletions(-) diff --git a/pkg/netconf/configurator.go b/pkg/netconf/configurator.go index b4f2c47..2eefb15 100644 --- a/pkg/netconf/configurator.go +++ b/pkg/netconf/configurator.go @@ -56,6 +56,7 @@ type ( FirewallConfigurator struct { CommonConfigurator EnableDNSProxy bool + EnableIDS bool } ) @@ -96,7 +97,7 @@ func (configurator FirewallConfigurator) Configure() { kb := configurator.Kb applyCommonConfiguration(Firewall, kb) - configurator.ConfugureNftables() + configurator.ConfigureNftables() chrony, err := NewChronyServiceEnabler(configurator.Kb) if err != nil { @@ -124,32 +125,35 @@ func (configurator FirewallConfigurator) Configure() { } } - src := mustTmpFile("suricata_") - applier, err := NewSuricataDefaultsApplier(kb, src) + configurator.ConfigureSuricataDefaults() + configurator.ConfigureSuricata() +} + +func (configurator FirewallConfigurator) ConfigureNftables() { + src := mustTmpFile("nftrules_") + validator := NftablesValidator{src} + applier := NewNftablesConfigApplier(configurator.Kb, validator, configurator.EnableDNSProxy) + applyAndCleanUp(applier, TplNftables, src, "/etc/nftables/rules", FileModeDefault) +} +func (configurator FirewallConfigurator) ConfigureSuricataDefaults() { + src := mustTmpFile("suricata_") + applier, err := NewSuricataDefaultsApplier(configurator.Kb, src) if err != nil { log.Warnf("failed to configure suricata defaults: %v", err) } - applyAndCleanUp(applier, tplSuricataDefaults, src, "/etc/default/suricata", FileModeSixFourFour) +} - src = mustTmpFile("suricata.yaml_") - applier, err = NewSuricataConfigApplier(kb, src) - +func (configurator FirewallConfigurator) ConfigureSuricata() { + src := mustTmpFile("suricata.yaml_") + applier, err := NewSuricataConfigApplier(configurator.Kb, src, configurator.EnableIDS) if err != nil { log.Warnf("failed to configure suricata: %v", err) } - applyAndCleanUp(applier, TplSuricataConfig, src, "/etc/suricata/suricata.yaml", FileModeSixFourFour) } -func (configurator FirewallConfigurator) ConfugureNftables() { - src := mustTmpFile("nftrules_") - validator := NftablesValidator{src} - applier := NewNftablesConfigApplier(configurator.Kb, validator, configurator.EnableDNSProxy) - applyAndCleanUp(applier, TplNftables, src, "/etc/nftables/rules", FileModeDefault) -} - func (configurator FirewallConfigurator) getUnits() []unitConfiguration { return []unitConfiguration{ { diff --git a/pkg/netconf/suricata_config.go b/pkg/netconf/suricata_config.go index 48c33f0..752f46f 100644 --- a/pkg/netconf/suricata_config.go +++ b/pkg/netconf/suricata_config.go @@ -14,6 +14,7 @@ type SuricataConfigData struct { Comment string DefaultRouteVrf string Interface string + EnableIDS bool } // SuricataConfigValidator can validate configuration for suricata. @@ -22,14 +23,19 @@ type SuricataConfigValidator struct { } // NewSuricataConfigApplier constructs a new instance of this type. -func NewSuricataConfigApplier(kb KnowledgeBase, tmpFile string) (net.Applier, error) { +func NewSuricataConfigApplier(kb KnowledgeBase, tmpFile string, enableIDS bool) (net.Applier, error) { defaultRouteVrf, err := kb.getDefaultRouteVRFName() if err != nil { return nil, err } i := strings.Replace(defaultRouteVrf, "vrf", "vlan", 1) - data := SuricataConfigData{Comment: versionHeader(kb.Machineuuid), DefaultRouteVrf: defaultRouteVrf, Interface: i} + data := SuricataConfigData{ + Comment: versionHeader(kb.Machineuuid), + DefaultRouteVrf: defaultRouteVrf, + Interface: i, + EnableIDS: enableIDS, + } validator := SuricataConfigValidator{tmpFile} return net.NewNetworkApplier(data, validator, nil), nil diff --git a/pkg/netconf/tpl/suricata_config.yaml.tpl b/pkg/netconf/tpl/suricata_config.yaml.tpl index 378b618..0dd5d25 100644 --- a/pkg/netconf/tpl/suricata_config.yaml.tpl +++ b/pkg/netconf/tpl/suricata_config.yaml.tpl @@ -81,6 +81,7 @@ outputs: # Extensible Event Format (nicknamed EVE) event log in JSON format - eve-log: + {{- if .EnableIDS }} enabled: yes filetype: regular filename: eve.json @@ -287,6 +288,9 @@ outputs: # and will include the pktvars, flowvars, flowbits and # flowints. #- metadata + {{- else }} + enabled: no + {{- end }} # deprecated - unified2 alert format for use with Barnyard2 - unified2-alert: From 708707e0af23d387c1c9a0b9b3cd333e17fea8e7 Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Mon, 5 Jul 2021 20:18:57 +0200 Subject: [PATCH 2/2] added IPS configuration --- pkg/netconf/configurator.go | 40 ++++++++++++++---------- pkg/netconf/nftables.go | 3 +- pkg/netconf/suricata.go | 32 +++++++++++++++++++ pkg/netconf/tpl/suricata.service.tpl | 18 +++++++++++ pkg/netconf/tpl/suricata_config.yaml.tpl | 4 +-- 5 files changed, 78 insertions(+), 19 deletions(-) create mode 100644 pkg/netconf/suricata.go create mode 100644 pkg/netconf/tpl/suricata.service.tpl diff --git a/pkg/netconf/configurator.go b/pkg/netconf/configurator.go index 2eefb15..b63ec43 100644 --- a/pkg/netconf/configurator.go +++ b/pkg/netconf/configurator.go @@ -57,10 +57,11 @@ type ( CommonConfigurator EnableDNSProxy bool EnableIDS bool + EnableIPS bool } ) -type unitConfiguration struct { +type UnitConfiguration struct { unit string templateFile string constructApplier func(kb KnowledgeBase, v ServiceValidator) (net.Applier, error) @@ -110,19 +111,7 @@ func (configurator FirewallConfigurator) Configure() { } for _, u := range configurator.getUnits() { - src := mustTmpFile(u.unit) - validatorService := ServiceValidator{src} - nfe, err := u.constructApplier(configurator.Kb, validatorService) - - if err != nil { - log.Warnf("failed to deploy %s service : %v", u.unit, err) - } - - applyAndCleanUp(nfe, u.templateFile, src, path.Join(SystemdUnitPath, u.unit), FileModeSystemd) - - if u.enabled { - mustEnableUnit(u.unit) - } + configurator.ApplySystemdUnit(u) } configurator.ConfigureSuricataDefaults() @@ -152,10 +141,29 @@ func (configurator FirewallConfigurator) ConfigureSuricata() { log.Warnf("failed to configure suricata: %v", err) } applyAndCleanUp(applier, TplSuricataConfig, src, "/etc/suricata/suricata.yaml", FileModeSixFourFour) + + // update systemd unit file to run suricata in correct mode(IDS/IPS) + configurator.ApplySystemdUnit(GetSystemdUnitConfig(configurator.EnableIPS)) +} + +func (configurator FirewallConfigurator) ApplySystemdUnit(u UnitConfiguration) { + src := mustTmpFile(u.unit) + validatorService := ServiceValidator{src} + nfe, err := u.constructApplier(configurator.Kb, validatorService) + + if err != nil { + log.Warnf("failed to deploy %s service : %v", u.unit, err) + } + + applyAndCleanUp(nfe, u.templateFile, src, path.Join(SystemdUnitPath, u.unit), FileModeSystemd) + + if u.enabled { + mustEnableUnit(u.unit) + } } -func (configurator FirewallConfigurator) getUnits() []unitConfiguration { - return []unitConfiguration{ +func (configurator FirewallConfigurator) getUnits() []UnitConfiguration { + return []UnitConfiguration{ { unit: systemdUnitDroptailer, templateFile: tplDroptailer, diff --git a/pkg/netconf/nftables.go b/pkg/netconf/nftables.go index 1a92b54..eefe3fb 100644 --- a/pkg/netconf/nftables.go +++ b/pkg/netconf/nftables.go @@ -4,9 +4,10 @@ import ( "fmt" "github.com/metal-stack/metal-go/api/models" - "github.com/metal-stack/metal-networker/pkg/exec" "inet.af/netaddr" + "github.com/metal-stack/metal-networker/pkg/exec" + "github.com/metal-stack/metal-networker/pkg/net" mn "github.com/metal-stack/metal-lib/pkg/net" diff --git a/pkg/netconf/suricata.go b/pkg/netconf/suricata.go new file mode 100644 index 0000000..4925c80 --- /dev/null +++ b/pkg/netconf/suricata.go @@ -0,0 +1,32 @@ +package netconf + +import ( + "github.com/metal-stack/metal-networker/pkg/net" +) + +// tplSuricata is the name of the template for the suricata service. +const tplSuricata = "suricata.service.tpl" + +// systemdUnitSuricata is the name of the systemd unit for the suricata. +const systemdUnitSuricata = "suricata.service" + +// SuricataData contains the data to render the suricata service template. +type SuricataData struct { + EnableIPS bool +} + +// NewSuricataServiceApplier constructs a new instance of this type. +func NewSuricataServiceApplier(kb KnowledgeBase, v net.Validator, enableIPS bool) (net.Applier, error) { + data := SuricataData{EnableIPS: enableIPS} + return net.NewNetworkApplier(data, v, nil), nil +} + +func GetSystemdUnitConfig(enableIPS bool) UnitConfiguration { + return UnitConfiguration{ + unit: systemdUnitSuricata, + templateFile: tplSuricata, + constructApplier: func(kb KnowledgeBase, v ServiceValidator) (net.Applier, error) { + return NewSuricataServiceApplier(kb, v, enableIPS) + }, + } +} diff --git a/pkg/netconf/tpl/suricata.service.tpl b/pkg/netconf/tpl/suricata.service.tpl new file mode 100644 index 0000000..afdc3ab --- /dev/null +++ b/pkg/netconf/tpl/suricata.service.tpl @@ -0,0 +1,18 @@ +[Unit] +Description=Suricata Intrusion Detection Service +After=network.target + +[Service] +EnvironmentFile=-/etc/default/suricata +ExecStartPre=/bin/rm -f $PIDFILE +{{- if .EnableIPS }} +ExecStart=/usr/bin/suricata -c $SURCONF --pidfile $PIDFILE -q 0 +{{- else }} +ExecStart=/usr/bin/suricata -c $SURCONF --pidfile $PIDFILE -i $IFACE +{{- end }} +ExecReload=/bin/kill -USR2 $MAINPID +Restart=always +RestartSec=60 + +[Install] +WantedBy=multi-user.target \ No newline at end of file diff --git a/pkg/netconf/tpl/suricata_config.yaml.tpl b/pkg/netconf/tpl/suricata_config.yaml.tpl index 0dd5d25..5f49636 100644 --- a/pkg/netconf/tpl/suricata_config.yaml.tpl +++ b/pkg/netconf/tpl/suricata_config.yaml.tpl @@ -240,8 +240,8 @@ outputs: # force logging of checksums, available hash functions are md5, # sha1 and sha256 #force-hash: [md5] - #- drop: - # alerts: yes # log alerts that caused drops + - drop: + alerts: yes # log alerts that caused drops # flows: all # start or all: 'start' logs only a single drop # # per flow direction. All logs each dropped pkt. - smtp: