Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 252470@bnt-lap001 Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241
83 lines
4.4 KiB
Bash
83 lines
4.4 KiB
Bash
#!/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 <<SH
|
|
#!/bin/sh
|
|
exec env PYTHONPATH=/app python3 -m mas_gateway.main "\$@"
|
|
SH
|
|
chmod +x /usr/local/bin/mas-gateway
|
|
|
|
# Not an open relay: no relay_domains, mynetworks is loopback only, so the
|
|
# only accepted recipients are @$DOMAIN, all delivered to the mas pipe.
|
|
# Stock reject_unauth_destination refuses any local-part containing '!' or '%'
|
|
# (treated as sender-specified routing), which kills every P2 address, and an
|
|
# access-map result is ignored for such routed addresses unless
|
|
# allow_untrusted_routing=yes (safe here: relay_domains is empty). So relay control is an
|
|
# explicit regexp whose match runs the `permit` restriction (not OK) for
|
|
# anything ending in @$DOMAIN; everything else falls through to `reject`
|
|
# (Postfix refuses to start smtpd without a reject-class entry in the list).
|
|
# With swap_bangpath/percent_hack off and local_transport=mas, those
|
|
# addresses can only reach the mas pipe.
|
|
DOMAIN_RE=$(printf '%s' "$DOMAIN" | sed 's/\./\\./g')
|
|
printf '/@%s$/ permit\n' "$DOMAIN_RE" > /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,reject" \
|
|
"local_transport=mas" "local_recipient_maps=" "mas_destination_recipient_limit=1" \
|
|
"recipient_delimiter=+" "swap_bangpath=no" "allow_percent_hack=no" \
|
|
"allow_untrusted_routing=yes" \
|
|
"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"
|
|
# start-fg does not populate the chroot (no resolv.conf), so DNS fails inside
|
|
# it: client rDNS shows "unknown" and a relayhost would not resolve. The
|
|
# container already isolates Postfix, so run the daemons unchrooted.
|
|
postconf -F '*/*/chroot = n'
|
|
|
|
# Outbound replies (reply test). Port 25 out is blocked on railiance01, so
|
|
# replies go through an authenticated submission relay, and only when its
|
|
# credentials are mounted. Only loopback (the ticket service) may relay.
|
|
# Without a relay all non-local mail fails fast instead of queueing.
|
|
SMTP_ARG=""
|
|
if [ -n "$MAS_RELAY" ] && [ -s /etc/mas-relay/username ]; then
|
|
printf '%s %s:%s\n' "$MAS_RELAY" "$(cat /etc/mas-relay/username)" \
|
|
"$(cat /etc/mas-relay/password)" > /etc/postfix/sasl_passwd
|
|
chmod 600 /etc/postfix/sasl_passwd && postmap /etc/postfix/sasl_passwd
|
|
postconf -e "relayhost=$MAS_RELAY" "smtp_sasl_auth_enable=yes" \
|
|
"smtp_sasl_password_maps=hash:/etc/postfix/sasl_passwd" \
|
|
"smtp_sasl_security_options=noanonymous" "smtp_tls_security_level=secure" \
|
|
"smtp_tls_CApath=/etc/ssl/certs"
|
|
# Postfix's own bounces (null sender) never use the relay, so the ticket
|
|
# service cap below really bounds everything sent through TEM.
|
|
postconf -e "sender_dependent_default_transport_maps=inline:{<>=discard:}" \
|
|
"empty_address_default_transport_maps_lookup_key=<>"
|
|
SMTP_ARG="--smtp 127.0.0.1:25 --max-sent ${MAS_MAX_SENT:-300}"
|
|
else
|
|
postconf -e "default_transport=error:5.7.1 outbound mail disabled"
|
|
fi
|
|
cat >> /etc/postfix/master.cf <<CF
|
|
mas unix - n n - - pipe
|
|
flags=Rq user=mas argv=/usr/local/bin/mas-gateway
|
|
--statute $STATUTE_DIR/.well-known/mas
|
|
pipe --app-url http://127.0.0.1:8024/mas-events --recipient \${recipient}
|
|
CF
|
|
|
|
mkdir -p /var/lib/mas && chown mas /var/lib/mas
|
|
# Replies are only recorded in the outbox unless a relay is configured above.
|
|
su -s /bin/sh mas -c "python3 /app/examples/ticket_service/ticket_service.py \
|
|
--db /var/lib/mas/tickets.sqlite3 --listen 127.0.0.1:8025 $SMTP_ARG" &
|
|
su -s /bin/sh mas -c "python3 /app/capture.py http://127.0.0.1:8025/mas-events \
|
|
/var/lib/mas/events.jsonl 127.0.0.1" &
|
|
exec postfix start-fg
|