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>
This commit is contained in:
18
CLAUDE.md
18
CLAUDE.md
@@ -4,7 +4,7 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
|
||||
|
||||
## Project Overview
|
||||
|
||||
mc-proxy is a Layer 4 TLS SNI proxy and router for Metacircular Dynamics services. It reads the SNI hostname from incoming TLS ClientHello messages and proxies the raw TCP stream to the matched backend. It does not terminate TLS. A global firewall (IP, CIDR, GeoIP country blocking) is evaluated before routing. See `ARCHITECTURE.md` for full design.
|
||||
mc-proxy is a TLS proxy and router for Metacircular Dynamics services. It operates in two per-route modes: **L4 passthrough** (reads SNI, proxies raw TCP without terminating TLS) and **L7 terminating** (terminates TLS, reverse proxies HTTP/2 and HTTP/1.1 traffic including gRPC). A global firewall (IP, CIDR, GeoIP, rate limiting) is evaluated before routing. PROXY protocol support enables multi-hop deployments preserving real client IPs. See `ARCHITECTURE.md` for full design.
|
||||
|
||||
## Build Commands
|
||||
|
||||
@@ -28,7 +28,9 @@ go test ./internal/sni -run TestExtract
|
||||
|
||||
- **Module path**: `git.wntrmute.dev/kyle/mc-proxy`
|
||||
- **Go with CGO_ENABLED=0**, statically linked, Alpine containers
|
||||
- **gRPC admin API** — manages routes and firewall rules at runtime; TLS with optional mTLS; optional (disabled if `[grpc]` section omitted from config)
|
||||
- **Dual mode, per-route** — L4 (passthrough) and L7 (TLS-terminating HTTP/2 reverse proxy) coexist on the same listener
|
||||
- **PROXY protocol** — listeners accept v1/v2; routes send v2. Enables edge→origin deployments over Tailscale
|
||||
- **gRPC admin API** — manages routes and firewall rules at runtime; Unix socket only; optional (disabled if `[grpc]` section omitted from config)
|
||||
- **No auth on proxy listeners** — this is pre-auth infrastructure; services behind it handle their own MCIAS auth
|
||||
- **SQLite database** — persists listeners, routes, and firewall rules; pure-Go driver (`modernc.org/sqlite`); seeded from TOML on first run, DB is source of truth thereafter
|
||||
- **Write-through pattern** — gRPC mutations write to DB first, then update in-memory state
|
||||
@@ -41,9 +43,11 @@ go test ./internal/sni -run TestExtract
|
||||
- `internal/config/` — TOML config loading and validation
|
||||
- `internal/db/` — SQLite database: migrations, CRUD for listeners/routes/firewall rules, seeding, snapshots
|
||||
- `internal/sni/` — TLS ClientHello parser; extracts SNI hostname without consuming bytes
|
||||
- `internal/firewall/` — global blocklist evaluation (IP, CIDR, GeoIP via MaxMind GeoLite2); thread-safe mutations and GeoIP reload
|
||||
- `internal/proxy/` — bidirectional TCP relay with half-close propagation and idle timeout
|
||||
- `internal/server/` — orchestrates listeners → firewall → SNI → route → proxy pipeline; per-listener state with connection tracking
|
||||
- `internal/firewall/` — global blocklist evaluation (IP, CIDR, GeoIP via MaxMind GeoLite2); rate limiting; thread-safe mutations and GeoIP reload
|
||||
- `internal/proxy/` — L4 bidirectional TCP relay with half-close propagation and idle timeout
|
||||
- `internal/proxyproto/` — PROXY protocol v1/v2 parser and v2 writer
|
||||
- `internal/l7/` — L7 TLS termination, `prefixConn`, HTTP/2 reverse proxy with h2c backend transport
|
||||
- `internal/server/` — orchestrates listeners → PROXY protocol → firewall → SNI → route → L4/L7 dispatch; per-listener state with connection tracking
|
||||
- `internal/grpcserver/` — gRPC admin API: route/firewall CRUD, status, write-through to DB
|
||||
- `proto/mc_proxy/v1/` — protobuf definitions; `gen/mc_proxy/v1/` has generated code
|
||||
|
||||
@@ -54,8 +58,10 @@ go test ./internal/sni -run TestExtract
|
||||
|
||||
## Critical Rules
|
||||
|
||||
- mc-proxy never terminates TLS and never modifies the byte stream.
|
||||
- L4 routes never terminate TLS and never modify the byte stream.
|
||||
- L7 routes terminate TLS at the proxy and reverse proxy HTTP/2 (including gRPC) to backends.
|
||||
- Firewall rules are always evaluated before any routing decision.
|
||||
- PROXY protocol is only parsed on explicitly enabled listeners.
|
||||
- SNI matching is exact and case-insensitive.
|
||||
- Blocked connections get a TCP RST — no error messages, no TLS alerts.
|
||||
- Database writes must succeed before in-memory state is updated (write-through).
|
||||
|
||||
Reference in New Issue
Block a user