feat(pr3): canonical wire-order header capture for h1/h2 + H3App for SETTINGS

- Renames caddy.listeners.decnet_h2fp → decnet_fp; adds h1 raw-byte
  header capture (plainTappingConn) and h2 continuous HPACK decode loop
  (parseH2HeadersLoop) so headers_ordered reflects actual wire order, not
  Go map iteration order.
- Adds H3App Caddy module (decnet_h3) that owns UDP/443 via quic-go,
  wraps accepted QUIC connections with h3SettingsTappingConn to intercept
  the h3 control stream and extract RFC 9114 SETTINGS in wire order.
- Wires access_log emission from FPHandler.ServeHTTP via responseCapture.
- Updates syslog_bridge.py (canonical + per-service copies) with inline
  _compute_ja4h and new fp socket record branches: http_request_headers,
  h3_settings, access_log.
- Fixes ingester proto field alias (bridge emits 'proto', ingester expected
  'protocol') and exposes _process_fingerprint_bounties test alias.
- Go tests: h1/h2/h3 golden-byte tests all green; h3_tracer_test covers
  varint parser, GREASE detection, truncated-stream safety.
- Python tests: 15/15 green across bridge JA4H hash parity, ingester
  compat (old + new event shapes), and Caddyfile h3 template assertions.
This commit is contained in:
2026-05-10 03:29:00 -04:00
parent 8d1f26c0c7
commit 5675dd8ebc
33 changed files with 7240 additions and 124 deletions

View File

@@ -637,7 +637,7 @@ async def _extract_bounty(
"payload": {
"fingerprint_type": "ja4h",
"ja4h": _ja4h,
"protocol": _fields.get("protocol", "h1"),
"protocol": _fields.get("proto") or _fields.get("protocol", "h1"),
"method": _fields.get("method"),
"path": _fields.get("path"),
},
@@ -1471,3 +1471,7 @@ def _classify_ua(ua: str) -> tuple[str, Optional[str], list[str]]:
return "browser", None, signals
return "nonstandard", None, signals
# Test-facing alias so tests can import by a stable name.
_process_fingerprint_bounties = _extract_bounty