Commit Graph

3 Commits

Author SHA1 Message Date
97909b7fbc Add L7 TLS-terminating HTTP/2 reverse proxy
New internal/l7 package implements TLS termination and HTTP/2 reverse
proxying for L7 routes. The proxy terminates the client TLS connection
using per-route certificates, then forwards HTTP/2 traffic to backends
over h2c (plaintext HTTP/2) or h2 (re-encrypted TLS).

PrefixConn replays the peeked ClientHello bytes into crypto/tls.Server
so the TLS handshake sees the complete ClientHello despite SNI
extraction having already read it.

Serve() is the L7 entry point: TLS handshake with route certificate,
ALPN negotiation (h2 preferred, HTTP/1.1 fallback), then HTTP reverse
proxy via httputil.ReverseProxy. Backend transport uses h2c by default
(AllowHTTP + plain TCP dial) or h2-over-TLS when backend_tls is set.

Forwarding headers (X-Forwarded-For, X-Forwarded-Proto, X-Real-IP)
are injected from the real client IP in the Rewrite function. PROXY
protocol v2 is sent to backends when send_proxy_protocol is enabled,
using the request context to carry the client address through the
HTTP/2 transport's dial function.

Server integration: handleConn dispatches to handleL7 when route.Mode
is "l7". The L7 handler converts RouteInfo to l7.RouteConfig and
delegates to l7.Serve.

L7 package tests: PrefixConn (4 tests), h2c backend round-trip,
forwarding header injection, backend unreachable (502), multiple
HTTP/2 requests over one connection.

Server integration tests: L7 route through full server pipeline with
TLS client, mixed L4+L7 routes on the same listener verifying both
paths work independently.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:43:20 -07:00
1ad9a1a43b Add PROXY protocol v1/v2 support for multi-hop deployments
New internal/proxyproto package implements PROXY protocol parsing and
writing without buffering past the header boundary (reads exact byte
counts so the connection is correctly positioned for SNI extraction).

Parser: auto-detects v1 (text) and v2 (binary) by first byte. Parses
TCP4/TCP6 for both versions plus v2 LOCAL command. Enforces max header
sizes and read deadlines.

Writer: generates v2 binary headers for IPv4 and IPv6 with PROXY
command.

Server integration:
- Receive: when listener.ProxyProtocol is true, parses PROXY header
  before firewall check. Real client IP from header is used for
  firewall evaluation and logging. Malformed headers cause RST.
- Send: when route.SendProxyProtocol is true, writes PROXY v2 header
  to backend before forwarding the ClientHello bytes.

Tests cover v1/v2 parsing, malformed rejection, timeout, round-trip
write+parse, and five server integration tests: receive with valid
header, receive with garbage, send verification, send-disabled
verification, and firewall evaluation using the real client IP.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:28:49 -07:00
ed94548dfa Add L7/PROXY protocol data model, config, and architecture docs
Extend the config, database schema, and server internals to support
per-route L4/L7 mode selection and PROXY protocol fields. This is the
foundation for L7 HTTP/2 reverse proxying and multi-hop PROXY protocol
support described in the updated ARCHITECTURE.md.

Config: Listener gains ProxyProtocol; Route gains Mode, TLSCert,
TLSKey, BackendTLS, SendProxyProtocol. L7 routes validated at load
time (cert/key pair must exist and parse). Mode defaults to "l4".

DB: Migration v2 adds columns to listeners and routes tables. CRUD
and seeding updated to persist all new fields.

Server: RouteInfo replaces bare backend string in route lookup.
handleConn dispatches on route.Mode (L7 path stubbed with error).
ListenerState and ListenerData carry ProxyProtocol flag.

All existing L4 tests pass unchanged. New tests cover migration v2,
L7 field persistence, config validation for mode/cert/key, and
proxy_protocol flag round-tripping.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-25 13:15:51 -07:00