Commit
Author: Kevin Schoon [me@kevinschoon.com]
Hash: 29bd4ae25d1db0db89c9ca4d052667cee8a81267
Timestamp: Tue, 23 Jul 2024 11:33:29 +0000 (6 months ago)

+219 -64 +/-10 browse
.
1diff --git a/containers/multiuser-mail/Containerfile b/containers/multiuser-mail/Containerfile
2index bf92233..a8725a8 100644
3--- a/containers/multiuser-mail/Containerfile
4+++ b/containers/multiuser-mail/Containerfile
5 @@ -19,6 +19,9 @@ USER root
6
7 RUN apk add --no-cache mutt postfix
8
9+ # un-privilaged user to run various milter software
10+ RUN adduser -D -s /bin/sh -H milter
11+
12 COPY --from=build --chown=0:0 /build/dkimdo /usr/bin/
13 COPY --from=build --chown=0:0 /build/dkim-milter /usr/bin/
14 COPY --from=build --chown=0:0 /build/spf-milter /usr/bin/
15 diff --git a/containers/multiuser-mail/init/dkim-milter.sh b/containers/multiuser-mail/init/dkim-milter.sh
16new file mode 100755
17index 0000000..e034704
18--- /dev/null
19+++ b/containers/multiuser-mail/init/dkim-milter.sh
20 @@ -0,0 +1,7 @@
21+ #!/bin/sh
22+ set -e
23+
24+ TEMPLATE_PATH="/etc/templates/dkim-milter.conf"
25+ CONFIG_PATH="/etc/dkim-milter.conf"
26+
27+ envsubst < "$TEMPLATE_PATH" > "$CONFIG_PATH"
28 diff --git a/containers/multiuser-mail/init/mail.sh b/containers/multiuser-mail/init/mail.sh
29deleted file mode 100755
30index e95fd4c..0000000
31--- a/containers/multiuser-mail/init/mail.sh
32+++ /dev/null
33 @@ -1,9 +0,0 @@
34- #!/bin/sh
35- set -e
36-
37- SPF_MILTER_CONFIG_PATH="/etc/spf-milter.conf"
38-
39- echo 'socket = unix:/tmp/spf-milter.sock' > $SPF_MILTER_CONFIG_PATH
40- echo 'log_destination = stderr' >> $SPF_MILTER_CONFIG_PATH
41- # Also verify HELO before MAIL FROM:
42- echo 'verify_helo = yes' >> $SPF_MILTER_CONFIG_PATH
43 diff --git a/containers/multiuser-mail/init/postfix.sh b/containers/multiuser-mail/init/postfix.sh
44new file mode 100755
45index 0000000..e64f38d
46--- /dev/null
47+++ b/containers/multiuser-mail/init/postfix.sh
48 @@ -0,0 +1,54 @@
49+ #!/bin/sh
50+
51+ AYLLU_MAIL="/usr/bin/ayllu-mail"
52+ AYLLU_CONFIG="${AYLLU_CONFIG-/etc/ayllu/config.toml}"
53+ AYLLU_DB_PATH="${AYLLU_DB_PATH-/home/ayllu/.local/share/ayllu/mail.db}"
54+
55+ # FIXME: Mailpot's master-cf generation seems to be broken but it may also be
56+ # due to my own ignorance so manually specifying it for now.
57+
58+ AYLLU_SMTP_TLS_SECURITY_LEVEL="${AYLLU_SMTP_TLS_SECURITY_LEVEL:-none}"
59+
60+ [ -n "${AYLLU_ROOT_MAIL_USER}" ] && {
61+ echo "# AYLLU: DO NOT EDIT" > /etc/postfix/aliases
62+ AYLLU_ROOT_MAIL_USER="$(echo "$AYLLU_ROOT_MAIL_USER" | tr '[:upper:]' '[:lower:]')"
63+ AYLLU_ROOT_MAIL_USER="$AYLLU_ROOT_MAIL_USER" envsubst < /etc/templates/postfix/aliases >> /etc/postfix/aliases
64+ newaliases
65+ }
66+
67+ # hide sender's IP address / User Agent
68+ # See https://wiki.archlinux.org/title/Postfix#Hide_the_sender's_IP_and_user_agent_in_the_Received_header
69+ cp /etc/templates/postfix/smtp_header_checks /etc/postfix/
70+ postconf -e smtp_header_checks="regexp:/etc/postfix/smtp_header_checks"
71+ postconf -e smtpd_helo_required=yes
72+
73+ # attachments are entirely disallowed
74+ cp /etc/templates/postfix/mime_header_checks /etc/postfix/
75+ postconf -e mime_header_checks="regexp:/etc/postfix/mime_header_checks"
76+
77+ postconf -e smtp_tls_security_level="$AYLLU_SMTP_TLS_SECURITY_LEVEL"
78+ postconf -e maillog_file="/dev/stdout"
79+
80+ AYLLU_MAIL_HOSTNAME="${AYLLU_MAIL_HOSTNAME:-localhost}"
81+ postconf -e myhostname="${AYLLU_MAIL_HOSTNAME}"
82+
83+ # disallow relay from anywhere but localhost
84+ postconf -e inet_interfaces="loopback-only"
85+ postconf -e mynetworks="127.0.0.0/8"
86+ postconf -e local_transport="local"
87+ postconf -e transport_maps="lmdb:/etc/postfix/transport"
88+
89+ # SPF
90+ postconf -e smtpd_milters="unix:/run/spf-milter.sock"
91+ postconf -e policyd-spf_time_limit="3600"
92+
93+ postconf -e smtpd_recipient_restrictions="permit_mynetworks,reject_unauth_destination,check_policy_service unix:private/policyd-spf"
94+
95+ # setup master.cf
96+ AYLLU_CONFIG="$AYLLU_CONFIG" AYLLU_DB_PATH="$AYLLU_DB_PATH" envsubst \
97+ < /etc/templates/postfix/master.cf > /etc/postfix/master.cf
98+
99+ "$AYLLU_MAIL" --config "$AYLLU_CONFIG" --database "$AYLLU_DB_PATH" \
100+ postfix maps > /etc/postfix/transport
101+
102+ postmap /etc/postfix/transport
103 diff --git a/containers/multiuser-mail/init/spf-milter.sh b/containers/multiuser-mail/init/spf-milter.sh
104new file mode 100755
105index 0000000..119a2c1
106--- /dev/null
107+++ b/containers/multiuser-mail/init/spf-milter.sh
108 @@ -0,0 +1,7 @@
109+ #!/bin/sh
110+ set -e
111+
112+ TEMPLATE_PATH="/etc/templates/spf-milter.conf"
113+ CONFIG_PATH="/etc/spf-milter.conf"
114+
115+ envsubst < "$TEMPLATE_PATH" > "$CONFIG_PATH"
116 diff --git a/containers/multiuser-mail/service/dkim-milter/run b/containers/multiuser-mail/service/dkim-milter/run
117new file mode 100755
118index 0000000..9bceb94
119--- /dev/null
120+++ b/containers/multiuser-mail/service/dkim-milter/run
121 @@ -0,0 +1,4 @@
122+ #!/bin/sh
123+ set -e
124+
125+ exec su milter -c '/usr/bin/dkim-milter'
126 diff --git a/containers/multiuser-mail/service/postfix/run b/containers/multiuser-mail/service/postfix/run
127index ce739d2..1ef4f87 100755
128--- a/containers/multiuser-mail/service/postfix/run
129+++ b/containers/multiuser-mail/service/postfix/run
130 @@ -1,57 +1,4 @@
131 #!/bin/sh
132 set -e
133
134- AYLLU_MAIL="/usr/bin/ayllu-mail"
135- AYLLU_CONFIG="${AYLLU_CONFIG-/etc/ayllu/config.toml}"
136- AYLLU_DB_PATH="${AYLLU_DB_PATH-/home/ayllu/.local/share/ayllu/mail.db}"
137-
138- # FIXME: Mailpot's master-cf generation seems to be broken but it may also be
139- # due to my own ignorance so manually specifying it for now.
140-
141- AYLLU_SMTP_TLS_SECURITY_LEVEL="${AYLLU_SMTP_TLS_SECURITY_LEVEL:-none}"
142-
143- [ -n "${AYLLU_ROOT_MAIL_USER}" ] && {
144- echo "# AYLLU: DO NOT EDIT" > /etc/postfix/aliases
145- AYLLU_ROOT_MAIL_USER="$(echo "$AYLLU_ROOT_MAIL_USER" | tr '[:upper:]' '[:lower:]')"
146- AYLLU_ROOT_MAIL_USER="$AYLLU_ROOT_MAIL_USER" envsubst < /etc/templates/postfix/aliases >> /etc/postfix/aliases
147- newaliases
148- }
149-
150- # hide sender's IP address / User Agent
151- # See https://wiki.archlinux.org/title/Postfix#Hide_the_sender's_IP_and_user_agent_in_the_Received_header
152- cp /etc/templates/postfix/smtp_header_checks /etc/postfix/
153- postconf -e smtp_header_checks="regexp:/etc/postfix/smtp_header_checks"
154- postconf -e smtpd_helo_required=yes
155-
156- # attachments are entirely disallowed
157- cp /etc/templates/postfix/mime_header_checks /etc/postfix/
158- postconf -e mime_header_checks="regexp:/etc/postfix/mime_header_checks"
159-
160- postconf -e smtp_tls_security_level="$AYLLU_SMTP_TLS_SECURITY_LEVEL"
161- postconf -e maillog_file="/dev/stdout"
162-
163- AYLLU_MAIL_HOSTNAME="${AYLLU_MAIL_HOSTNAME:-localhost}"
164- postconf -e myhostname="${AYLLU_MAIL_HOSTNAME}"
165-
166- # disallow relay from anywhere but localhost
167- postconf -e inet_interfaces="loopback-only"
168- postconf -e mynetworks="127.0.0.0/8"
169- postconf -e local_transport="local"
170- postconf -e transport_maps="lmdb:/etc/postfix/transport"
171-
172- # SPF
173- postconf -e smtpd_milters="unix:/tmp/spf-milter.sock"
174- postconf -e policyd-spf_time_limit="3600"
175-
176- postconf -e smtpd_recipient_restrictions="permit_mynetworks,reject_unauth_destination,check_policy_service unix:private/policyd-spf"
177-
178- # setup master.cf
179- AYLLU_CONFIG="$AYLLU_CONFIG" AYLLU_DB_PATH="$AYLLU_DB_PATH" envsubst \
180- < /etc/templates/postfix/master.cf > /etc/postfix/master.cf
181-
182- "$AYLLU_MAIL" --config "$AYLLU_CONFIG" --database "$AYLLU_DB_PATH" \
183- postfix maps > /etc/postfix/transport
184-
185- postmap /etc/postfix/transport
186-
187- exec postfix -c /etc/postfix start-fg
188+ exec postfix -c '/etc/postfix start-fg'
189 diff --git a/containers/multiuser-mail/service/spf-milter/run b/containers/multiuser-mail/service/spf-milter/run
190index d07941c..ad35f0c 100755
191--- a/containers/multiuser-mail/service/spf-milter/run
192+++ b/containers/multiuser-mail/service/spf-milter/run
193 @@ -1,4 +1,4 @@
194 #!/bin/sh
195 set -e
196
197- exec su ayllu -c '/usr/bin/spf-milter'
198+ exec su milter -c '/usr/bin/spf-milter'
199 diff --git a/containers/multiuser-mail/templates/dkim-milter.conf b/containers/multiuser-mail/templates/dkim-milter.conf
200new file mode 100644
201index 0000000..6461337
202--- /dev/null
203+++ b/containers/multiuser-mail/templates/dkim-milter.conf
204 @@ -0,0 +1,135 @@
205+ # DKIM Milter sample configuration file
206+ # See the manual page dkim-milter.conf(5) for reference documentation.
207+
208+ #
209+ # General
210+ #
211+
212+ # Start the milter listening on port 3000:
213+ # socket = inet:localhost:3000
214+ socket = unix:/run/dkim-milter.sock
215+
216+ # Whether to only "sign", only "verify", or make this decision "auto"matically:
217+ mode = auto
218+ #mode = sign
219+
220+ # Read signing keys and signing senders from the following files:
221+ # signing_senders = <sample-conf/signing-senders
222+ # signing_keys = <sample-conf/signing-keys
223+ #signing_keys = file:sample-conf/signing-keys
224+ #signing_keys = sqlite://mail-config.db
225+ #signing_keys = sqlite://mail-config.db#dkim_signing_keys
226+
227+ # Read connection-specific configuration overrides from this file:
228+ # connection_overrides = <sample-conf/connection-overrides
229+ #
230+ # # Read recipient-specific configuration overrides from this file:
231+ # recipient_overrides = <sample-conf/recipient-overrides
232+
233+ # Treat message transactions from these networks as eligible for signing:
234+ # trusted_networks = loopback
235+ # #trusted_networks = 12.3.4.56/28, 2001:1600:2:3::4cde
236+ #
237+ # # Whether to treat messages from authenticated senders as eligible for signing:
238+ # trust_authenticated_senders = yes
239+ #
240+ # # Use this authserv-id in generated Authentication-Results headers:
241+ # authserv_id = mail.example.com
242+ #
243+ # # Whether to delete forged Authentication-Results headers
244+ # # ("forged" means *incoming* authserv-id equals *our* authserv-id).
245+ # # Important: If you use an earlier milter that adds such headers and takes care
246+ # # of deletion itself (eg, SPF Milter), you must disable this setting, else those
247+ # # legitimate headers will be deleted by DKIM Milter.
248+ # delete_incoming_authentication_results = yes
249+ #
250+ # # Whether to only accept signing senders (in Sender or From header) that match
251+ # # the envelope sender (in MAIL FROM) for signing.
252+ # require_envelope_sender_match = no
253+
254+ # Log destination (syslog, stderr) and log level (error, warn, info, debug).
255+ log_destination = syslog
256+ log_level = info
257+
258+ # Maximum time to allow when querying for DKIM public key records.
259+ lookup_timeout = 10s
260+
261+ # Whether to operate without applying changes to messages or rejecting messages.
262+ dry_run = no
263+
264+ #
265+ # Signing
266+ #
267+
268+ # When signing, include the following headers in the signature. Value "default"
269+ # selects the default set of headers plus additional colon-separated headers
270+ # after a semicolon. Value "all" selects all headers present.
271+ sign_headers = default
272+ #sign_headers = default; Message-ID
273+ #sign_headers = all
274+ #sign_headers = From:To:Cc:Date:Subject
275+
276+ # Value "default" in parameter sign_headers refers to this set of headers:
277+ default_signed_headers = From:Reply-To:Subject:Date:To:Cc:Resent-Date:Resent-From:Resent-To:Resent-Cc:In-Reply-To:References:List-Id:List-Help:List-Unsubscribe:List-Subscribe:List-Post:List-Owner:List-Archive
278+
279+ # When value "all" is used in parameter sign_headers, exclude these headers:
280+ default_unsigned_headers = Return-Path:Received:Comments:Keywords
281+
282+ # When signing, oversign these headers, that is include them in h= once more
283+ # than actually present. Value "signed" oversigns all headers included in the
284+ # h= tag, value "signed-extended" additionally oversigns all headers in the
285+ # default set even if not present in the message.
286+ oversign_headers =
287+ #oversign_headers = From:To
288+ #oversign_headers = signed
289+ #oversign_headers = signed-extended
290+
291+ # When signing, canonicalize using the following algorithm:
292+ canonicalization = relaxed/simple
293+
294+ # When signing, set the valid duration in the x= tag to this value:
295+ expiration = 5d
296+ #expiration = never
297+
298+ # Whether to record the length of the signed body in the l= tag:
299+ limit_body_length = no
300+
301+ # Whether to record the original headers in the z= tag:
302+ copy_headers = no
303+
304+ # Whether to include tag r=y in signatures (RFC 6651, DKIM Failure Reporting):
305+ request_reports = no
306+
307+ #
308+ # Verification
309+ #
310+
311+ # Whether to accept expired signatures.
312+ allow_expired = no
313+
314+ # Whether to accept signatures with a timestamp in the future.
315+ allow_timestamp_in_future = no
316+
317+ # Whether to accept signatures using the SHA-1 hash algorithm.
318+ # (This setting is only effective if DKIM Milter was compiled with feature
319+ # "pre-rfc8301".)
320+ allow_sha1 = no
321+
322+ # Minimum acceptable RSA public key size.
323+ min_rsa_key_bits = 1024
324+
325+ # When verifying, require these headers to be signed.
326+ required_signed_headers = From*
327+ #required_signed_headers = From:To:Subject
328+
329+ # When verifying, whether to accept messages whose body is only partially
330+ # included in a signature through an l= tag limit.
331+ forbid_unsigned_content = no
332+
333+ # The set of signature verification results to reject with an SMTP error reply:
334+ # "missing": reject messages without DKIM signature
335+ # "no-pass": reject messages without a passing DKIM signature
336+ # "author-mismatch": reject messages that don’t have a passing DKIM signature
337+ # where d= matches the From header domain
338+ reject_failures =
339+ #reject_failures = missing, no-pass, author-mismatch
340 diff --git a/containers/multiuser-mail/templates/spf-milter.conf b/containers/multiuser-mail/templates/spf-milter.conf
341new file mode 100644
342index 0000000..19a6cde
343--- /dev/null
344+++ b/containers/multiuser-mail/templates/spf-milter.conf
345 @@ -0,0 +1,7 @@
346+ # spf-milter.conf
347+
348+ socket = unix:/run/spf-milter.sock
349+ log_destination = stderr
350+
351+ # Also verify HELO before MAIL FROM:
352+ verify_helo = yes