Suricata in Kubernetes

Hi Suricata Developers!

I wanted to know how can I use Suricata as NIDS in Kubernetes, can you guide me with any links or blogs, it would be really useful.

Reviving this for the sake of having an answer, in case others also have a similar question.

I’m no expert, but I’ve found a few things that may be able to help.

Again, old post, but since someone recently had a similar question during a talk I was attending, I think it may be useful for others…

2 Likes

I’ve been researching this as well. And your post @jufajardini gave me a few ideas.

I came up with this configuration:

---
apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: suricata
spec:
  selector:
    matchLabels:
      app: suricata
  template:
    metadata:
      labels:
        app: suricata
      name: suricata
    spec:
      hostIPC: true
      hostPID: true
      hostNetwork: true
      containers:
        - name: suricata
          image: jasonish/suricata:latest
          command:
            - /usr/bin/suricata
            - -i
            - eth0
            - -i
            - eth1
            - -i
            - eth2
            - -i
            - eth3
          securityContext:
            privileged: true
          volumeMounts:
            - mountPath: /host/dev
              name: dev
            - mountPath: /var/run/docker.sock
              name: docker-socket-mount
            - name: "varlog"
              mountPath: /var/log/suricata
        # suricata-tail-eve-log container
        - name: suricata-tail-eve-log
          image: bash
          command:
            - tail
            - -F
            - /var/log/suricata/eve.json
          resources:
            requests:
              memory: 0Mi
          volumeMounts:
            - name: "varlog"
              mountPath: /var/log/suricata
        # suricata-tail-fast-log container
        - name: suricata-tail-fast-log
          image: bash
          command:
            - tail
            - -F
            - /var/log/suricata/fast.log
          resources:
            requests:
              memory: 0Mi
          volumeMounts:
            - name: "varlog"
              mountPath: /var/log/suricata
        # suricata-tail-stats-log container
        - name: suricata-tail-stats-log
          image: bash
          command:
            - tail
            - -F
            - /var/log/suricata/stats.log
          resources:
            requests:
              memory: 0Mi
          volumeMounts:
            - name: "varlog"
              mountPath: /var/log/suricata
        # suricata-tail-suricata-log container
        - name: suricata-tail-suricata-log
          image: bash
          command:
            - tail
            - -F
            - /var/log/suricata/suricata.log
          resources:
            requests:
              memory: 0Mi
          volumeMounts:
            - name: "varlog"
              mountPath: /var/log/suricata
      volumes:
        - name: dev
          hostPath:
            path: /dev
        - name: docker-socket-mount
          hostPath:
            path: /var/run/docker.sock
        - name: "varlog"
          emptyDir: {}

And then inside the pod, run this command:

/usr/bin/suricata -i eth0 -i eth1 -i eth2 -i eth3

This is just for testing purposes. My nodes have each 4 interfaces. I’m using AWS EKS. And I tried testing a simple telnet command:

telnet 1.1.1.5 50049

While tailing the eve.json file, and I’m happy to tell you I can see it there:

{"timestamp":"2021-09-22T01:59:07.009270+0000","flow_id":628562234223859,"in_iface":"eth0","event_type":"flow","src_ip":"172.16.7.219","src_port":25506,"dest_ip":"1.1.1.5","dest_port":50049,"proto":"TCP","flow":{"pkts_toserver":7,"pkts_toclient":0,"bytes_toserver":518,"bytes_toclient":0,"start":"2021-09-22T01:53:52.240883+0000","end":"2021-09-22T01:54:56.242484+0000","age":64,"state":"new","reason":"unknown","alerted":false},"tcp":{"tcp_flags":"02","tcp_flags_ts":"02","tcp_flags_tc":"00","syn":true,"state":"syn_sent"}}

And this is interesting because the pod from which the telnet command was ran has hostNetwork enabled, so it gets an IP that is different from the host itself:

root@my-pod-name-7b559685c5-b8lcm:/# ifconfig
eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 9001
        inet 172.16.6.241  netmask 255.255.255.255  broadcast 0.0.0.0
        ether 22:04:e1:14:12:71  txqueuelen 0  (Ethernet)
        RX packets 33627  bytes 46410965 (44.2 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 34653  bytes 34578156 (32.9 MiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0

But as you can see from the eve file line it is using the main eth0 from the host.

I’m still researching this to see if we can analyze our traffic inside the kubernetes cluster.

Hopefully this helps you @Heeraj_Nair

UPDATE

Added side cars to read the logs and send them to cloudwatch via stdout

2 Likes