Path-B r11: bridging Squid ICAP and Suricata AF_PACKET IPS with a synthetic FlowBus

Hi everyone,

I would like to share a small preproduction lab project I have been working on: Path-B v8.0-beta1-r11.

It is not meant to be a production security gateway and it is not a dashboard project. It is an architectural experiment around a fairly specific question:

Can a Squid ICAP transaction be turned into a synthetic cleartext network flow, inspected by Suricata in AF_PACKET IPS mode, and then mapped back into a deterministic ICAP allow or block response?

The repository is here:

Architecture in one picture

The validated lab path is roughly this:

Client / Browser
  -> Squid 6.x explicit proxy with SSL-Bump
  -> ICAP REQMOD / RESPMOD cleartext transaction
  -> Path-B ICAP / FlowBus orchestrator
  -> synthetic TCP/HTTP endpoint flow
  -> pbfb_suri_a
  -> Suricata 8.0.4 AF_PACKET IPS
  -> pbfb_suri_b
  -> EVE / fast.log / FlowBus evidence
  -> deterministic ICAP allow or HTTP 403 block back to Squid

The FlowBus part is a small Linux namespace and veth setup. The ICAP server injects the Squid-provided cleartext into a synthetic TCP/HTTP flow. Suricata sits between the two FlowBus interfaces in copy-mode: ips. If a Suricata drop rule fires and the event is correlated in time, Path-B returns a block response to Squid.

The current r11 lab validation uses Suricata 8.0.4, AF_PACKET IPS, Hyperscan support, and rules_failed=0 after suricata -T. Direct EICAR URLs and the indirect browser download path from the EICAR website are blocked, while normal websites remain usable and fast in the test setup.

What I find interesting

The main design goal is that Suricata remains the security authority.

Earlier iterations had local ICAP-side EICAR safety checks. Those were useful for debugging, but they also made the result less honest: it was no longer clear whether Suricata or the ICAP code produced the final block. In r11, the active enforcement path is Suricata-native again. Detection logic belongs in Suricata rules, and Path-B acts as the correlation and transport layer between Squid and Suricata.

The second interesting part is the timing model. Squid expects a synchronous ICAP answer per transaction. Suricata emits events asynchronously through EVE and fast.log. Path-B therefore has to correlate a synthetic flow, a request ID, selected fallback metadata, and Suricata output inside a strict ICAP deadline.

This is the part I would most like feedback on. It works in the lab, but it is clearly a design tradeoff.

What it is not

I want to be careful with the claims here.

  • It is not a production-ready appliance.
  • It is not a native Suricata ICAP integration. Suricata does not speak ICAP here; Path-B bridges ICAP to a synthetic AF_PACKET inspection path.
  • It is not an HTTP/2 or HTTP/3 native inspection system.
  • It is not AF_XDP, DPDK, or eBPF/TC. r11 deliberately uses AF_PACKET because it is simple, reproducible, and close to Suricata’s standard IPS lab workflow.
  • It is not open source in the OSI sense. The repository is source-available for lab, education, research, and controlled preproduction testing. The license file spells out the restrictions.

Protocol scope

This point is important.

HTTP/1.0 and HTTP/1.1: yes, this is the validated path. HTTPS over CONNECT is handled through Squid SSL-Bump, and the resulting cleartext is adapted through ICAP REQMOD and RESPMOD.

HTTP/2: modern sites may still work through browser fallback, proxy behaviour, or Squid normalization, but Path-B r11 should not be described as a native HTTP/2 frame-inspection backend. Suricata sees the cleartext transaction provided to ICAP, not native h2 frames.

HTTP/3 / QUIC: no. r11 does not inspect HTTP/3 natively. HTTP/3 is UDP/QUIC based, while this lab is built around Squid, TCP CONNECT, SSL-Bump, and ICAP. For strict inspection in this model, UDP/443 should be blocked at the client network or gateway so clients fall back to TCP-based HTTPS through the proxy.

Why I am posting it here

I would be interested in technical feedback from people who know Suricata’s IPS behaviour better than I do, especially around these points:

  1. Synthetic L2 injection into AF_PACKET IPS
    Is this a reasonable experiment, or is there a cleaner approach using NFQUEUE, eBPF/TC, or another Suricata integration path?

  2. EVE correlation under deadline pressure
    How would you model tight ICAP deadlines against asynchronous Suricata output? Is a request-ID marker plus metadata fallback defensible, or is there a better correlation primitive?

  3. Rule design for proxy-presented cleartext
    The lab uses a small local SID range for validation rules. Is there a better convention for rules that are only intended for synthetic proxy-cleartext inspection?

  4. Future H1/H2/H3 direction
    A more native future design might move away from Squid as the protocol translator and use a real H1/H2/H3 terminator in front of the inspection path. Envoy ext_proc, HAProxy SPOE, or a dedicated QUIC/H2 terminator could be interesting research directions. I am not announcing such a project; I only think the protocol question is worth documenting.

Current lab result

The current test state is documented in the repository, including the installer workflow and the Windows client tests. In the confirmed r11 lab:

EICAR direct URL tests:           blocked
EICAR browser indirection 308-b:  blocked
HTTP baseline test:               200 OK
Suricata/ICAP block test:         403 Forbidden
HTTPS SSL-Bump trust test:        200 OK
Normal websites:                  allowed and fast
Suricata rules_failed:            0

Closing thought

For me, Path-B is mainly an architecture pattern: keep Squid’s ICAP contract, keep Suricata authoritative for the verdict, and bridge the two with a synthetic cleartext FlowBus.

I do not know yet whether this is the right long-term direction, but the current lab result is good enough that I think it is worth discussing publicly.

Feedback, criticism, and alternative design ideas are very welcome.

Cheers,

Path-B maintainer
Cetux