15 Commits

Author SHA1 Message Date
97e58b5a42 test: update tests and benchmarks for ensemble architecture
- Rewrite DDoS tests to use ensemble detector (remove KNN model setup)
- Update scanner tests for ensemble-based detection
- Remove legacy model construction helpers from benchmarks
- Add copyright headers to test files

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:22 +00:00
385e9d4c59 chore: add SPDX copyright headers and update license year
Add `// Copyright Sunbeam Studios 2026` and `// SPDX-License-Identifier:
Apache-2.0` headers to all source files missing them. Update LICENSE
copyright year, Dockerfile copyright header, and .dockerignore for new
project structure (lean4/, docs/, training artifacts).

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:21 +00:00
5daed3ecb0 chore: update scanner/ddos trainers, benchmarks, and tests
Expand DDoS feature vector to 14 dimensions (cookie_ratio, referer_ratio,
accept_language_ratio, suspicious_path_ratio). Add heuristic auto-labeling
to DDoS trainer. Update benchmarks and tests to match new feature vectors.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:21 +00:00
9db2b1655f test(cluster): add integration tests and proptests for cluster subsystem
7 integration tests: two-node gossip exchange, three-node mesh
propagation, tenant isolation, standalone mode, aggregate bandwidth
meter, bandwidth limiter enforcement, and default 1 Gbps cap.

8 proptests for the bandwidth limiter plus 11 existing cluster proptests
covering meter, tracker, and cluster state invariants.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:21 +00:00
65516404e1 feat(cluster): wire cluster into proxy lifecycle and request pipeline
Spawn cluster on dedicated thread in main.rs with graceful fallback to
standalone on failure. Add cluster field to SunbeamProxy, record
bandwidth in logging(), and enforce cluster-wide bandwidth cap in
request_filter with 429 JSON response.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:21 +00:00
2660ee974c fix(proxy): skip detection pipeline for bypass CIDR IPs
Trusted IPs (localhost, pod network) now skip the entire DDoS/scanner/
rate-limit pipeline via early return. Fixes buildkitd pushes to Gitea
being blocked by the scanner when using host networking.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:20 +00:00
39fe5f9f5f test: add property-based tests for new proxy features
Add proptest-based tests covering content_type_for, cache_control_for,
backend_addr, UUID v4 request IDs, rewrite rule compilation, body
rewriting, config TOML deserialization, path traversal prevention,
metrics label validation, and static file serving.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:20 +00:00
0f31c7645c feat(cache): add pingora-cache integration with per-route config
Add in-memory HTTP response cache using pingora-cache MemCache backend.
Cache runs after the detection pipeline so cache hits bypass upstream
request modifications and body rewriting. Respects Cache-Control
(no-store, private, s-maxage, max-age), skips caching for routes with
body rewrites or auth subrequest headers, and supports configurable
default TTL, stale-while-revalidate, and max file size per route.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:20 +00:00
76ad9e93e5 feat(static_files): add static file serving, SPA fallback, rewrites, body rewriting, and auth subrequests
Add static file serving with try_files chain ($uri, $uri.html,
$uri/index.html, fallback), regex-based URL rewrites compiled at
startup, response body find/replace for text/html and JS content,
auth subrequests with header capture for path routes, and custom
response headers per route. Extends RouteConfig with static_root,
fallback, rewrites, body_rewrites, and response_headers fields.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:20 +00:00
867b6b2489 feat(proxy): integrate DDoS, scanner, and rate limiter into request pipeline
Wire up all three detection layers in request_filter with pipeline
logging at each stage for unfiltered training data. Add DDoS, scanner,
and rate_limit config sections. Bot allowlist check before scanner
model on the hot path. CLI subcommands for train/replay.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:20 +00:00
b7c8243955 feat(scanner): add per-request scanner detector with linear classifier
12-feature extraction (zero-alloc hot path), 2 interaction terms,
weighted linear scoring model with hard allowlist short-circuits for
configured host+cookies and host+browser UA. Returns ScannerVerdict
with score+reason for pipeline logging.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:19 +00:00
4bccff3303 feat(rate_limit): add per-identity leaky bucket rate limiter
256-shard RwLock<FxHashMap> for concurrent access, auth key extraction
(ory_kratos_session cookie > Bearer token > client IP), CIDR bypass
for trusted networks, and background eviction of stale buckets.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:19 +00:00
007865fbe7 feat(ddos): add KNN-based DDoS detection module
14-feature vector extraction, KNN classifier using fnntw, per-IP
sliding window aggregation, and heuristic auto-labeling for training.
Includes replay subcommand for offline evaluation and integration tests.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:19 +00:00
e16299068f feat: add native dual-stack IPv4/IPv6 support
This commit implements comprehensive dual-stack support for the proxy,
allowing it to listen on both IPv4 and IPv6 addresses simultaneously.

Key changes:
- Added new dual_stack.rs module with DualStackTcpListener implementation
- Updated SSH module to use dual-stack listener
- Updated configuration documentation to reflect IPv6 support
- Added comprehensive tests for dual-stack functionality

The implementation is inspired by tokio_dual_stack but implemented
natively without external dependencies. It provides fair connection
distribution between IPv4 and IPv6 clients while maintaining full
backward compatibility with existing IPv4-only configurations.

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:19 +00:00
4ce008dc11 fix(proxy): forward X-Forwarded-Proto via insert_header; add e2e test
Root cause: upstream_request_filter was inserting x-forwarded-proto with
a raw headers.insert() call (via DerefMut) which only updates base.headers
but NOT the CaseMap. header_to_h1_wire zips CaseMap with base.headers, so
headers added without a CaseMap entry are silently dropped on the wire.

Fix: use insert_header() which keeps both maps in sync.

Also adds:
- src/lib.rs + [lib] section: exposes SunbeamProxy/RouteConfig/AcmeRoutes
  to integration tests without re-declaring modules in main.rs
- tests/e2e.rs: real end-to-end test — starts a SunbeamProxy over plain
  HTTP, routes it to a TCP echo backend, and asserts x-forwarded-proto: http
  is present in the upstream request headers
- Updated unit tests to verify header_to_h1_wire round-trip (not just that
  HeaderMap::insert works in isolation)

Signed-off-by: Sienna Meridian Satterwhite <sienna@sunbeam.pt>
2026-03-10 23:38:19 +00:00