Running Suricata IPS AF-Packet in docker container

Hi my friends,

I have a really specific task to run Suricata in IPS mode by Af-packet in docker and use It as a gateway for Nginx server also running in docker on same internal network.
In Af-packet because docker containers running on linuxkit or WSL dont have a NQUEUE kernel module and adding is impossible (maybe I am wrong, but It will be a really painful and Ill try to avoid it if its possible).

I am using this image created by jasonish:

First of all I will try to explain my infrastructure

In my suricata.yml looks like this:

vars:
  # more specific is better for alert accuracy and performance
  address-groups:
    HOME_NET: "[172.21.0.0/16]"

    EXTERNAL_NET: "!$HOME_NET"

    HTTP_SERVERS: "$HOME_NET"

.......
.......

af-packet:
  - interface: eth1
    threads: 1
    defrag: no
    cluster-id: 98
    cluster-type: cluster_flow
    copy-mode: ips
    copy-iface: eth0
    buffer-size: 64535
    use-mmap: yes
  - interface: eth0
    threads: 1
    cluster-id: 97
    defrag: no
    cluster-type: cluster_flow
    copy-mode: ips
    copy-iface: eth1
    buffer-size: 64535
    use-mmap: yes

My docker infrastructure looks like this:

Important parts from my docker compose file:

services:
  # Suricata service
  suricata:
    image: jasonish/suricata:latest
    command: suricata -i eth0 -I eth1 --af-packet

    networks:
      suricata_network:
        ipv4_address: 172.20.0.2    
      shared_network:
        ipv4_address: 172.21.0.2 

    cap_add:
      - net_admin
      - net_raw
      - sys_nice

    #cpus: 2
    #mem_limit: 4000m
    volumes:
      #- C:\UserData\z004se1x\Documents\GitHub\ddos-ev-tech-optimalisation\suricata.yml:/etc/suricata/suricata.yaml
      - /suricata.yml
      - suricata_data:/var/log/suricata

  nginx:
    image: nginx:latest
    ports:
      - 8080:80
    volumes:
      - ./nginx.conf:/etc/nginx/nginx.conf
    networks:
      shared_network:
        ipv4_address: 172.21.0.3
    cpus: 0.5
    mem_limit: 512m

networks:
  suricata_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.20.0.0/16

  shared_network:
    driver: bridge
    ipam:
      config:
        - subnet: 172.21.0.0/16

Now my questions:

  1. I am trying to set suricata to block permanently IP addresses from which there is a big flow of HTTP requests (40+ per sec. for example). But I dont know how can I achieve this with af-packet.

  2. I dont know how to set correct forwarding from: suricata_network → suricata → shared_network → nginx and back. With Iptables it’s easy but how I said in docker container there is no kernel module for this. So are there any options how to make it work ?

I am a newbie so please try to be gentle on me :-/
Thank you for your tips, tricks
Michal

Hello, and welcome to Suricata,

First, I’ve never had luck getting AF_PACKET IPS to work on anything but physical interfaces, and I’ve spent a few hours trying to get something working with AF_PACKET IPS solely in Docker for test purposes, but have never succeeded.

When it comes to AF_PACKET IPS you have to think like you are connecting the interfaces together with a switch, or even an ethernet coupler. No routing, address translation, etc. is occurring. I often test the scenarios first using standard Linux kernel bridging, because if that’s not going to work, AF_PACKET IPS isn’t either.

From your docker-compose (ok, coming clean, I don’t know docker networking that well) it looks as though you have Suricata sitting between 2 different /16 networks. In that case, AF_PACKET IPS is not going to work as you need something to route the packets, and as far as I know, NFQ is the only way to tap into that on Linux.work, AF_PACKET IPS isn’t either.

From your docker-compose (ok, coming clean, I don’t know docker networking that well) it looks as though you have Suricata sitting between 2 different /16 networks. In that case, AF_PACKET IPS is not going to work as you need something to route the packets, and as far as I know, NFQ is the only way to tap into that on Linux.

I hope that helps, even if only to lay out the challenges…

1 Like

So from your side the best solution is to use IPS mode out of container (in normal virtual machine or on desktop itself) or trying to make it but probably without any success because of docker env. :frowning: .

Hi @demoxCZ ,
What did you choose in the end? Were you able to set up IDS in docker?