Commit
+219 -64 +/-10 browse
1 | diff --git a/containers/multiuser-mail/Containerfile b/containers/multiuser-mail/Containerfile |
2 | index 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 |
16 | new file mode 100755 |
17 | index 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 |
29 | deleted file mode 100755 |
30 | index 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 |
44 | new file mode 100755 |
45 | index 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 |
104 | new file mode 100755 |
105 | index 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 |
117 | new file mode 100755 |
118 | index 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 |
127 | index 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 |
190 | index 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 |
200 | new file mode 100644 |
201 | index 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 |
341 | new file mode 100644 |
342 | index 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 |