Hi,
I am running Suricata 8.0 in a container using jasonish/suricata:8.0
. I want to play around with ja4+ hashed, especially ja4 (for clients) and ja4s for servers. However, I only found instructions on the Suricata documentation about ja4 (client).
My first requirement would be to generate the JA4 hashes then I could add a matching rule to capture them.
Step #1: enable ja4
So, I enabled ja4 in the logging section for eve.log
in suricata.yaml.
- tls:
enabled: yes
extended: yes # enable this for extended logging information
ja4: yes # enable JA4 fingerprinting for TLS 1.3
ja4s: yes # enable JA4S fingerprinting for TLS 1.3 server
Actually, I don’t know if ja4s
exists, but it does not complain, so I just tried to enforce it.
Step #2: enable stream processing with memcaps
I headed to my stream
section in suricata.yml and provided these settings:
stream:
memcap: 256 MiB
#memcap-policy: ignore
checksum-validation: no
#midstream: false
#midstream-policy: ignore
inline: auto # auto will use inline mode in IPS mode, yes or no set it statically
reassembly:
urgent:
policy: oob
oob-limit-policy: drop
memcap: 512 MiB
#memcap-policy: ignore
depth: 1 MiB # reassemble 1 MiB into a stream
toserver-chunk-size: 2560
toclient-chunk-size: 2560
randomize-chunk-size: yes
I disabled checksum validation as per my understanding, Suricata will reject those packets with wrong checksum, and since checksumming is usually offloaded to the NIC, they are never good in the stream.
Step #3: Interface setting
I run Suricata with af-packet
and before i initiate its container, I run another docker stack with a simple linux container to create a dedicated br-XXXXX interface. Then, I can set Suricata to tap on that br-XXXXX interface via the CLI. Accordingly, I set af-packet
settings like this:
- interface: default
threads: auto
cluster-id: 99
cluster-type: cluster_flow
defrag: yes
tpacket-v3: yes
buffer-size: 128535
disable-promisc: no
checksum-checks: kernel
use-mmap: yes
Then, without adding any rule, I made a curl
request from my client container to google.com and checked the eve.json
.
And I found the ja4 (client) hash generated properly, however, for the reverse direction (from google back to me), there is no log generated at all.
"timestamp": "2025-08-07T11:12:02.308270+0800",
"flow_id": 657866726477229,
"in_iface": "br-c975b4118201",
"event_type": "tls",
"src_ip": "172.23.1.2",
"src_port": 56294,
"dest_ip": "74.125.200.99",
"dest_port": 443,
"proto": "TCP",
"ip_v": 4,
"pkt_src": "wire/pcap",
"tls": {
"sni": "www.google.com",
"version": "TLS 1.3",
"ja4": "t13d3112h2_e8f1e7e78f70_b26ce05bbdd6",
"client_alpns": [
"h2",
"http/1.1"
]
}
I guess this is not just about the ja4s itself, but the reverse direction too. For DNS for instance, I have both directions logged, as it is UDP and no stream should be followed by Suricata. But since I set that up, hopefully properly, I don’t understand why am I not seeing anything from the Google’s servers in my log.
Even if just cat eve.json|jq .|grep src_ip
, I only see my container IP and the DNS resolver’s IP
# cat eve.json |jq . |grep src_ip
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
"src_ip": "9.9.9.9",
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
"src_ip": "9.9.9.9",
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
"src_ip": "172.23.1.2",
What am I missing here?