Project

General

Profile

Actions

Bug #8390

open

firewall: reject action to send TCP RST / ICMP unreachable

Added by Yash Datre 12 days ago. Updated 4 days ago.

Status:
New
Priority:
Normal
Assignee:
Target version:
Affected Versions:
Effort:
Difficulty:
Label:

Description

Suricata's firewall mode accepts reject:flow and reject:packet syntax, and the rules load without error. However, the reject action silently degrades to a plain drop — no TCP RST (or ICMP unreachable for UDP) is sent, no alert is generated, and stats.ips.rejected stays at 0.

This is needed for the Firewall mode, which supports a REJECT action that notifies the client/server that the connection is being refused, rather than silently dropping packets and leaving the peer to time out.

Current behavior on 8.0.4:
  • reject:flow rule loads successfully (no parse error)
  • When the rule matches, the flow is dropped (same as drop:flow )
  • stats.ips.rejected remains 0; the count goes to stats.ips.blocked instead
  • No TCP RST packet is injected
  • No alert is generated for the reject rule match ( detect.alerts_suppressed absorbs it)
Expected behavior:
  • reject:flow on a TCP flow should inject a TCP RST to both client and server before dropping
  • reject:packet on a UDP flow should inject an ICMP port unreachable before dropping
  • stats.ips.rejected should increment (not stats.ips.blocked )
  • An alert event should be logged with the reject rule's signature ID and action: blocked
  • The drop event should indicate the reason is rules (from the reject rule), not default app policy

Rules tested :

accept:hook tcp:all any any -> any 443 (flow:not_established; sid:1;)
accept:hook tcp:all any any <> any 443 (flow:established; sid:2;)
accept:hook tls:client_in_progress any any -> any any (sid:3;)
reject:flow tls:client_hello_done any any -> any any (tls.sni; content:"suricata.io"; endswith; sid:99;)

The test accepts the TCP handshake and TLS client_in_progress, then rejects the flow at client_hello_done based on SNI matching suricata.io.

Result:

  • stats.ips.accepted : 2, stats.ips.blocked : 11, stats.ips.rejected : 0
  • drop_reason.default_app_policy : 1, drop_reason.flow_drop : 9, drop_reason.default_packet_policy : 1
  • detect.alert : 0, detect.alerts_suppressed : 6
  • No alert or drop event references sid 99
  • All drop events show reason: "default app policy" or "reason: flow drop" — none show reason: "rules"

The reject rule matched (evidenced by the flow being dropped and alerts being suppressed), but the reject action was not executed — it behaved identically to a drop:flow .


Files

test.yaml (724 Bytes) test.yaml Yash Datre, 03/19/2026 03:00 AM
suricata.yaml (291 Bytes) suricata.yaml Yash Datre, 03/19/2026 03:00 AM
firewall.rules (578 Bytes) firewall.rules Yash Datre, 03/19/2026 03:00 AM
Actions #1

Updated by Victor Julien 12 days ago

  • Subject changed from Firewall mode: Wire reject action to send TCP RST / ICMP unreachable to firewall: reject action to send TCP RST / ICMP unreachable
Actions #2

Updated by Victor Julien 11 days ago

  • Assignee set to Victor Julien

The test at https://github.com/OISF/suricata-verify/pull/2977 shows that the basic reject action works, although it doesn't test the actual sending of RST packets.

Actions #3

Updated by Victor Julien 4 days ago

A live test shows that there are still some issues. The code does not by default use the correct interface to send out the RST in bridge mode.

Actions

Also available in: Atom PDF