Skip to content

biandratti/huginn-proxy

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

91 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Huginn Proxy Logo

Huginn Proxy

License Release CI Security Audit Pure Rust codecov GitHub Release Docker

High-performance reverse proxy with passive fingerprinting capabilities powered by Huginn Net.

Overview

Huginn Proxy is a reverse proxy built on Tokio, Hyper, and Rustls. It routes incoming connections to backend services while passively extracting TLS (JA4), HTTP/2 (Akamai), and TCP SYN (p0f-style) fingerprints and injecting them as headers. TCP SYN fingerprinting is implemented via an XDP eBPF program using Aya. Fingerprinting libraries are provided by Huginn Net.

Inspired by production-grade proxies like Pingora, Sozu, and rust-rpxy.

Quick Start

See examples/ for the full setup guide, including:

  • Building from source (standard and with eBPF/TCP SYN fingerprinting)
  • Generating TLS certificates
  • Running with Docker Compose
  • Configuration examples (rate limiting, routing, …)

Features

  • HTTP/1.x & HTTP/2 - Full support for both protocol versions
  • Load Balancing - Round-robin load balancing across multiple backends
  • Connection Pooling - Automatic connection reuse to backends for reduced latency (bypasses pooling per-route for fingerprinting)
  • Path-based Routing - Route matching with prefix support, path stripping, and path rewriting
  • Rate Limiting - Token bucket algorithm with multiple strategies (IP, Header, Route, Combined), global and per-route limits
  • Header Manipulation - Add or remove request/response headers globally or per-route for security and customization
  • Security Headers - HSTS, CSP, X-Frame-Options, and custom headers
  • IP Filtering (ACL) - Allowlist/denylist with CIDR notation support
  • TLS Termination - Server-side TLS with ALPN, certificate hot reload (single certificate per configuration)
  • TLS Session Resumption - Support for TLS 1.2 session IDs and TLS 1.3 session tickets
  • mTLS (Mutual TLS) - Client certificate authentication for secure service-to-service communication
  • Granular Timeouts - TLS handshake and connection handling timeouts for resource protection
  • Host Header Preservation - Configurable forwarding of original Host header for virtual hosting
  • Passive Fingerprinting - Automatic TLS (JA4), HTTP/2 (Akamai), and TCP SYN (p0f-style via eBPF) fingerprint extraction
  • X-Forwarded- Headers* - Automatic injection of proxy forwarding headers
  • Comprehensive Telemetry - Prometheus metrics covering requests, throughput, rate limiting, TLS, backends, and security features
  • High Performance - Built on Tokio and Hyper
  • Easy Deployment - Single binary, Docker-ready

See FEATURES.md for detailed descriptions and limitations of each feature.

For deployment instructions, see DEPLOYMENT.md.

Fingerprinting

Fingerprints are automatically extracted and injected as headers:

  • TLS (JA4): x-huginn-net-ja4: sorted cipher suites and extensions, SHA-256 hashed. Standard FoxIO JA4. using huginn-net-tls
  • TLS (JA4_r): x-huginn-net-ja4_r: original ClientHello order, SHA-256 hashed (FoxIO JA4_r)
  • TLS (JA4_o): x-huginn-net-ja4_o: sorted, raw hex values without hashing (FoxIO JA4_o, useful for debugging)
  • TLS (JA4_or): x-huginn-net-ja4_or: original order, raw hex values without hashing (FoxIO JA4_or)
  • HTTP/2 (Akamai): x-huginn-net-akamai: Extracted from HTTP/2 connections only using huginn-net-http
  • TCP SYN (p0f-style): x-huginn-net-tcp - Raw TCP SYN signature extracted via eBPF/XDP using huginn-net-tcp. Requires tcp_enabled = true and the ebpf-tcp feature. Present on all requests of a connection (the fingerprint is captured once at TCP accept time and reused). IPv4 only, not captured for direct IPv6 connections (transparent when a load balancer forwards internally over IPv4). See EBPF-SETUP.md for setup, kernel requirements, and deployment options.
  • The proxy automatically injects standard X-Forwarded-* headers to inform backends about the original client request:

Examples:

x-huginn-net-ja4:    t13d3112h2_e8f1e7e78f70_b26ce05bbdd6,
x-huginn-net-ja4_r:  t13d3112h2_002f,0033,0035,0039,003c,003d,0067,006b,009c,009d,009e,009f,00ff,1301,1302,1303,c009,c00a,c013,c014,c023,c024,c027,c028,c02b,c02c,c02f,c030,cca8,cca9,ccaa_000a,000b,000d,0015,0016,0017,002b,002d,0031,0033_0403,0503,0603,0807,0808,0809,080a,080b,0804,0805,0806,0401,0501,0601,0303,0301,0302,0402,0502,0602,
x-huginn-net-ja4_o:  t13d3112h2_d7c3e2abb617_cad92ccb4254,
x-huginn-net-ja4_or: t13d3112h2_1302,1303,1301,c02c,c030,009f,cca9,cca8,ccaa,c02b,c02f,009e,c024,c028,006b,c023,c027,0067,c00a,c014,0039,c009,c013,0033,009d,009c,003d,003c,0035,002f,00ff_0000,000b,000a,0010,0016,0017,0031,000d,002b,002d,0033,0015_0403,0503,0603,0807,0808,0809,080a,080b,0804,0805,0806,0401,0501,0601,0303,0301,0302,0402,0502,0602,
x-huginn-net-ja4_r:  t13d3112h2_d7c3e2abb617_cad92ccb4254,
x-huginn-net-akamai: 3:100;4:10485760;2:0|1048510465|0|m,s,a,p,
x-huginn-net-tcp:    4:64+0:0:1460:mss*44,10:mss,sok,ts,nop,ws:df,id+:0,
x-forwarded-for:     172.18.0.1,
x-forwarded-port:    50908,
x-forwarded-proto:   https,
x-forwarded-host:    localhost

These headers always override any client-provided values to prevent spoofing.

Advanced Configuration Options

Per-Route Settings

  • fingerprinting (bool, default: true) - Enable/disable TLS (JA4) and HTTP/2 (Akamai) fingerprint extraction and header injection
  • TLS fingerprints are captured once per TLS session and reused for all HTTP requests on that connection this is by design. To observe per-connection variation (e.g. Chrome's extension-order randomization), set alpn = ["http/1.1"] and keep_alive.enabled = false for debugging only; this is a protocol downgrade not suitable for production.

Health Check Endpoints

When telemetry.metrics_port is configured, Huginn Proxy exposes health check endpoints on the observability server ( separate from the main proxy port):

  • /health - General health check (200 OK if process is running)
  • /ready - Readiness check (200 OK if backends configured, 503 otherwise) - for Kubernetes readiness probes
  • /live - Liveness check (200 OK if process is running) - for Kubernetes liveness probes
  • /metrics - Prometheus metrics endpoint

All endpoints return JSON responses (except /metrics which returns Prometheus format) and follow Kubernetes health check conventions.

Performance

  • Fingerprinting Overhead: ~2.2% (minimal impact)
  • Concurrent Connections: Handles thousands of concurrent connections
  • Latency: Sub-millisecond overhead for fingerprint extraction

See benches/README.md for detailed benchmark results from development environment.

Roadmap

See ROADMAP.md for a detailed list of planned features and upcoming phases.

Containers and Binaries Matrix

Docker images

Images published to ghcr.io/biandratti/huginn-proxy (linux/amd64, linux/arm64).

Image tag Base image User eBPF Capabilities
:latest / :v0.0.1-beta.1 debian:bookworm-slim 10001 ✅ reads pinned maps CAP_BPF
:latest-plain / :v0.0.1-beta.1-plain debian:bookworm-slim 10001 none
:latest-ebpf-agent / :v0.0.1-beta.1-ebpf-agent debian:bookworm-slim root ✅ loads XDP, pins maps CAP_BPF + CAP_NET_ADMIN + CAP_PERFMON

See DEPLOYMENT.md for Docker and Kubernetes setup, and EBPF-SETUP.md for eBPF runtime requirements.

Release binaries
Artifact Suffix OS Arch libc eBPF
huginn-proxy x86_64-unknown-linux-musl Linux amd64 musl (static)
huginn-proxy aarch64-unknown-linux-musl Linux arm64 musl (static)
huginn-proxy x86_64-unknown-linux-gnu-ebpf Linux amd64 glibc ✅ (reader)
huginn-proxy aarch64-unknown-linux-gnu-ebpf Linux arm64 glibc ✅ (reader)
huginn-proxy x86_64-apple-darwin macOS amd64 -
huginn-proxy aarch64-apple-darwin macOS arm64 -
huginn-ebpf-agent x86_64-unknown-linux-gnu-ebpf-agent Linux amd64 glibc ✅ (loader)
huginn-ebpf-agent aarch64-unknown-linux-gnu-ebpf-agent Linux arm64 glibc ✅ (loader)
  • musl (static): zero runtime dependencies, runs on any Linux kernel and distro.
  • glibc (eBPF): extracted from the Docker image, requires glibc and Linux kernel ≥ 5.11.

Architecture

For module structure and design decisions, see ARCHITECTURE.md.

Fingerprint Header eBPF agent required
TLS (JA4) x-huginn-net-ja4 No
HTTP/2 (Akamai) x-huginn-net-akamai No
TCP SYN (p0f) x-huginn-net-tcp Yes — Linux only, kernel ≥ 5.11
TCP SYN Fingerprinting — Deployment Architecture
┌─────────────────────────────────────────────────────────┐
│  Node                                                   │
│                                                         │
│  ┌─────────────────────────┐                            │
│  │  huginn-ebpf-agent      │  CAP_BPF + CAP_NET_ADMIN   │
│  │                         │  + CAP_PERFMON             │
│  │  XDP program (kernel)   │  + seccomp:unconfined      │
│  │  ┌─────────────────┐    │  + apparmor:unconfined     │
│  │  │ tcp_syn_map     │    │  (no open ports)           │
│  │  │ syn_counter     │    │                            │
│  │  └────────┬────────┘    │                            │
│  │           │ pin_maps()  │                            │
│  └───────────┼─────────────┘                            │
│              │ /sys/fs/bpf/huginn/                      │
│  ┌───────────┼─────────────┐                            │
│  │  huginn-proxy (×N)      │  CAP_BPF only              │
│  │           │             │  seccomp: default          │
│  │  ┌────────┴────────┐    │  USER 10001                │
│  │  │ from_pinned()   │    │                            │
│  │  │ map lookup      │    │                            │
│  │  └─────────────────┘    │                            │
│  │                         │                            │
│  │  HTTP/TLS → backends    │                            │
│  │  x-huginn-net-tcp ──►   │                            │
│  └─────────────────────────┘                            │
└─────────────────────────────────────────────────────────┘

The agent loads the XDP program once per node and pins BPF maps under /sys/fs/bpf/huginn/. Multiple proxy replicas read the shared maps in read-only mode.

License

Dual-licensed under MIT or Apache 2.0.

Attribution

Huginn Proxy uses the Huginn Net fingerprinting libraries:

Contributing

Contributions are welcome! Please see our contributing guidelines for details.

About

High-performance reverse proxy that forwards the client TLS (JA4), HTTP/2 (Akamai) and TCP SYN (p0f via eBPF/XDP) signatures as headers to backend via HTTP for bot detection and traffic analysis

Topics

Resources

License

Apache-2.0, MIT licenses found

Licenses found

Apache-2.0
LICENSE-APACHE
MIT
LICENSE-MIT

Stars

Watchers

Forks

Packages

 
 
 

Contributors