From 5de1c95172b0a2b2eacc306806ccc5409e429bdd Mon Sep 17 00:00:00 2001 From: Grigoriy Mikhalkin Date: Tue, 29 Jun 2021 19:23:15 +0200 Subject: [PATCH] restart suricata service --- api/v1/firewall_types.go | 4 +- .../crd/bases/metal-stack.io_firewalls.yaml | 8 +- controllers/firewall_controller.go | 11 ++- main.go | 9 +- pkg/network/suricata.go | 15 --- pkg/suricata/stats.go | 53 ----------- pkg/suricata/suricata.go | 94 +++++++++++++++++++ 7 files changed, 112 insertions(+), 82 deletions(-) delete mode 100644 pkg/network/suricata.go delete mode 100644 pkg/suricata/stats.go create mode 100644 pkg/suricata/suricata.go diff --git a/api/v1/firewall_types.go b/api/v1/firewall_types.go index 97b5c91c..fb7f91a4 100644 --- a/api/v1/firewall_types.go +++ b/api/v1/firewall_types.go @@ -81,8 +81,8 @@ type Data struct { EgressRules []EgressRuleSNAT `json:"egressRules,omitempty"` // FirewallNetworks holds the networks known at the metal-api for this firewall machine FirewallNetworks []FirewallNetwork `json:"firewallNetworks,omitempty"` - // EnableSuricataIDS specifies if we need to enable IDS on the firewall machine - EnableSuricataIDS bool `json:"enableSuricataIDS,omitempty"` + // DisableSuricataIDS specifies if we need to enable IDS on the firewall machine + DisableSuricataIDS bool `json:"disableSuricataIDS,omitempty"` } // FirewallStatus defines the observed state of Firewall diff --git a/config/crd/bases/metal-stack.io_firewalls.yaml b/config/crd/bases/metal-stack.io_firewalls.yaml index c9c44a45..5e083144 100644 --- a/config/crd/bases/metal-stack.io_firewalls.yaml +++ b/config/crd/bases/metal-stack.io_firewalls.yaml @@ -53,6 +53,10 @@ spec: description: ControllerVersion holds the firewall-controller version to reconcile. type: string + disableSuricataIDS: + description: DisableSuricataIDS specifies if we need to enable IDS + on the firewall machine + type: boolean dryrun: description: DryRun if set to true, firewall rules are not applied type: boolean @@ -72,10 +76,6 @@ spec: - networkid type: object type: array - enableSuricataIDS: - description: EnableSuricataIDS specifies if we need to enable IDS - on the firewall machine - type: boolean firewallNetworks: description: FirewallNetworks holds the networks known at the metal-api for this firewall machine diff --git a/controllers/firewall_controller.go b/controllers/firewall_controller.go index 62599a2d..ebc5bb12 100644 --- a/controllers/firewall_controller.go +++ b/controllers/firewall_controller.go @@ -57,7 +57,7 @@ type FirewallReconciler struct { recorder record.EventRecorder Log logr.Logger Scheme *runtime.Scheme - EnableIDS bool + Suricata *suricata.Suricata EnableSignatureCheck bool CAPubKey *rsa.PublicKey } @@ -143,7 +143,9 @@ func (r *FirewallReconciler) Reconcile(req ctrl.Request) (ctrl.Result, error) { } log.Info("reconciling suricata config") - network.ReconcileSuricata(kb, f.Spec.EnableSuricataIDS) + if err := r.Suricata.ReconcileSuricata(kb, !f.Spec.DisableSuricataIDS); err != nil { + errors = multierror.Append(errors, err) + } log.Info("reconciling firewall services") if err = r.reconcileFirewallServices(ctx, f); err != nil { @@ -425,9 +427,8 @@ func (r *FirewallReconciler) updateStatus(ctx context.Context, f firewallv1.Fire f.Status.FirewallStats.DeviceStats = deviceStats idsStats := firewallv1.IDSStatsByDevice{} - if r.EnableIDS { // checks the CLI-flag - s := suricata.New() - ss, err := s.InterfaceStats() + if r.Suricata.EnableIDS { + ss, err := r.Suricata.InterfaceStats() if err != nil { return err } diff --git a/main.go b/main.go index 078282ff..29dfa01c 100644 --- a/main.go +++ b/main.go @@ -24,8 +24,8 @@ import ( "os" "time" - "github.com/metal-stack/firewall-controller/controllers" - "github.com/metal-stack/firewall-controller/controllers/crd" + "github.com/metal-stack/firewall-controller/pkg/suricata" + "github.com/metal-stack/metal-lib/pkg/sign" "github.com/metal-stack/v" apiextensions "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1beta1" @@ -35,6 +35,9 @@ import ( ctrl "sigs.k8s.io/controller-runtime" "sigs.k8s.io/controller-runtime/pkg/log/zap" + "github.com/metal-stack/firewall-controller/controllers" + "github.com/metal-stack/firewall-controller/controllers/crd" + firewallv1 "github.com/metal-stack/firewall-controller/api/v1" // +kubebuilder:scaffold:imports ) @@ -158,7 +161,7 @@ func main() { Client: mgr.GetClient(), Log: ctrl.Log.WithName("controllers").WithName("Firewall"), Scheme: mgr.GetScheme(), - EnableIDS: enableIDS, + Suricata: suricata.New(enableIDS), EnableSignatureCheck: enableSignatureCheck, CAPubKey: caPubKey, }).SetupWithManager(mgr); err != nil { diff --git a/pkg/network/suricata.go b/pkg/network/suricata.go deleted file mode 100644 index de839215..00000000 --- a/pkg/network/suricata.go +++ /dev/null @@ -1,15 +0,0 @@ -package network - -import ( - "github.com/metal-stack/metal-networker/pkg/netconf" -) - -func ReconcileSuricata(kb netconf.KnowledgeBase, enableIDS bool) { - configurator := netconf.FirewallConfigurator{ - CommonConfigurator: netconf.CommonConfigurator{ - Kb: kb, - }, - EnableIDS: enableIDS, - } - configurator.ConfigureSuricata() -} diff --git a/pkg/suricata/stats.go b/pkg/suricata/stats.go deleted file mode 100644 index 63b47ff9..00000000 --- a/pkg/suricata/stats.go +++ /dev/null @@ -1,53 +0,0 @@ -package suricata - -import ( - "context" - - "github.com/ks2211/go-suricata/client" -) - -// defaultSocket to communicate with suricata -const defaultSocket = "/run/suricata-command.socket" - -type Suricata struct { - socket string -} - -type InterfaceStats map[string]InterFaceStat - -type InterFaceStat struct { - Drop int - InvalidChecksums int - Pkts int -} - -func New() Suricata { - return Suricata{socket: defaultSocket} -} - -func (s *Suricata) InterfaceStats() (*InterfaceStats, error) { - suricata, err := client.CreateSocket(s.socket) - if err != nil { - return nil, err - } - defer suricata.Close() - - ifaces, err := suricata.IFaceListCommand(context.Background()) - if err != nil { - return nil, err - } - result := InterfaceStats{} - for _, iface := range ifaces.Ifaces { - stat, err := suricata.IFaceStatCommand(context.Background(), client.IFaceStatRequest{IFace: iface}) - if err != nil { - return nil, err - } - result[iface] = InterFaceStat{ - Drop: stat.Drop, - InvalidChecksums: stat.InvalidChecksums, - Pkts: stat.Pkts, - } - } - - return &result, nil -} diff --git a/pkg/suricata/suricata.go b/pkg/suricata/suricata.go new file mode 100644 index 00000000..5ba4d8c8 --- /dev/null +++ b/pkg/suricata/suricata.go @@ -0,0 +1,94 @@ +package suricata + +import ( + "context" + "fmt" + "os/exec" + + "github.com/metal-stack/metal-networker/pkg/netconf" + + "github.com/ks2211/go-suricata/client" +) + +const ( + suricataService = "suricata.service" + systemctlBin = "/bin/systemctl" + + // defaultSocket to communicate with suricata + defaultSocket = "/run/suricata-command.socket" +) + +type Suricata struct { + socket string + EnableIDS bool +} + +type InterfaceStats map[string]InterFaceStat + +type InterFaceStat struct { + Drop int + InvalidChecksums int + Pkts int +} + +func New(enableIDS bool) *Suricata { + return &Suricata{ + socket: defaultSocket, + EnableIDS: enableIDS, + } +} + +func (s *Suricata) InterfaceStats() (*InterfaceStats, error) { + suricata, err := client.CreateSocket(s.socket) + if err != nil { + return nil, err + } + defer suricata.Close() + + ifaces, err := suricata.IFaceListCommand(context.Background()) + if err != nil { + return nil, err + } + result := InterfaceStats{} + for _, iface := range ifaces.Ifaces { + stat, err := suricata.IFaceStatCommand(context.Background(), client.IFaceStatRequest{IFace: iface}) + if err != nil { + return nil, err + } + result[iface] = InterFaceStat{ + Drop: stat.Drop, + InvalidChecksums: stat.InvalidChecksums, + Pkts: stat.Pkts, + } + } + + return &result, nil +} + +func (s *Suricata) ReconcileSuricata(kb netconf.KnowledgeBase, enableIDS bool) error { + if enableIDS != s.EnableIDS { + configurator := netconf.FirewallConfigurator{ + CommonConfigurator: netconf.CommonConfigurator{ + Kb: kb, + }, + EnableIDS: enableIDS, + } + configurator.ConfigureSuricata() + + if err := s.restart(); err != nil { + return fmt.Errorf("failed to restart suricata: %w", err) + } + s.EnableIDS = enableIDS + } + + return nil +} + +func (s *Suricata) restart() error { + c := exec.Command(systemctlBin, "restart", suricataService) + err := c.Run() + if err != nil { + return fmt.Errorf("could not reload suricata service, err: %w", err) + } + return nil +}