Hello,
I’m running Suricata in IPS mode on a public Debian server, using nftables and NFQUEUE. When Suricata is running, new outbound TCP connections from the server can hang, even though the NFQUEUE rule is in the
INPUTchain only.Stopping Suricata immediately restores normal outbound connectivity.
System
- Debian 13 (Trixie)
- Suricata 8.0.7
- nftables
- NFQUEUE queue 0
- Suricata started with
-q 0- IPS configuration:
nfq: mode: accept fail-open: yes
suricata -Tsucceeds and Suricata processes packets normally.Problem
The clearest example is a PHP application on the server which makes an HTTPS request to OpenWeatherMap.
With Suricata running:
CONNECT=0.000000s START=0.000000s TOTAL=10.002769sThe
curlcommand was using--connect-timeout 10, so the connection never completed.With Suricata stopped, the same connection establishes immediately:
* Trying 141.95.47.140:443... * Connected to api.openweathermap.org (141.95.47.140) port 443DNS resolution works correctly, and routing is correct:
141.95.47.139 via 147.135.136.254 dev eno1 src 147.135.136.17 uid 0The destination IP can change because OpenWeatherMap has multiple addresses.
A
tcpdumprunning onanyduring the failed connection did not show the expected TCP SYN.Important nftables detail
The permanent NFQUEUE rule is in the
INPUTchain:chain input { type filter hook input priority filter; policy drop; ip saddr @admin_ip accept iif "lo" accept counter packets 942605 bytes 113912625 queue flags bypass to 0 ct state established,related accept ip protocol icmp accept ip6 nexthdr ipv6-icmp accept meta nfproto ipv6 drop ... }The complete relevant structure is:
table inet filter { set admin_ip { type ipv4_addr elements = { 87.88.33.47 } } chain input_early { type filter hook input priority -20; policy accept; ip saddr @admin_ip accept } chain input { type filter hook input priority filter; policy drop; ip saddr @admin_ip accept iif "lo" accept counter packets 942605 bytes 113912625 queue flags bypass to 0 ct state established,related accept ip protocol icmp accept ip6 nexthdr ipv6-icmp accept meta nfproto ipv6 drop tcp dport 6969 accept tcp dport { 80, 443 } accept tcp dport { 25, 110, 143, 465, 587, 993, 995 } accept tcp dport 10000 ip saddr @admin_ip accept tcp dport 20000 accept tcp dport 8443 accept tcp dport 8081 accept ct state new tcp flags syn tcp dport 35565-35569 limit rate 15/second burst 30 packets accept ct state new tcp flags syn tcp dport 35565-35569 drop tcp dport 35565-35569 accept tcp flags syn ct state new limit rate over 60/second burst 100 packets drop tcp flags syn ct state new limit rate over 30/second burst 50 packets drop tcp dport 10050 ip saddr @admin_ip accept counter packets 1834164 bytes 119245484 drop } chain forward { type filter hook forward priority filter; policy drop; ct state established,related accept iifname "pterodactyl0" accept oifname "pterodactyl0" accept } chain output { type filter hook output priority filter; policy accept; # Temporary test only: ct state new tcp dport 443 queue flags bypass to 0 } }The
OUTPUTNFQUEUE rule above was added only as a diagnostic test. It did not solve the problem. The outbound HTTPS connection still timed out with Suricata running.The normal
OUTPUTpolicy is:policy acceptand:
iptables -S OUTPUT -P OUTPUT ACCEPTAnother important observation
My home IP (
87.88.33.47) is inadmin_ip.Therefore incoming connections from my home PC are accepted here:
ip saddr @admin_ip acceptbefore reaching the NFQUEUE rule.
Nevertheless, I initially observed significant delays in some HTTP/API connections from my home PC.
For example, the main website was fast:
https://www.extra-ordinaire.com/with curl taking about 0.08 s.
The API endpoint:
https://lesmdc.net/meg-e/src/could take about 134 seconds.
The reason for that particular API delay was subsequently identified as a PHP cURL call to OpenWeatherMap without a timeout. The OpenWeatherMap connection itself fails only while Suricata is running, so this application-level delay is a consequence rather than the root cause.
NFQUEUE status
The NFQUEUE itself does not appear saturated.
/proc/net/netfilter/nfnetlink_queueshowed:0 709319 0 2 65531 0 0 30 1The queue length is zero.
Suricata counters
The latest
dump-counterswhile Suricata was running showed:rules_loaded: 53115 ips.accepted: 3449 ips.blocked: 1023 ips.rejected: 0 drop_reason.nfq_error: 0 detect.alert: 20 detect.alert_queue_overflow: 0 RX-NFQ#0.decoder.pkts: 4473 TX#00.ips.accepted: 3449 TX#00.ips.blocked: 1023There were no NFQUEUE errors reported.
What I have tested
- DNS resolution: OK
- Routing: OK
- ICMP: normal, approximately 7–9 ms from my home connection
- Normal inbound HTTPS: works
- Outbound HTTPS with Suricata stopped: works immediately
- Outbound HTTPS with Suricata running: TCP connection hangs
- NFQUEUE queue is not full
OUTPUTnftables policy is ACCEPTiptables OUTPUTis ACCEPT- Adding a temporary
OUTPUT -> NFQUEUE 0rule did not solve the problemtcpdumpdoes not see the expected outbound SYN while Suricata is running- Stopping Suricata immediately restores outbound connectivity
Question
I would like to understand why simply running Suricata with NFQUEUE on INPUT can prevent new outbound TCP connections from being established, even though:
- OUTPUT is ACCEPT;
- there is no permanent OUTPUT NFQUEUE rule;
- the INPUT NFQUEUE queue is not saturated;
fail-open: yesis configured;- the outbound SYN does not appear in tcpdump when Suricata is running.
Is this a known interaction between Suricata 8.0.7, NFQUEUE, conntrack and nftables?
Is there something specific I should check regarding NFQUEUE/conntrack state, hook ordering, or Suricata’s NFQ handling?
I have currently stopped Suricata to restore normal outbound connectivity.
Thanks for any help.