JA4+ Fingerprinting
Synapse implements the complete JA4+ fingerprinting suite for advanced threat detection and behavioral analysis. Fingerprints identify clients, servers, and connections by their protocol behavior — not just IP addresses.
Fingerprint Suite
| Fingerprint | Layer | Source | Available In |
|---|---|---|---|
| JA4 | TLS | ClientHello | Proxy |
| JA4S | TLS | ServerHello | Proxy |
| JA4H | HTTP | Request Headers | Proxy |
| JA4L | Network | Client-to-Server Latency | Both |
| JA4LS | Network | Server-to-Client Latency | Both |
| JA4T | TCP | SYN Packet Options | Both |
| JA4TS | TCP | SYN-ACK Response | Proxy |
| JA4TScan | TCP | Active TCP Scan | Both |
| JA4X | TLS | X.509 Certificate | Proxy |
| JA4SSH | SSH | SSH Traffic Patterns | Both |
| JA4D | DHCP | DHCPv4 Fingerprinting | Both |
| JA4D6 | DHCP | DHCPv6 Fingerprinting | Both |
JA4 — TLS Client Fingerprint
Fingerprints the TLS ClientHello message to uniquely identify client applications.
Format: {proto}{version}{sni}{cipher_count}{ext_count}{alpn}_{cipher_hash}_{ext_hash}
Example: t13d1516h2_8daaf6152771_b186095e22b6
| Segment | Meaning |
|---|---|
t | TCP (or q for QUIC) |
13 | TLS 1.3 |
d | SNI present (d = domain, i = IP) |
15 | 15 cipher suites |
16 | 16 extensions |
h2 | ALPN protocol (HTTP/2) |
_8daaf6152771 | SHA256 truncated hash of sorted cipher suites |
_b186095e22b6 | SHA256 truncated hash of sorted extensions |
Detects: Bot traffic, TLS library tampering, client application identification, impersonation attempts.
JA4S — TLS Server Fingerprint
Fingerprints the TLS ServerHello response to identify server infrastructure.
Format: {proto}{version}{ext_count}{alpn}_{cipher}_{extensions_hash}
Example: t1302h2_1301_a56c5b993250
| Segment | Meaning |
|---|---|
t13 | TLS 1.3 over TCP |
02 | 2 extensions |
h2 | ALPN HTTP/2 |
1301 | Cipher: TLS_AES_128_GCM_SHA256 |
_a56c5b993250 | Extension hash |
Detects: Backend infrastructure mapping, load balancer identification, server configuration changes, CDN fingerprinting.
JA4H — HTTP Header Fingerprint
Fingerprints HTTP request headers to identify clients at the application layer.
Format: {method}{version}{cookie}{referer}{count}{lang}_{headers_hash}_{cookie_names_hash}_{cookie_values_hash}
Example: ge11cr15enus_a1b2c3d4e5f6_123456789abc_def012345678
| Segment | Meaning |
|---|---|
ge | First 2 chars of HTTP method (GET) |
11 | HTTP/1.1 |
c | Cookie header present |
r | Referer header present |
15 | 15 headers (excluding Cookie/Referer) |
enus | Accept-Language (en-US) |
| Three hashes | Headers, cookie names, cookie values |
Detects: Browser fingerprinting, User-Agent spoofing, header manipulation, automation tools, scrapers.
JA4T — TCP Client Fingerprint
Fingerprints the TCP SYN packet to identify the client's OS and network stack.
Format: {window_size}_{tcp_options}_{mss}_{window_scale}
Example: 65535_2-4-8-1-3_1460_7
| Segment | Meaning |
|---|---|
65535 | TCP window size |
2-4-8-1-3 | TCP option kinds (MSS, SACK, Timestamps, NOP, Window Scale) |
1460 | Maximum Segment Size |
7 | Window scale factor |
Common patterns:
| Pattern | OS |
|---|---|
| TTL=64, Window=65535 | Linux |
| TTL=128, Window=65535 | Windows |
| TTL=64, Window=65535 | macOS |
These are rules of thumb about the IP and TCP headers, not about a JA4T value: a JA4T carries no TTL, and the window size alone does not separate the three rows above. To tell these stacks apart from a fingerprint, compare the TCP option order and the MSS - see OS Fingerprinting.
Detects: Operating system fingerprinting, network stack behavior, NAT/proxy presence, device type identification.
JA4TS — TCP Server Fingerprint
Fingerprints the TCP SYN-ACK response from the server side.
Format: Same structure as JA4T but captured from the server's SYN-ACK packet.
Detects: Server OS identification, load balancer detection, backend infrastructure mapping.
JA4L — Client-to-Server Latency
Measures client-to-server latency from packet timing for light distance estimation.
Format: {rtt_microseconds}_{ttl}
Example: 12500_64 (12.5ms RTT, TTL 64)
Calculation: (ACK - SYNACK) / 2
Detects: Network distance estimation, geographic location approximation, proxy/VPN detection, CDN usage patterns.
JA4LS — Server-to-Client Latency
Measures server-to-client latency from packet timing.
Format: {rtt_microseconds}_{ttl}
Calculation: (SYNACK - SYN) / 2
Detects: Server distance measurement, hosting provider identification, latency anomaly detection.
JA4X — X.509 Certificate Fingerprint
Fingerprints X.509 certificates by their structural properties.
Format: {issuer_hash}_{subject_hash}_{extensions_hash}
Example: aae71e8db6d7_b186095e22b6_c1a4f9e7d8b3
Three 12-char SHA256 truncated hashes of:
- Issuer — RDN OIDs of the certificate issuer
- Subject — RDN OIDs of the certificate subject
- Extensions — Certificate extension OIDs
Detects: Certificate authority patterns, certificate structure anomalies, organization identification, PKI mapping.
JA4TScan — Active TCP Fingerprint Scanner
Active TCP fingerprint scanning tool that sends crafted packets to identify remote systems.
Detects: Remote OS identification, network service discovery, infrastructure mapping.
JA4SSH — SSH Traffic Fingerprint
Fingerprints SSH sessions by analyzing traffic patterns without decrypting the session.
Detects: SSH client identification, automated SSH tools, lateral movement detection, tunneling activity.
JA4D — DHCPv4 Fingerprint
Fingerprints DHCP clients by analyzing DHCPv4 Discover and Request messages.
Detects: Device type identification (IoT, workstation, mobile), rogue device detection, network inventory, unauthorized device discovery.
JA4D6 — DHCPv6 Fingerprint
Fingerprints DHCP clients by analyzing DHCPv6 Solicit and Request messages.
Detects: IPv6 device identification, dual-stack device correlation, rogue device detection on IPv6 networks.
Access Log Integration
A proxy records every fingerprint it collected for a request under one fingerprints
object, with the client address under network:
{
"event_type": "http_access_log",
"timestamp": "2025-10-29T12:34:56.789Z",
"http": { "method": "GET", "path": "/api/data" },
"network": { "src_ip": "192.168.1.100", "src_port": 54321 },
"fingerprints": {
"ja4": "t13d1516h2_8daaf6152771_b186095e22b6",
"ja4h": "ge11cr15enus_a1b2c3d4e5f6_123456789abc_def012345678",
"ja4t": "65535_2-4-8-1-3_1460_7",
"ja4s": "t1302h2_1301_a56c5b993250",
"ja4x": "aae71e8db6d7_b186095e22b6_c1a4f9e7d8b3",
"ja4l": "12500_64"
}
}
There is no client_ip, no tcp object and no tls.ja4: every JA4 value is a field of
fingerprints. The access log is a proxy file and needs
logging.file_logging_enabled: true; an agent reports its fingerprints through
eventbridge.log instead, where the same values sit at the top level of each line. See
Viewing Fingerprints.
Configuration
The fingerprint and BPF-statistics streams share one switch, and it is on by default:
# /etc/synapse/config.yaml
logging:
eventbridge_log:
enabled: true # the default
# file: /var/log/synapse/eventbridge.log
fingerprint_log is an accepted alias for eventbridge_log, and one line per event covers
every fingerprint type and the BPF statistics together. With file unset the path is
{log_directory}/eventbridge.log — not fingerprints.log, which is the stream's old name
and names no file anything writes. LOGGING_EVENTBRIDGE_LOG_ENABLED is the environment
equivalent of the key.
logging.tcp_fingerprint, logging.bpf_stats and the other four per-type sections are
absent from the 0.8.8 schema, and this page used to tell you to set two of them.
Setting any of them has no effect: the keys land in the Unused config options in <path>
warning at startup and nothing else happens. TCP_FINGERPRINT_ENABLED,
TCP_FINGERPRINT_LOG_INTERVAL, BPF_STATS_ENABLED and BPF_STATS_LOG_INTERVAL have no
reader anywhere in the code either.
Analyzing Fingerprints
Extract Unique Fingerprints
Every JA4 value is a field of fingerprints, and the client address is
network.src_ip:
AL=/var/log/synapse/access.log
# -R with `fromjson?` skips any line that is not JSON instead of aborting the run:
# two appenders write this path, and only one of them guarantees JSON.
# Unique JA4 (TLS client) fingerprints
jq -R -r 'fromjson? | select(.fingerprints.ja4) | .fingerprints.ja4' "$AL" |
sort | uniq -c | sort -rn
# Unique JA4T (TCP) fingerprints
jq -R -r 'fromjson? | select(.fingerprints.ja4t) | .fingerprints.ja4t' "$AL" |
sort | uniq -c | sort -rn
# Unique JA4H (HTTP) fingerprints
jq -R -r 'fromjson? | select(.fingerprints.ja4h) | .fingerprints.ja4h' "$AL" |
sort | uniq -c | sort -rn
# Correlate address with all fingerprints
jq -R -r 'fromjson? | [.network.src_ip, .fingerprints.ja4 // "-", .fingerprints.ja4t // "-",
.fingerprints.ja4h // "-"] | @tsv' "$AL"
On a proxy without logging.file_logging_enabled there is no access.log, but the
record is not lost: it goes to the console instead, printed raw as one JSON object per
line with no prefix, interleaved with non-JSON tracing lines. Pipe it through
jq -R 'fromjson? | select(.http)' so those lines are skipped rather than fatal. On an
agent there is no access log at all - read eventbridge.log, where each observation
carries the same fingerprint values at the top level of its own line, without the
request correlation.
Bot Detection
Combine multiple fingerprints to identify automated traffic:
# Group by JA4 fingerprint, find addresses sharing the same fingerprint
jq -R 'fromjson? | select(.fingerprints.ja4)
| {ip: .network.src_ip, ja4: .fingerprints.ja4, ja4h: .fingerprints.ja4h}' \
/var/log/synapse/access.log |
jq -s 'group_by(.ja4) | map({ja4: .[0].ja4, count: length, ips: map(.ip) | unique})'
Find Rare Fingerprints
# Rare fingerprints often indicate attack tools or unusual clients
jq -R -r 'fromjson? | select(.fingerprints.ja4) | .fingerprints.ja4' \
/var/log/synapse/access.log |
sort | uniq -c | sort -n | head -20
Why JA4+ Matters
Traditional IP-based blocking is easily bypassed. JA4+ fingerprints provide:
- Persistent identification — Fingerprints remain consistent across IP changes
- Evasion resistance — Harder to spoof than User-Agent headers or IP addresses
- Granular detection — Distinguish between different client types sharing the same IP
- Zero-day detection — Identify previously unknown attack tools by their protocol behavior
- Cross-layer correlation — Combine TLS, TCP, HTTP, and latency signals for high-confidence identification
References
License
- JA4 (TLS Client) — BSD 3-Clause License
- JA4S, JA4H, JA4L, JA4LS, JA4T, JA4TS, JA4TScan, JA4X, JA4SSH, JA4D, JA4D6 — FoxIO License 1.1
See JA4 License for details.