#!/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,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} --require-dmarc-pass" else postconf -e "default_transport=error:5.7.1 outbound mail disabled" fi # Sender authentication (spec 14 item 10). The MTA does SPF/DKIM/DMARC, since # they need DNS; the gateway only reads Authentication-Results carrying our # authserv-id. Postfix header_checks drop incoming A-R headers claiming that # id; header_checks do not see milter-added headers, so only the milters' # own results survive and a sender cannot forge a pass. (OpenDKIM's # RemoveARFrom did not remove them in testing.) Annotate only: never reject, # and accept mail if a milter is down. Loopback (the ticket service's # replies) is skipped. Both milters run in the foreground: daemonized, # OpenDKIM died on its first connection in this container. mkdir -p /run/opendkim /run/opendmarc chown opendkim:opendkim /run/opendkim && chown opendmarc:opendmarc /run/opendmarc printf '127.0.0.1\n' > /etc/opendkim-peers cat > /etc/opendkim.conf < /etc/opendmarc.conf < /etc/postfix/ar_strip.regexp postconf -e "header_checks=regexp:/etc/postfix/ar_strip.regexp" "smtpd_milters=inet:127.0.0.1:8891,inet:127.0.0.1:8893" "non_smtpd_milters=" \ "milter_default_action=accept" "milter_protocol=6" cat >> /etc/postfix/master.cf <