From 279f110050a64ad68be1423e2a7dd08b5e97fd5f Mon Sep 17 00:00:00 2001 From: Kyle Isom Date: Wed, 25 Mar 2026 18:53:44 -0700 Subject: [PATCH] Add rift deployment config for fronting metacrypt containers Rift-specific config routes metacrypt.svc.mcp.metacircular.net across three listeners: L7 TLS-terminating to metacrypt-web on :443, L4 passthrough to API on :8443, and L4 passthrough to gRPC on :9443. Docker compose uses host networking for direct port binding. Includes self-signed cert generation script for initial L7 deployment. Updates example config with metrics section and Unix socket for gRPC admin. Co-Authored-By: Claude Opus 4.6 (1M context) --- deploy/docker/docker-compose-rift.yml | 24 ++++++++++ deploy/mc-proxy-rift.toml | 64 ++++++++++++++++++++++++++ deploy/mc-proxy.toml.example | 16 +++---- deploy/scripts/generate-self-signed.sh | 43 +++++++++++++++++ 4 files changed, 138 insertions(+), 9 deletions(-) create mode 100644 deploy/docker/docker-compose-rift.yml create mode 100644 deploy/mc-proxy-rift.toml create mode 100755 deploy/scripts/generate-self-signed.sh diff --git a/deploy/docker/docker-compose-rift.yml b/deploy/docker/docker-compose-rift.yml new file mode 100644 index 0000000..f1fcfec --- /dev/null +++ b/deploy/docker/docker-compose-rift.yml @@ -0,0 +1,24 @@ +# mc-proxy on rift — TLS ingress for metacrypt containers. +# +# Uses host networking so mc-proxy can bind directly to host ports +# and reach metacrypt containers on 127.0.0.1:18443/18080/19443. +# +# Usage: +# docker compose -f deploy/docker/docker-compose-rift.yml up -d +# +# Prerequisites: +# - /srv/mc-proxy/mc-proxy.toml (copy from deploy/mc-proxy-rift.toml) +# - /srv/mc-proxy/certs/ with TLS cert for L7 route +# - metacrypt containers running (127.0.0.1:18443, 18080, 19443) + +services: + mc-proxy: + build: + context: ../.. + dockerfile: Dockerfile + args: + VERSION: "${VERSION:-dev}" + network_mode: host + volumes: + - /srv/mc-proxy:/srv/mc-proxy + restart: unless-stopped diff --git a/deploy/mc-proxy-rift.toml b/deploy/mc-proxy-rift.toml new file mode 100644 index 0000000..1ffa2f4 --- /dev/null +++ b/deploy/mc-proxy-rift.toml @@ -0,0 +1,64 @@ +# mc-proxy configuration for rift. +# +# Fronts metacrypt containers: +# :443 → metacrypt-web (L7, TLS termination + re-encrypt) +# :8443 → metacrypt API (L4 passthrough) +# :9443 → metacrypt gRPC (L4 passthrough) +# +# Copy to /srv/mc-proxy/mc-proxy.toml on rift before starting. + +[database] +path = "/srv/mc-proxy/mc-proxy.db" + +# :443 — L7 TLS-terminating route to metacrypt web UI. +[[listeners]] +addr = ":443" + + [[listeners.routes]] + hostname = "metacrypt.svc.mcp.metacircular.net" + backend = "127.0.0.1:18080" + mode = "l7" + tls_cert = "/srv/mc-proxy/certs/metacrypt-svc.pem" + tls_key = "/srv/mc-proxy/certs/metacrypt-svc.key" + backend_tls = true + +# :8443 — L4 passthrough to metacrypt API (already serves TLS). +[[listeners]] +addr = ":8443" + + [[listeners.routes]] + hostname = "metacrypt.svc.mcp.metacircular.net" + backend = "127.0.0.1:18443" + +# :9443 — L4 passthrough to metacrypt gRPC (already serves TLS). +[[listeners]] +addr = ":9443" + + [[listeners.routes]] + hostname = "metacrypt.svc.mcp.metacircular.net" + backend = "127.0.0.1:19443" + +# gRPC admin API — Unix socket, secured by file permissions. +[grpc] +addr = "/srv/mc-proxy/mc-proxy.sock" + +# Firewall — no GeoIP on local network, basic rate limiting. +[firewall] +blocked_ips = [] +blocked_cidrs = [] +blocked_countries = [] +rate_limit = 100 +rate_window = "1m" + +# Prometheus metrics — loopback only, for node-local MCP scraping. +[metrics] +addr = "127.0.0.1:9090" +path = "/metrics" + +[proxy] +connect_timeout = "5s" +idle_timeout = "300s" +shutdown_timeout = "30s" + +[log] +level = "info" diff --git a/deploy/mc-proxy.toml.example b/deploy/mc-proxy.toml.example index df1f28e..acedc6b 100644 --- a/deploy/mc-proxy.toml.example +++ b/deploy/mc-proxy.toml.example @@ -34,16 +34,9 @@ addr = ":9443" backend = "127.0.0.1:28443" # gRPC admin API. Optional — omit or leave addr empty to disable. -# If enabled over TCP, tls_cert and tls_key are required. mTLS (client_ca) -# is strongly recommended for any non-loopback listen address. +# Unix socket, secured by file permissions (no TLS needed). [grpc] -addr = "127.0.0.1:9090" -tls_cert = "/srv/mc-proxy/certs/cert.pem" -tls_key = "/srv/mc-proxy/certs/key.pem" -client_ca = "/srv/mc-proxy/certs/ca.pem" # mTLS; omit to disable client auth - -# Unix socket alternative (no TLS needed, secured by file permissions): -# addr = "/srv/mc-proxy/admin.sock" +addr = "/srv/mc-proxy/mc-proxy.sock" # Firewall. Global blocklist, evaluated before routing. Default allow. [firewall] @@ -54,6 +47,11 @@ blocked_countries = ["KP", "CN", "IN", "IL"] rate_limit = 100 # max connections per source IP per window (0 = disabled) rate_window = "1m" # sliding window duration (required if rate_limit > 0) +# Prometheus metrics. Optional — omit or leave addr empty to disable. +[metrics] +addr = "127.0.0.1:9090" +path = "/metrics" + # Proxy behavior. [proxy] connect_timeout = "5s" diff --git a/deploy/scripts/generate-self-signed.sh b/deploy/scripts/generate-self-signed.sh new file mode 100755 index 0000000..2617c5e --- /dev/null +++ b/deploy/scripts/generate-self-signed.sh @@ -0,0 +1,43 @@ +#!/bin/sh +set -eu + +# Generate a self-signed TLS certificate for mc-proxy L7 routes. +# Usage: generate-self-signed.sh [output-dir] +# +# Example: +# generate-self-signed.sh metacrypt.svc.mcp.metacircular.net /srv/mc-proxy/certs +# +# Produces: +# /.pem (certificate) +# /.key (private key) + +if [ $# -lt 1 ]; then + echo "Usage: $0 [output-dir]" >&2 + exit 1 +fi + +HOSTNAME="$1" +OUTPUT_DIR="${2:-/srv/mc-proxy/certs}" +DAYS=365 + +# Sanitize hostname for filename (replace dots with hyphens, drop leading wildcard). +BASENAME=$(echo "$HOSTNAME" | sed 's/^\*\.//; s/\./-/g') +CERT="${OUTPUT_DIR}/${BASENAME}.pem" +KEY="${OUTPUT_DIR}/${BASENAME}.key" + +mkdir -p "$OUTPUT_DIR" + +openssl req -x509 -newkey ec -pkeyopt ec_paramgen_curve:prime256v1 \ + -nodes -days "$DAYS" \ + -keyout "$KEY" -out "$CERT" \ + -subj "/CN=${HOSTNAME}" \ + -addext "subjectAltName=DNS:${HOSTNAME}" + +chmod 600 "$KEY" +chmod 644 "$CERT" + +echo "Generated self-signed certificate (${DAYS} days):" +echo " cert: ${CERT}" +echo " key: ${KEY}" +echo "" +echo "Verify: openssl x509 -in ${CERT} -noout -text | grep -A1 'Subject Alternative'"