summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMalfurious <m@lfurio.us>2024-06-14 23:21:59 -0400
committerMalfurious <m@lfurio.us>2024-06-15 17:41:53 -0400
commit7d2158a75b6ff294146444a6e1b51170d3f43010 (patch)
tree9ac8d354a77f1076dd97ab18c1eb7ddec3ddf961
parent5eb4f64c86a963c33b5958092b33924a43749e99 (diff)
downloadmailnode-7d2158a75b6ff294146444a6e1b51170d3f43010.tar.gz
mailnode-7d2158a75b6ff294146444a6e1b51170d3f43010.zip
mlmmj: Integration with postfix
Incoming mail for an mlmmj list is caught by a virtual mapping and directed via virtual transport to the mlmmj system for processing. Outgoing mail is implicitly allowed since it originates from the localhost. The postfix entrypoint script now dynamically generates these mailing list mappings on startup from data in the mlmmj spool directory, so user configuration is minimal. In addition, the script will now sync the user's mailing list parameters into the spool directory, thus automatically creating new lists and deleting old ones. The list creation logic is implemented in a new script `make_list.sh`. This is made necessary as the mlmmj built in tooling for this must be run interactively, so we duplicate the logic. This is separate from `entrypoint.sh` mainly because we need to drop privileges to the mlmmj user while creating files. Signed-off-by: Malfurious <m@lfurio.us>
-rw-r--r--Dockerfile1
-rwxr-xr-xpostfix/entrypoint.sh45
-rw-r--r--postfix/main.cf6
-rwxr-xr-xpostfix/make_list.sh13
-rw-r--r--postfix/master.cf2
5 files changed, 58 insertions, 9 deletions
diff --git a/Dockerfile b/Dockerfile
index 55e2c07..55b4e01 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -34,6 +34,7 @@ RUN apt update \
mlmmj \
postfix \
postfix-pcre \
+ sudo \
&& apt clean
# Install files
diff --git a/postfix/entrypoint.sh b/postfix/entrypoint.sh
index 46c06ab..afea241 100755
--- a/postfix/entrypoint.sh
+++ b/postfix/entrypoint.sh
@@ -1,18 +1,47 @@
#!/bin/sh
-# Generate virtual mappings from user password file
+users() {
+ sed 's/:.*$//g' /etc/userconfig/passwd
+}
+
+## Generate virtual mappings from user password file
# Incoming mail: "user@domain domain/user/" >vmailbox
-# (The trailing slash indicates the directory is a maildir.)
-sed 's/:.*$//g' </etc/userconfig/passwd \
- | awk -F '@' '{printf "%s %s/%s/\n", $0, $2, $1}' >/etc/postfix/vmailbox
+# Outgoing mail: "user@domain user@domain" >vaddress
+users | awk -F '@' '{printf "%s %s/%s/\n", $0, $2, $1}' >/etc/postfix/vmailbox
+users | awk '{printf "%s %s\n", $0, $0}' >/etc/postfix/vaddress
+
+## Synchronize mailing list configuration directories
+eul=$(ls /etc/userconfig/lists | sed '/ /d') # Ignore spaces and dotfiles
+vsl=$(ls -A /var/spool/mlmmj)
+added=$(printf '%s\n' "$vsl" "$vsl" "$eul" | sort | uniq -u)
+removed=$(printf '%s\n' "$eul" "$eul" "$vsl" | sort | uniq -u)
+
+for list in $added; do
+ sudo -u mlmmj /etc/postfix/make_list.sh "$list"
+done
+for list in $removed; do
+ listdir="/var/spool/mlmmj/$list"
+ rm -rf "$listdir"
+ printf 'Deleted list directory: %s\n' "$listdir"
+done
-# Outgoing mail: "user@domain user@domain" >vaddress
-sed 's/:.*$//g' </etc/userconfig/passwd \
- | awk '{printf "%s %s\n", $0, $0}' >/etc/postfix/vaddress
+## Generate virtual mappings from mailing list addresses
+# "address@domain list@localhost.mlmmj" >mlvirtual
+# "list@localhost.mlmmj mlmmj:list" >mltransport
+touch /etc/postfix/mlvirtual
+touch /etc/postfix/mltransport
+for list in $(ls -A /var/spool/mlmmj); do
+ address="/var/spool/mlmmj/$list/control/listaddress" # there could be multiple
+ sed "s/$/ $list@localhost.mlmmj/g" <$address >>/etc/postfix/mlvirtual
+ echo "$list@localhost.mlmmj mlmmj:$list" >>/etc/postfix/mltransport
+done
-# Generate Berkeley DB files
+## Generate Berkeley DB files
+postmap /etc/postfix/mltransport
+postmap /etc/postfix/mlvirtual
postmap /etc/postfix/vaddress
postmap /etc/postfix/vmailbox
postmap /etc/userconfig/aliases
+## Execute postfix daemons
exec /usr/sbin/postfix start-fg
diff --git a/postfix/main.cf b/postfix/main.cf
index 7ded588..7f701a8 100644
--- a/postfix/main.cf
+++ b/postfix/main.cf
@@ -53,4 +53,8 @@ virtual_uid_maps = static:2000
virtual_gid_maps = static:2000
virtual_mailbox_limit = 0
-virtual_alias_maps = hash:/etc/userconfig/aliases
+# Mlmmj mailing list parameters
+mlmmj_destination_recipient_limit = 1
+transport_maps = hash:/etc/postfix/mltransport
+
+virtual_alias_maps = hash:/etc/userconfig/aliases hash:/etc/postfix/mlvirtual
diff --git a/postfix/make_list.sh b/postfix/make_list.sh
new file mode 100755
index 0000000..45a198e
--- /dev/null
+++ b/postfix/make_list.sh
@@ -0,0 +1,13 @@
+#!/bin/sh
+
+mkdir -p "/var/spool/mlmmj/$1"
+cd "/var/spool/mlmmj/$1"
+
+mkdir -p incoming queue queue/discarded archive subconf unsubconf bounce \
+ moderation subscribers.d digesters.d requeue nomailsubs.d
+
+touch index
+ln -s "/etc/userconfig/lists/$1" control
+ln -s /etc/userconfig/listtext text
+
+printf 'Created list directory: %s\n' "$(pwd)"
diff --git a/postfix/master.cf b/postfix/master.cf
index 935dbec..3511856 100644
--- a/postfix/master.cf
+++ b/postfix/master.cf
@@ -65,6 +65,8 @@ postlog unix-dgram n - n - 1 postlogd
# agent. See the pipe(8) man page for information about ${recipient}
# and other message envelope options.
# ====================================================================
+mlmmj unix - n n - - pipe
+ flags=ORhu user=mlmmj argv=/usr/bin/mlmmj-receive -F -L /var/spool/mlmmj/${nexthop}
#
# maildrop. See the Postfix MAILDROP_README file for details.
# Also specify in main.cf: maildrop_destination_recipient_limit=1