Files
mc-proxy/CLAUDE.md
Kyle Isom 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

68 lines
3.8 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Project Overview
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
```bash
make all # vet → lint → test → build
make mc-proxy # build the binary with version injection
make build # compile all packages
make test # run all tests
make vet # go vet
make lint # golangci-lint
make proto # regenerate gRPC code from proto definitions
make devserver # build and run locally with srv/mc-proxy.toml
```
Run a single test:
```bash
go test ./internal/sni -run TestExtract
```
## Architecture
- **Module path**: `git.wntrmute.dev/kyle/mc-proxy`
- **Go with CGO_ENABLED=0**, statically linked, Alpine containers
- **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
- **Config**: TOML via `go-toml/v2`, runtime data in `/srv/mc-proxy/`
- **Testing**: stdlib `testing` only, `t.TempDir()` for isolation
- **Linting**: golangci-lint v2 with `.golangci.yaml`
## Package Structure
- `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); 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
## Signals
- `SIGINT`/`SIGTERM` — graceful shutdown (drain in-flight connections up to `shutdown_timeout`)
- `SIGHUP` — reload GeoIP database without restart
## Critical Rules
- 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).