From e517f2b81af530c2581ca425a985c63e4e9bc9ea Mon Sep 17 00:00:00 2001 From: tegwick Date: Sun, 11 Oct 2026 20:22:37 +0200 Subject: [PATCH] Add railiance deploy manifests, mas.coulomb.social statute example, probe JSONL log + bind option Co-Authored-By: Claude Opus 5.5 Assistant: claude-code Assistant-Model: opus Assistant-Process: 1370019@bnt-lap001 Assistant-Session: d462dd63-16de-4189-ae70-b9cd6566bf87 --- deploy/railiance/Dockerfile | 15 +++ deploy/railiance/entrypoint.sh | 53 +++++++++ deploy/railiance/manifests.yaml | 105 ++++++++++++++++++ .../mas.coulomb.social/.well-known/mas | 35 ++++++ experiments/postfix-probe/capture.py | 10 +- 5 files changed, 216 insertions(+), 2 deletions(-) create mode 100644 deploy/railiance/Dockerfile create mode 100644 deploy/railiance/entrypoint.sh create mode 100644 deploy/railiance/manifests.yaml create mode 100644 examples/statute/mas.coulomb.social/.well-known/mas diff --git a/deploy/railiance/Dockerfile b/deploy/railiance/Dockerfile new file mode 100644 index 0000000..79c7708 --- /dev/null +++ b/deploy/railiance/Dockerfile @@ -0,0 +1,15 @@ +# MAS live-test MX for mas.coulomb.social (MAS-WP-0003). +# Build from the repo root: docker build -f deploy/railiance/Dockerfile . +FROM debian:bookworm-slim +RUN apt-get update && DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + postfix python3 python3-jsonschema ssl-cert ca-certificates && rm -rf /var/lib/apt/lists/* +RUN useradd -r -s /usr/sbin/nologin mas +COPY mas_core /app/mas_core +COPY mas_gateway /app/mas_gateway +COPY examples /app/examples +COPY experiments/postfix-probe/capture.py /app/capture.py +COPY deploy/railiance/entrypoint.sh /entrypoint.sh +ENV PYTHONPATH=/app +EXPOSE 25 8080 +ENTRYPOINT ["/bin/sh", "/entrypoint.sh"] +CMD ["mx"] diff --git a/deploy/railiance/entrypoint.sh b/deploy/railiance/entrypoint.sh new file mode 100644 index 0000000..e5540ea --- /dev/null +++ b/deploy/railiance/entrypoint.sh @@ -0,0 +1,53 @@ +#!/bin/sh +# mx : Postfix -> pipe -> mas-gateway -> capture (JSONL evidence) -> ticket service +# statute : static /.well-known/mas only (the only thing exposed over HTTPS) +set -e +DOMAIN="${MAS_DOMAIN:-mas.coulomb.social}" +STATUTE_DIR="/app/examples/statute/$DOMAIN" + +if [ "$1" = "statute" ]; then + exec python3 /app/examples/statute/serve.py "$STATUTE_DIR" --host 0.0.0.0 --port 8080 +fi + +cat > /usr/local/bin/mas-gateway < /etc/postfix/mas_rcpt.regexp +postconf -e \ + "maillog_file=/dev/stdout" "myhostname=$DOMAIN" "mydomain=$DOMAIN" \ + "mydestination=$DOMAIN" "relay_domains=" "mynetworks=127.0.0.0/8" \ + "smtpd_relay_restrictions=permit_mynetworks,check_recipient_access regexp:/etc/postfix/mas_rcpt.regexp,permit" \ + "local_transport=mas" "local_recipient_maps=" "mas_destination_recipient_limit=1" \ + "recipient_delimiter=+" "swap_bangpath=no" "allow_percent_hack=no" \ + "disable_vrfy_command=yes" "smtpd_helo_required=yes" "smtpd_recipient_limit=20" \ + "message_size_limit=10240000" "smtpd_banner=\$myhostname ESMTP MAS live test" \ + "smtpd_tls_security_level=may" \ + "smtpd_tls_cert_file=/etc/ssl/certs/ssl-cert-snakeoil.pem" \ + "smtpd_tls_key_file=/etc/ssl/private/ssl-cert-snakeoil.key" \ + "inet_protocols=ipv4" "compatibility_level=3.6" +cat >> /etc/postfix/master.cf < 2 else None # optional JSONL evidence file +BIND = sys.argv[3] if len(sys.argv) > 3 else "0.0.0.0" EVENTS = [] @@ -20,7 +22,11 @@ class H(BaseHTTPRequestHandler): status, resp = r.status, r.read() except urllib.error.HTTPError as e: status, resp = e.code, e.read() - EVENTS.append({"event": json.loads(body), "app_status": status, "app": json.loads(resp or b"null")}) + rec = {"event": json.loads(body), "app_status": status, "app": json.loads(resp or b"null")} + EVENTS.append(rec) + if LOG: + with open(LOG, "a") as f: + f.write(json.dumps(rec) + "\n") self._send(status, resp) def do_GET(self): @@ -37,4 +43,4 @@ class H(BaseHTTPRequestHandler): pass -ThreadingHTTPServer(("0.0.0.0", 8024), H).serve_forever() +ThreadingHTTPServer((BIND, 8024), H).serve_forever()