Skip to content

Fingerprinting

Huginn Proxy passively extracts fingerprints and forwards them as request headers. Analysis and blocking decisions belong on the backend.

For a full feature overview (protocols, limitations, metrics), see Features on GitHub.

Global toggles live under [fingerprint] (static). Per-route control uses fingerprinting on each route (TLS + HTTP/2 only; TCP SYN stays global).

Derived from the TLS ClientHello (via huginn-net-tls):

HeaderRole
x-tls-ja4Sorted cipher suites and extensions, SHA-256 hashed (FoxIO JA4)
x-tls-ja4-rOriginal ClientHello order, hashed (JA4_r)
x-tls-ja4-oSorted, raw hex (JA4_o), useful for debugging
x-tls-ja4-orOriginal order, raw hex (JA4_or)

TLS fingerprints are usually once per TLS session. For debugging per-connection variation (e.g. extension order randomization), you may need to force new connections or adjust ALPN / keep-alive. That is not generally recommended for production.

Enable or disable globally with tls_enabled:

fingerprint:
tls_enabled: true

Per route: use fingerprinting on the route (see Per-route); it turns TLS and HTTP/2 fingerprint headers on or off together for that prefix.

On HTTP/2 connections only, a compact signature is emitted as x-http2-akamai using huginn-net-http.

Enable or disable globally with http_enabled:

fingerprint:
http_enabled: true

If tls_enabled or http_enabled is false, the corresponding headers are not injected. Per-route fingerprinting applies to both TLS and HTTP/2 fingerprints for that route.

When built with ebpf-tcp, tcp_enabled = true, and the eBPF agent is running, a p0f-style string is sent as x-tcp-p0f (huginn-net-tcp).

Enable or disable globally. There is no per-route TCP SYN toggle:

fingerprint:
tcp_enabled: true

Constraints

  • Linux with XDP/eBPF; not available on macOS or Windows for this path.
  • Typically one signature per TCP connection, reused across HTTP requests on that connection.

fingerprinting on a route enables or disables TLS (JA4) and HTTP/2 (Akamai) headers for requests matching that route. TCP SYN remains governed only by fingerprint.tcp_enabled (global).

Example: fingerprints on /api, but not on /static:

routes:
- prefix: "/api"
backend: "api:9000"
fingerprinting: true
- prefix: "/static"
backend: "cdn:9000"
fingerprinting: false
fingerprint:
tls_enabled: true
http_enabled: true
tcp_enabled: true
max_capture: 65536

Example: disable TLS + HTTP/2 fingerprints everywhere via config, but keep the section for documentation:

fingerprint:
tls_enabled: false
http_enabled: false
tcp_enabled: true

See Configuration overview for where [fingerprint] sits in the file; fields include max_capture (HTTP/2 capture cap).