Support #7457
openResolving Multi-Packet HTTP Request Handling Issues in Suricata IPS Mode
Description
We are using Suricata in IPS mode as the L7 network policy engine for our project. One of our simple policies is to allow HTTP requests with the `GET` method only while denying all other protocols, including HTTP requests using the `POST` or `PUT` methods. The corresponding Suricata rules are defined as follows:
# Reject non-allowed traffic reject http any any -> any any (msg: "Reject by AntreaNetworkPolicy:default/egress-allow-http"; flow: to_server, established; sid: 1;) # Allow HTTP GET requests to the /echo endpoint pass http any any -> any any (msg: "Allow HTTP by AntreaNetworkPolicy:default/egress-allow-http"; http.uri; content:"/echo"; startswith; http.method; content:"GET"; sid: 2;)
Test Cases¶
We designed test cases under the assumption that the MTU of interfaces connected to Suricata is 1500 bytes. The test cases are as follows:
- Case 1:
Command: `curl http://192.168.77.101/echo?msg=$(head -c 2000 </dev/zero | tr '\0' 'A')`
Description: The HTTP payload is split across multiple packets due to its size. - Case 2:
Command: `curl http://192.168.77.101/echo?msg=$(head -c 100 </dev/zero | tr '\0' 'A')`
Description: The HTTP payload fits within a single packet. - Case 3:
Command: `curl http://192.168.77.101/hostname`
Description: A request to an endpoint not allowed by the policy (e.g., `/hostname`). - Case 4:
Description: Traffic using other L7 protocols (e.g., TCP, UDP, or ICMP).
Expected Behavior¶
- Case 1 and Case 2: Allowed, as they match the policy permitting HTTP GET requests to `/echo`.
- Case 3 and Case 4: Rejected, as they do not match the allowed policy.
Observed Behavior¶
- Case 2-4: Behave as expected.
- Case 1: Fails unexpectedly.
- When the HTTP payload is split across multiple packets, the first packet containing part of the HTTP data matches the `reject` rule (SID: 1). This prematurely interrupts the connection, even though the request aligns with the policy.
Problem¶
The Suricata rules are not correctly handling HTTP payloads split across multiple packets (e.g., Case 1). The partial match with the `reject` rule on the initial packet disrupts the flow, preventing valid requests from being allowed.
Request¶
Could you provide guidance on how to modify the Suricata rules or configuration to ensure that HTTP requests spanning multiple packets are properly evaluated before a decision is made?
Thank you for your help!
Besides, this is the extra config we are using which is included in /etc/suricata/suricata.yaml. Maybe it could be helpful.
%YAML 1.1
---
outputs:
- eve-log:
enabled: yes
filetype: regular
filename: eve-%Y-%m-%d.json
rotate-interval: day
pcap-file: false
community-id: false
community-id-seed: 0
xff:
enabled: no
types:
- alert:
packet: yes
- http:
extended: yes
- tls:
extended: yes
- eve-log:
enabled: yes
filetype: unix_stream
filename: /var/run/suricata/suricata_eve.socket
pcap-file: false
community-id: false
community-id-seed: 0
xff:
enabled: no
types:
- http:
extended: yes
af-packet:
- interface: antrea-l7-tap0
threads: auto
cluster-id: 80
cluster-type: cluster_flow
defrag: no
use-mmap: yes
tpacket-v2: yes
checksum-checks: no
copy-mode: ips
copy-iface: antrea-l7-tap1
- interface: antrea-l7-tap1
threads: auto
cluster-id: 81
cluster-type: cluster_flow
defrag: no
use-mmap: yes
tpacket-v2: yes
checksum-checks: no
copy-mode: ips
copy-iface: antrea-l7-tap0
multi-detect:
enabled: yes
selector: vlan
Updated by Hongliang Liu 10 days ago
We don't change the default options of Suricata and only include the above extra config file.