Suricata IPS: Fixing Legitimate Traffic Drops by Disabling drop-invalid

I encountered a peculiar issue where my WordPress instance was unable to reach wordpress.org, and DokuWiki could not access its plugin repository. All standard network checks (wget, curl, DNS) worked fine, and no drops were registered by the standard firewall rules.

However, logging revealed a problem deep within the Intrusion Prevention System (IPS) layer.

The Diagnostic: Stream Errors

I noticed an unusually high number of dropped packets related to stream errors in the stats.log:

ips.drop_reason.flow_drop | Total | 837
ips.drop_reason.rules | Total | 3398
ips.drop_reason.stream_error | Total | 19347

This confirmed that Suricata’s TCP Stream Engine was classifying legitimate traffic as invalid, causing the connection to stall before the application layer could proceed. The volume of stream_error drops was alarmingly high.

Further investigation into Suricata’s internal statistics revealed details about the nature of the errors:

stream.fin_but_no_session                     | Total | 12508
stream.rst_but_no_session                     | Total | 2577
stream.pkt_spurious_retransmission            | Total | 14735

These specific counters (FINs/RSTs without an active session, spurious retransmissions) point to common issues in asymmetric routing or session tracking in complex bridged/virtualized environments.

The Workaround: Disabling Strict Stream Enforcement

Based on community discussions regarding unexpected drops in IPS mode, I tested a key stream-configuration variable.

The default setting drop-invalid: yes instructs Suricata to immediately drop packets it deems invalid according to its internal state machine (often due to out-of-sync sequence numbers or timing issues).

The Fix: I set this directive to no.

stream:
  memcap: 64mb
  memcap-policy: ignore  
  drop-invalid: no # Set to 'no' to fix legitimate traffic drops
  checksum-validation: yes
  midstream-policy: ignore
  inline: auto
  reassembly:

As soon as I applied this change, the traffic to wordpress.org and the DokuWiki repository resumed functioning normally.

Conclusion: The Security Trade-off

While this workaround immediately solved the connectivity problem, I am consciously accepting a security trade-off. Disabling drop-invalid instructs the IPS to allow potentially ambiguous or invalid packets to pass.

  • Risk: This allows a low-volume attacker to potentially use malformed packets to bypass the stream state-tracking.
  • Benefit: It ensures Service Availability for crucial application updates and connections that the IPS was incorrectly flagging due to virtualization or network environment subtleties.

My next step will be to investigate the root cause of the high stream_error count to see if the error is caused by a kernel-level configuration or a misaligned network path.

Sources / See Also (Quellen)

  1. Suricata Documentation. Stream Configuration and Settings (Specifically drop-invalid). https://docs.suricata.io/en/latest/configuration/stream.html
  2. Suricata Documentation. Understanding and Analyzing the Stats Log. https://docs.suricata.io/en/latest/output/stats/stats-log.html
  3. Suricata Documentation. IPS Mode and Traffic Drop Reasons. https://docs.suricata.io/en/latest/performance/ips-mode.html
  4. OISF Community Forum. Discussion on high stream errors/spurious retransmissions and network offloading. (Diese Art von Diskussion ist der primäre Fundort für solche Workarounds).
  5. Linux Manpage: ethtool. Documentation on Network Offloading (TSO, GSO, LRO) which often causes Suricata Stream issues.

OpenSSH Hardening Strategy: Auditing Policies and Mitigating Low-Strength Ciphers

OpenSSH ships with a default configuration that prioritizes high compatibility. However, this compatibility comes at a price: some of the included ciphers and algorithms may be outdated or contain known vulnerabilities. To strengthen the encryption and gain a transparent overview of known weaknesses, ssh-audit is the essential auditing tool.

My hardening strategy uses the Mozilla Security Guidelines on OpenSSH as a base, which I then refined using the specific findings from ssh-audit.

Part I: Initial Server Hardening and Auditing

Before tuning algorithms, I enforce core security policy: limiting access to specific users, disabling root login, and preventing password authentication.

AuthenticationMethods publickey
PermitRootLogin no
# AllowUsers replace-with-your-usernames,separate-by-comma

1. Installation and Usage of ssh-audit

I use pip3 to install and maintain ssh-audit to ensure I have the most current version, which is necessary for accurate vulnerability assessment.

Server Audit (Debian 12 Default) Output: Running ssh-audit localhost on a default installation reveals critical weaknesses. The output serves as our baseline:

# general
(gen) banner: SSH-2.0-OpenSSH_9.2p1 Debian-2+deb12u2
(gen) software: OpenSSH 9.2p1
(gen) compatibility: OpenSSH 8.5+, Dropbear SSH 2018.76+
(gen) compression: enabled (zlib@openssh.com)

# key exchange algorithms
(kex) sntrup761x25519-sha512@openssh.com    -- [info] available since OpenSSH 8.5
(kex) curve25519-sha256                     -- [info] available since OpenSSH 7.4, Dropbear SSH 2018.76
                                            `- [info] default key exchange since OpenSSH 6.4
(kex) curve25519-sha256@libssh.org          -- [info] available since OpenSSH 6.4, Dropbear SSH 2013.62
                                            `- [info] default key exchange since OpenSSH 6.4
(kex) ecdh-sha2-nistp256                    -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp384                    -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) ecdh-sha2-nistp521                    -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(kex) diffie-hellman-group-exchange-sha256 (3072-bit) -- [info] available since OpenSSH 4.4
                                                      `- [info] OpenSSH's GEX fallback mechanism was triggered during testing. Very old SSH clients will still be able to create connections using a 2048-bit modulus, though modern clients will use 3072. This can only be disabled by recompiling the code (see https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477).
(kex) diffie-hellman-group16-sha512         -- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) diffie-hellman-group18-sha512         -- [info] available since OpenSSH 7.3
(kex) diffie-hellman-group14-sha256         -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
                                            `- [info] available since OpenSSH 7.3, Dropbear SSH 2016.73
(kex) kex-strict-s-v00@openssh.com          -- [info] pseudo-algorithm that denotes the peer supports a stricter key exchange method as a counter-measure to the Terrapin attack (CVE-2023-48795)

# host-key algorithms
(key) rsa-sha2-512 (2048-bit)               -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
                                            `- [info] available since OpenSSH 7.2
(key) rsa-sha2-256 (2048-bit)               -- [warn] 2048-bit modulus only provides 112-bits of symmetric strength
                                            `- [info] available since OpenSSH 7.2
(key) ecdsa-sha2-nistp256                   -- [fail] using elliptic curves that are suspected as being backdoored by the U.S. National Security Agency
                                            `- [warn] using weak random number generator could reveal the key
                                            `- [info] available since OpenSSH 5.7, Dropbear SSH 2013.62
(key) ssh-ed25519                           -- [info] available since OpenSSH 6.5

# encryption algorithms (ciphers)
(enc) chacha20-poly1305@openssh.com         -- [info] available since OpenSSH 6.5
                                            `- [info] default cipher since OpenSSH 6.9
(enc) aes128-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes192-ctr                            -- [info] available since OpenSSH 3.7
(enc) aes256-ctr                            -- [info] available since OpenSSH 3.7, Dropbear SSH 0.52
(enc) aes128-gcm@openssh.com                -- [info] available since OpenSSH 6.2
(enc) aes256-gcm@openssh.com                -- [info] available since OpenSSH 6.2

# message authentication code algorithms
(mac) umac-64-etm@openssh.com               -- [warn] using small 64-bit tag size
                                            `- [info] available since OpenSSH 6.2
(mac) umac-128-etm@openssh.com              -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha2-512-etm@openssh.com         -- [info] available since OpenSSH 6.2
(mac) hmac-sha1-etm@openssh.com             -- [fail] using broken SHA-1 hash algorithm
                                            `- [info] available since OpenSSH 6.2
(mac) umac-64@openssh.com                   -- [warn] using encrypt-and-MAC mode
                                            `- [warn] using small 64-bit tag size
                                            `- [info] available since OpenSSH 4.7
(mac) umac-128@openssh.com                  -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 6.2
(mac) hmac-sha2-256                         -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha2-512                         -- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 5.9, Dropbear SSH 2013.56
(mac) hmac-sha1                             -- [fail] using broken SHA-1 hash algorithm
                                            `- [warn] using encrypt-and-MAC mode
                                            `- [info] available since OpenSSH 2.1.0, Dropbear SSH 0.28

# fingerprints
(fin) ssh-ed25519: SHA256:---
(fin) ssh-rsa: SHA256:---

# algorithm recommendations (for OpenSSH 9.2)
(rec) -ecdh-sha2-nistp256                   -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp384                   -- kex algorithm to remove 
(rec) -ecdh-sha2-nistp521                   -- kex algorithm to remove 
(rec) -ecdsa-sha2-nistp256                  -- key algorithm to remove 
(rec) -hmac-sha1                            -- mac algorithm to remove 
(rec) -hmac-sha1-etm@openssh.com            -- mac algorithm to remove 
(rec) !rsa-sha2-256                         -- key algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) !rsa-sha2-512                         -- key algorithm to change (increase modulus size to 3072 bits or larger) 
(rec) -diffie-hellman-group14-sha256        -- kex algorithm to remove 
(rec) -hmac-sha2-256                        -- mac algorithm to remove 
(rec) -hmac-sha2-512                        -- mac algorithm to remove 
(rec) -umac-128@openssh.com                 -- mac algorithm to remove 
(rec) -umac-64-etm@openssh.com              -- mac algorithm to remove 
(rec) -umac-64@openssh.com                  -- mac algorithm to remove 

# additional info
(nfo) For hardening guides on common OSes, please see: <https://www.ssh-audit.com/hardening_guides.html>
(nfo) Be aware that, while this target properly supports the strict key exchange method (via the kex-strict-?-v00@openssh.com marker) needed to protect against the Terrapin vulnerability (CVE-2023-48795), all peers must also support this feature as well, otherwise the vulnerability will still be present.  The following algorithms would allow an unpatched peer to create vulnerable SSH channels with this target: chacha20-poly1305@openssh.com.  If any CBC ciphers are in this list, you may remove them while leaving the *-etm@openssh.com MACs in place; these MACs are fine while paired with non-CBC cipher types.

Part II: Mitigating Weak Cryptography

1. Hardening Diffie-Hellman (GEX) Moduli

I use awk to filter the /etc/ssh/moduli file to enforce a minimum size of 3072 bits, eliminating low-strength moduli.

awk '$5 >= 3071' /etc/ssh/moduli > /etc/ssh/moduli.tmp && mv /etc/ssh/moduli.tmp /etc/ssh/moduli

2. Replacing Host Keys

I replace the default host keys with stronger settings, which is essential for modern security. The Ed25519 key is the current gold standard for key exchange performance and security.

rm /etc/ssh/ssh_host_*
ssh-keygen -t rsa -b 4096 -f /etc/ssh/ssh_host_rsa_key -N ""
ssh-keygen -t ed25519 -f /etc/ssh/ssh_host_ed25519_key -N ""

3. Finalizing the SSHD Configuration

I explicitly define the allowed algorithms in a dedicated drop-in file (/etc/ssh/sshd_config.d/ciphers.conf) to ensure that only the secure algorithms identified by ssh-audit remain.

# /etc/ssh/sshd_config.d/ciphers.conf
# Ciphers

HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519,rsa-sha2-512,rsa-sha2-256

KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,sntrup761x25519-sha512@openssh.com,diffie-hellman-group-exchange-sha256,diffie-hellman-group16-sha512,diffie-hellman-group18-sha512

Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,aes256-ctr,aes192-ctr,aes128-ctr

MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com

Part III: Auditing Clients and Avoiding Pitfalls

1. Client-Side Hardening

I recommend applying a strong default set of algorithms to the client’s ~/.ssh/config file to reduce its attack surface, overriding weak defaults when connecting to external hosts.

# ~/.ssh/config

Host *
    HashKnownHosts yes
    HostKeyAlgorithms ssh-ed25519-cert-v01@openssh.com,ssh-ed25519
    KexAlgorithms curve25519-sha256@libssh.org,curve25519-sha256,diffie-hellman-group16-sha512,...
    Ciphers chacha20-poly1305@openssh.com,aes256-gcm@openssh.com,aes128-gcm@openssh.com,...
    MACs hmac-sha2-512-etm@openssh.com,hmac-sha2-256-etm@openssh.com,umac-128-etm@openssh.com

2. Defense Tool Context (RKhunter and Lynis)

When using system auditing tools, I recognize that their checks can be incomplete or based on outdated assumptions.

  • RKhunter Context: RKhunter incorrectly read the active drop-in configuration (sshd_config.d), confirming the necessity of manual verification.
  • Lynis Context: Changing port 22 or disabling modern compression offers minimal additional protection on systems already hardened with public-key authentication. Do not apply settings blindly.

3. Reducing Service Footprint (Defense-in-Depth)

Finally, I hide the OpenSSH version for minor defense-in-depth:

Plaintext

# /etc/ssh/sshd_config.d/other.conf
Banner none
DebianBanner no

This reduces the public information available to automated scanners.

Sources / See Also

  1. Mozilla Security Guidelines. OpenSSH Recommended Configuration. https://wiki.mozilla.org/Security/Guidelines/OpenSSH
  2. SSH-Audit. SSH Hardening Guides for Common OSes. https://www.ssh-audit.com/hardening_guides.html
  3. OpenSSH. Release Notes for OpenSSH 7.4 (Removal of pre-auth compression). https://www.openssh.com/txt/release-7.4
  4. OpenSSH. Release Notes for OpenSSH 4.2 (Delayed compression). https://www.openssh.com/txt/release-4.2
  5. GitHub (OpenSSH Portable). Source Code Reference for GEX fallback mechanism. https://github.com/openssh/openssh-portable/blob/V_9_4/dh.c#L477
  6. CISOfy Lynis. Control Reference for SSH Hardening (SSH-7408). https://cisofy.com/controls/SSH-7408/

Bogon Defense: Integrating Dynamic IP Blacklists into Suricata’s Reputation System

Bogon networks are IP address ranges that should never appear on the public internet, as they are either reserved or unassigned. Blocking these ranges is a fundamental and highly effective security measure. While this can be done with simple firewall rules, integrating the blocklist directly into the Suricata IP Reputation system is far more performant.

I rely on the lists provided by Team Cymru for both IPv4 and IPv6 bogons.

1. IPv6 Whitelisting: The Link-Local Caveat

When running an IPS/Firewall, one must be careful not to block essential local network traffic. The global IPv6 bogon list often includes the Link-Local and Multicast ranges (fe80::/10 and ff02::/16) because they fall under the wider 8000::/1 block.

Since blocking these addresses is incorrect and breaks internal IPv6 communication, a specific pass rule for ICMPv6 is required.

Suricata Pass Rule and RFC Reference

The rule uses ip_proto:58 (ICMPv6) and is carefully scoped. I use the Suricata reference system to document the source of the decision (RFC 4890).

Reference Configuration (/etc/suricata/reference.config):

config reference: rfc       https://datatracker.ietf.org/doc/html/

The Final ICMPv6 Whitelist Rule:

pass ip [fe80::/10,ff02::/16] any -> any any (msg:"Pass essential ICMPv6 Link-Local traffic"; ip_proto:58; reference:rfc,rfc4890; sid:10; rev:1;)

2. Implementing the IP Reputation System

Suricata’s IP Reputation system is a performant alternative to sequential firewall checks. It loads external IP lists into an internal hashmap, allowing for a single, fast lookup per packet.

Configuration Setup

  1. Enable IP Reputation: Uncomment the relevant sections in suricata.yaml and define the list files:
# IP Reputation
reputation-categories-file: /etc/suricata/iprep/categories.txt
default-reputation-path: /etc/suricata/iprep
reputation-files:
 - bogons-v4.list
 - bogons-v6.list
  1. Define the Category: Define a specific category for bogons in the categories.txt file. The number 1 is the category ID used in the final rule.
# /etc/suricata/iprep/categories.txt
1,Bogons,fullbogons list

The Bash Automation Script (IPv4 Example)

A robust Bash script is needed to fetch the lists and format the output into the Suricata-specific IP Reputation format (IP,categoryID,score).

#!/bin/bash
# ... (Source URL and File paths defined) ...

# 1. Fetch the list and check for changes
wget -q -O "$TMPIPREPFILE" "$SRCURL"
# ... (Diff check to prevent unnecessary updates) ...

# 2. Format and load the list
if [ -s "$TMPIPREPFILE" ]; then
  # Remove current list for atomic update
  if [ -f $IPREPFILE ]; then
    rm $IPREPFILE
  fi

  # Add each CIDR block with the category ID (1) and a score (10)
  while read -r NETWORK; do
    # Note: Score > 1 is needed to trigger the alert/drop rule
    echo "$NETWORK,1,10" >> $IPREPFILE
  done< <(grep -v "^#" $TMPIPREPFILE)
fi

Note: I use a score of 10, meaning a source must have a reputation score greater than 1 to trigger the rule.

3. The Final Detection and Prevention Rules

The final rule leverages the iprep keyword to check the source IP against the newly loaded Bogon list.

Detection Rule (Testing Phase)

The detection rule is used first to verify the configuration and observe traffic without blocking. The rule is triggered if the source IP’s reputation is in the Bogons category (category ID 1) and the score is greater than 1.

# Use this first to see what it would drop.
alert ip $EXTERNAL_NET any -> $HOME_NET any (msg:"DROP FullBogons listed."; iprep:src,Bogons,>,1; sid:11; rev:1;)

Prevention Rule (Active Defense)

Once testing is complete, the rule is switched to drop for active prevention.

# Use this for active IPS defense.
drop ip $EXTERNAL_NET any -> $HOME_NET any (msg:"DROP FullBogons listed."; iprep:src,Bogons,>,1; sid:11; rev:1;)

4. Verification

Verification confirms the lists are loaded and the counts are correct. The vast number of IPv6 bogons (142054) highlights the importance of this protection layer.

root@fw2:/etc/suricata/iprep# wc -l *
674 bogons-v4.list
142054 bogons-v6.list
1 categories.txt
142729 total

# Suricata log confirming load:
[Info] - reputation: Loading reputation file: /etc/suricata/iprep/bogons-v4.list
[Info] - reputation: Loading reputation file: /etc/suricata/iprep/bogons-v6.list

Sources / See Also

  1. Team Cymru. Bogon Networks Reference. https://www.team-cymru.com/bogon-networks
  2. Team Cymru. List of Unallocated IPv4 Address Space. http://www.team-cymru.org/Services/Bogons/fullbogons-ipv4.txt
  3. Team Cymru. List of Unallocated IPv6 Address Space. http://www.team-cymru.org/Services/Bogons/fullbogons-ipv6.txt
  4. RFC 4890. Recommendations for ICMPv6 Traffic. https://datatracker.ietf.org/doc/html/rfc4890
  5. Suricata Documentation. IP Reputation Configuration. https://docs.suricata.io/en/latest/configuration/ip-reputation.html
  6. Suricata Documentation. Working with Suricata-Update (Rule Management). https://suricata-update.readthedocs.io/en/latest/update.html

Suricata IPS: Building a Transparent Network Defense Layer with AF-Packet Bridging

Suricata functions as a powerful engine for Network Intrusion Detection and Prevention (IDS/IPS). This guide demonstrates how to set up Suricata as a transparent Intrusion Prevention System (IPS) within a KVM environment by replacing the kernel bridge with the high-performance AF-Packet mechanism.

Continue reading Suricata IPS: Building a Transparent Network Defense Layer with AF-Packet Bridging

Securing Email with MTA-STS and TLSRPT

What is MTA-STS (MTA Strict Transport Security)?

MTA-STS is a mechanism that enforces TLS encryption for your email communication. Think of it as HTTP Strict Transport Security (HSTS) for email. By instructing the sending mail server that a secure connection is mandatory, you can effectively mitigate or stop Man-in-the-Middle (MITM) attacks. The official abstract from the RFC puts it best:

Continue reading Securing Email with MTA-STS and TLSRPT