Layer 4 TLS SNI proxy with global firewall (IP/CIDR/GeoIP blocking), per-listener route tables, bidirectional TCP relay with half-close propagation, and a gRPC admin API (routes, firewall, status) with TLS/mTLS support. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2.4 KiB
2.4 KiB
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 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.
Build Commands
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
Run a single test:
go test ./internal/sni -run TestExtract
Architecture
- Module path:
git.wntrmute.dev/kyle/mc-proxy - Go with CGO_ENABLED=0, statically linked, Alpine containers
- No API surface yet — config-driven via TOML; gRPC admin API planned for future MCP integration
- No auth — this is pre-auth infrastructure; services behind it handle their own MCIAS auth
- No database — routes and firewall rules are in the TOML config; SQLite planned for dynamic route management
- Config: TOML via
go-toml/v2, runtime data in/srv/mc-proxy/ - Testing: stdlib
testingonly,t.TempDir()for isolation - Linting: golangci-lint v2 with
.golangci.yaml
Package Structure
internal/config/— TOML config loading and validationinternal/sni/— TLS ClientHello parser; extracts SNI hostname without consuming bytesinternal/firewall/— global blocklist evaluation (IP, CIDR, GeoIP via MaxMind GeoLite2); thread-safe GeoIP reloadinternal/proxy/— bidirectional TCP relay with half-close propagation and idle timeoutinternal/server/— orchestrates listeners → firewall → SNI → route → proxy pipeline; graceful shutdown
Signals
SIGINT/SIGTERM— graceful shutdown (drain in-flight connections up toshutdown_timeout)SIGHUP— reload GeoIP database without restart
Critical Rules
- mc-proxy never terminates TLS and never modifies the byte stream.
- Firewall rules are always evaluated before any routing decision.
- SNI matching is exact and case-insensitive.
- Blocked connections get a TCP RST — no error messages, no TLS alerts.