Http protocol detection/parser not working on forwarded packts

Hello,

We want to detect HTTP requests with specific keywords, like for example the word “delete”:

http://domain-name/**delete**

The following rule, does not match with packets that are forwarded on the box running Suricata:

alert http any any → any any (msg:“delete detected”; content:“delete”; http_uri; nocase; sid:1; rev:1)

However, it does match with packets that are originate from or are targeted at the box itself. (Tested on both Linux Suricata 3.2.2 and FreeBSD Suricata 4.0.0 and 5.0.1). I tested this both in netmap and libpcap capture modes.

However, as soon as the HTTP protocol detection module gets out of the way, it starts to work as expected:

alert ip any any → any any (msg:“delete detected”; content:“delete”; nocase; sid:1; rev:1)

This rule does match with forwarded packets.

Can you please let me know if I am missing something?

Can you share a stats.log entry from when it fails your test?

This is the stats.log before the HTTP request:

Date: 9/1/2020 – 10:25:33 (uptime: 0d, 00h 00m 08s)
Counter | TM Name | Value
capture.kernel_packets | Total | 182
decoder.pkts | Total | 201
decoder.bytes | Total | 21224
decoder.ipv4 | Total | 120
decoder.ipv6 | Total | 10
decoder.ethernet | Total | 201
decoder.tcp | Total | 105
decoder.udp | Total | 12
decoder.icmpv4 | Total | 8
decoder.icmpv6 | Total | 5
decoder.avg_pkt_size | Total | 105
decoder.max_pkt_size | Total | 902
app_layer.flow.failed_udp | Total | 5
flow.spare | Total | 10000
flow_mgr.rows_checked | Total | 65536
flow_mgr.rows_skipped | Total | 65536
tcp.memuse | Total | 1638400
tcp.reassembly_memuse | Total | 12320544
flow.memuse | Total | 7076608

and after:

Date: 9/1/2020 – 10:25:40 (uptime: 0d, 00h 00m 15s)
Counter | TM Name | Value
capture.kernel_packets | Total | 245
decoder.pkts | Total | 256
decoder.bytes | Total | 31960
decoder.ipv4 | Total | 162
decoder.ipv6 | Total | 10
decoder.ethernet | Total | 256
decoder.tcp | Total | 137
decoder.udp | Total | 18
decoder.icmpv4 | Total | 12
decoder.icmpv6 | Total | 5
decoder.avg_pkt_size | Total | 124
decoder.max_pkt_size | Total | 1514
tcp.sessions | Total | 1
tcp.syn | Total | 1
tcp.synack | Total | 1
detect.alert | Total | 1
app_layer.flow.http | Total | 1
app_layer.tx.http | Total | 2
app_layer.flow.failed_udp | Total | 6
flow.spare | Total | 10000
flow_mgr.rows_checked | Total | 65536
flow_mgr.rows_skipped | Total | 65536
tcp.memuse | Total | 1638400
tcp.reassembly_memuse | Total | 12320544
http.memuse | Total | 34450
flow.memuse | Total | 7078336

Can you provide pcaps of the two different cases (forwarded and directed)?

The test setup is a multi-path routing scenario, and it turns out that Suricata is not seeing the whole TCP flow.

However, it is seeing the packet that carries the HTTP request in question.

Is there any way to configure Suricata to work on HTTP payloads even if it is not seeing the whole flow?

You could try enabling stream.midstream and stream.async-oneside.

I got the same issue than Amin when running Suricata on a pcap with only http requests. Only the first packet triggers an alert and the rest of the capture is not seen as http flow. When splitting the pcap in single-packet pcaps, each pcap triggers the alert as expected. Can be reproduced by keeping only client to server requests from this pcap.

stream.midstream and stream.async-oneside are enabled. It works fine when seeing the whole trafic but any idea why Suricata is not able to detect in this case ? According to FAQ, Suricata HTTP detection is expected to use “patterns. Detection only on response also works.

@Amin_Saba, did you find a solution ?