An installation and configuration guide to mlmmj. This guide includes howtos for the tunables, and also information on how to make mlmmj play nice with different mail servers.
Installing mlmmj is trivial. Simply compile it if you're not using a binary package such as dpkg, rpm or a ports collection from a BSD or Gentoo. To compile, untar the tar-ball and do:
$ ./configure && make && make install
That is it. Now on to making a new list.
To create a new list follow steps 1-5 and optionally you can also do steps 6-10.
recipient_delimiter = +
to /etc/postfix/main.cf. In Exim it can be done by adding
local_part_suffix = +* local_part_suffix_optional
to the "userforward:" and the "localuser:" router in /etc/exim/exim.conf, and also add "local_part_suffix = +*" to the system_aliases function. Also make sure that exim will add the envelope from in the Return-Path: header.
There is a nice FAQ explaining recipient delimiter configuration here
The "delimiter" tunable configures this on a per list basis
In the case of a list called mlmmj-test below /var/spool/mlmmj it makes the
following directories:
/var/spool/mlmmj/mlmmj-test/incoming /var/spool/mlmmj/mlmmj-test/queue /var/spool/mlmmj/mlmmj-test/queue/discarded /var/spool/mlmmj/mlmmj-test/archive /var/spool/mlmmj/mlmmj-test/text /var/spool/mlmmj/mlmmj-test/subconf /var/spool/mlmmj/mlmmj-test/unsubconf /var/spool/mlmmj/mlmmj-test/bounce /var/spool/mlmmj/mlmmj-test/control /var/spool/mlmmj/mlmmj-test/moderation /var/spool/mlmmj/mlmmj-test/subscribers.d /var/spool/mlmmj/mlmmj-test/digesters.d /var/spool/mlmmj/mlmmj-test/nomailsubs.d /var/spool/mlmmj/mlmmj-test/requeue
NOTE: The mailinglist directory (/var/spool/mlmmj/mlmmj-test in our example) have to be owned by the user the mailserver writes as. On some Postfix installations Postfix is run by the user postfix, but still writes files as nobody:nogroup or nobody:nobody
mlmmj-test: "|/usr/bin/mlmmj-recieve -L /var/spool/mlmmj/mlmmj-test"
NOTE: Don't forget newaliases.
"0 */2 * * * /usr/bin/mlmmj-maintd -F -L /var/spool/mlmmj/mlmmj-test"
It should be started as root, as mlmmj-maintd will become the user owning the listdir (/var/spool/mlmmj/mlmmj-test), and log it's last maintenance run to listdir/mlmmj-maintd.lastrun.log.
If you have several lists below /var/spool/mlmmj you can use -d:
/usr/bin/mlmmj-maintd -F -d /var/spool/mlmmj
/usr/bin/mlmmj-sub -L /var/spool/mlmmj/mlmmj-test/ -a joe@domain.tld
$ cat /var/spool/mlmmj/mlmmj-test/control/customheaders
X-Mailinglist: mlmmj-test
Reply-To: mlmmj-test@domain.tld
-- To unsubscribe send a mail to coollist+unsubscribe@lists.domain.net
Just add what you want to a file named "footer" in the same dir as "customheader" (listdir/control/).
Subject: [mlmmj-test] how are we doing?
Simply do
echo "[mlmmj-test]" > control/prefix
The following files can be used for changing the behaviour of a list. The filename is supposed to be below listdir/control. In the case it's a "boolean", the contents of a file does not matter, the mere presence of it, will set the variable to "true". If it's a "normal" file, the first line will be used as value, leaving line 2 and forward ready for commentary etc. If it's possible to specify several entries (one per line), it's marked "list".
If this file exists, all headers of a post to the list is matched against the rules. The first rule to match wins. See access rules for syntax and examples.
When this file is present, a To: header including the recipients emailaddress will be added to outgoing mail. Recommended usage is to remove existing To: headers with delheaders (see above) first.
Here is specified for how long time in seconds an address can bounce before it's unsubscribed. Defaults to 432000 seconds, which is 5 days.
Is the list is open or closed. If it's closed subscription and unsubscription via mail is disabled.
This works like closedlist, except it allows unsubscription by normal means.
These headers are added to every mail coming through. This is the place you want to add Reply-To:, List-Info:, etc headers in case you want such.
In this file is specified *ONE* headertoken to match per line. If the file
consists of:
Received: Message-ID:
Then all occurences of these headers in incoming list mail will be deleted. "From " and "Return-Path:" are deleted no matter what.
This specifies what to use as recipient delimiter for the list. Default is "+".
This file specifies how many seconds will pass before the next digest is sent. Defaults to 604800 seconds, which is 7 days.
This file specifies how many mails can accumulate before digest sending is triggered. Defaults to 50 mails, meaning that if 50 mails arrive to the list before digestinterval have passed, the digest is delivered.
This file contains all addresses which mlmmj sees as listaddresses (see tocc below). The first one is the one used as the primary one, when mlmmj sends out mail.
The functionality
There's a mailing list, , for discussions of any kind with regards to mlmmj. Archive.
Feel free to join in by sending a mail to .
On to the project page
With this option the maximal allowed size of incoming mails can be specified.
How many recipients per mail delivered to the smtp server. Defaults to 100.
Here is specified in bytes how big a mail can be and still be prepared for sending in memory. It's greatly reducing the amount of write system calls to prepare it in memory before sending it, but can also lead to denial of service attacks. Default is 16k (16384 bytes).
If this file is present, the emailaddresses in the file listdir/control/moderators will act as moderators for the list.
When this file is present and subonlypost is enabled, all postings from people who are not subscribed to the list will be moderated.
This switch turns off whether mlmmj sends out notification about postings being denied when it was rejected due to an access rule (see 'access').
If this file exists, the mail won't be saved in the archive but simply deleted.
If this file exists, subscription to the digest version of the mailinglist will be denied. (Useful if you don't want to allow digests and notify users about it).
If this file exists, digest mails won't have a text part with a thread summary.
If this file exists, then retrieving old posts with +get-N is disabled.
If this is set, no reject notifications caused by violation of maxmailsize will be sent.
If this file exists, subscription to the nomail version of the mailinglist will be denied. (Useful if you don't want to allow nomail and notify users about it).
If this file exists, no mail confirmation is needed to subscribe to the list. This should in principle never ever be used, but there is times on local lists etc. where this is useful.
HANDLE WITH CARE!
This switch turns off whether mlmmj sends out notification about postings being denied due to it's a subscribers only posting list (see 'subonlypost').
If this file is present, the owner(s) will get a mail with the address of someone sub/unsubscribing to a mailinglist.
This switch turns off whether mlmmj sends out notification about postings being denied due to the listaddress not being in To: or Cc: (see 'tocc').
The emailaddresses in this file (1 per line) will get mails to listname+owner@listdomain.tld
The prefix for the Subject: line of mails to the list. This will alter the Subject: line, and add a prefix if it's not present elsewhere.
The host specified (IP address or hostname, both works) in this file will be used for relaying the mail sent to the list. Defaults to 127.0.0.1.
In this file a port other than port 25 for connecting to the relayhost can be specified.
If this file is present, subscription will be moderated by owner(s). If there are emailaddresses in this file, then these will be used instead of owner.
If this file exists, then retrieving old posts with +get-N is only possible for subscribers. The tunable 'noget' has precedence.
When this file is present, only people who are subscribed to the list, are allowed to post to it. The check is made against the "From:" header.
If this file is present, the list address does not have to be in the To: or Cc: header of the email to the list.
Enable VERP support. Anything added in this variable will be appended the MAIL FROM: line. If "postfix" is put in the file, it'll make postfix use VERP by adding XVERP=-= to the MAIL FROM: line.
If the file listdir/control/access is present, access control is enabled.
NOTE: the default action is to deny access (reject the mail), so an empty access control file will cause mlmmj to reject all posts, whereas a non-existant file will change nothing, and mlmmj will behave as usual.
Each header in the mail is tested against each rule, rule by rule. That is, all headers are first tested against the first rule, then all headers are tested against the second rule, and so on.
The first rule to match a header decides which action to take - allow, deny or moderate the post.
The syntax is quite simple:
action[ [!]regexp]
IMPORTANT: if "moderate" is used then don't forget to add people who should function as moderators in listdir/control/moderators
First a simple example. This rule set will reject any mail that is NOT plain text, or has a subject that contains "BayStar", and allow anything else:
deny !^Content-Type: text/plain deny ^Subject:.*BayStar allow
To allow only text mails, but have the moderators moderate every html mail one would use this:
allow ^Content-Type: text/plain moderate ^Content-Type: text/html deny
Now on to a more advanced example. Morten can post anything, Mads Martin can post if the subject does not contain "SCO". Everything else is denied:
allow ^From: Morten deny ^Subject:.*SCO allow ^From: Mads Martin deny
The last rule (deny) can be left out, as deny is the default action.
A third example. Deny any mails with "discount", "weightloss", or "bonus" in the subject. Allow PGP signed and plain text mails. Anything else is denied:
deny ^Subject:.*discount deny ^Subject:.*weightloss deny ^Subject:.*bonus allow ^Content-Type: multipart/signed allow ^Content-Type: text/plain
This is a step-by-step guide to run mlmmj with Exim4. The most current version
of this can be found on http://plonk.de/sw/mlmmj/README.exim4.
Notes:
MLMMJ_HOME=/var/spool/mlmmj domainlist mlmmj_domains = list.example.net
domainlist relay_to_domains = other.domain : +mlmmj_domains
delay_warning_condition = ${if match_domain{$domain}{+mlmmj_domains}{no}{yes}}
mlmmj_router:
driver = accept
domains = +mlmmj_domains
require_files = MLMMJ_HOME/${lc::$local_part}
# Use this instead, if you don't want to give Exim rx rights to mlmmj spool.
# Exim will then spawn a new process running under the UID of "mlmmj".
#require_files = mlmmj:MLMMJ_HOME/${lc::$local_part}
local_part_suffix = +*
local_part_suffix_optional
headers_remove = Delivered-To
headers_add = Delivered-To: $local_part$local_part_suffix@$domain
transport = mlmmj_transport
If you want VERP to be done by your MTA, also add this:
verp_router:
driver = dnslookup
domains = !+mlmmj_domains
# we only consider messages sent in through loopback
condition = ${if eq{$sender_host_address}{127.0.0.1}{yes}{no}}
ignore_target_hosts = <; 0.0.0.0; 127.0.0.0/8; ::1/128; fe80::/10; ff00::/8
# only the un-VERPed bounce addresses are handled
senders = \N^.+\+bounces-\d+@.+\N
transport = verp_smtp
To prevent temporary errors for not-existing lists, add !+mlmmj_domains to the
domains condition of the dnslookup router:
dnslookup: driver = dnslookup domains = !+mlmmj_domains : !+local_domains [...]
mlmmj_transport:
driver = pipe
return_path_add
user = mlmmj
group = mlmmj
home_directory = MLMMJ_HOME
current_directory = MLMMJ_HOME
command = /usr/local/bin/mlmmj-recieve -F -L MLMMJ_HOME/${lc:$local_part}
If you want VERP to be done by your MTA, also add this:
verp_smtp:
driver = smtp
# put recipient address into return_path
return_path = ${quote_local_part:${local_part:$return_path}}-\
${original_local_part}=${original_domain}@\
${domain:$return_path}
# must restrict to one recipient at a time
max_rcpt = 1
# Errors-To: may carry old return_path
headers_remove = Errors-To
headers_add = Errors-To: $return_path
$ exim -bt mlmmj-test@your.list.domain mlmmj-test@your.list.domain router = mlmmj_router, transport = mlmmj_transport
If you get different output, run it with -d to see what's going wrong.
If not, you're done!
Jakob Hirsch (jh at plonk dot de)
Using mlmmj with qmail (and vpopmail)
by Fabio Busatto
This mini-HOWTO is a step-by-step guide for using mlmmj with qmail MTA
(http://www.qmail.org/), and it has been successfully tested also with vpopmail
virtual domains (http://www.inter7.com/vpopmail/).
Prerequisites:
Conventions:
Configuration:
# cd ${LISTDIR}/control/; echo '-' > delimiter# echo -e "|${BINDIR}/mlmmj-recieve -L ${LISTDIR}" > ${DQFILE}WARNING: REMEMBER that the delimiter is -, so do not use + when composing mail
addresses for extensions!!!
WARNING: DO NOT USE 'preline' command in dot-qmail files, it will result in
mlmmj to not work properly!!!
Example:
Configuring mlmmj to handle ml@programmazione.it mailing list using qmail as MTA and vpopmail for virtual domain support:
# mlmmj-make-ml.sh -c vpopmail:vchkpw -L ml Creating Directorys below /var/spool/mlmmj. Use '-s spooldir' to change The Domain for the List? [] : programmazione.it The emailaddress of the list owner? [postmaster] : postmaster@programmazione.it The path to texts for the list? [/usr/local/share/mlmmj/text.skel] : chown -R vpopmail:vchkpw /var/spool/mlmmj/ml? [y/n]: y # cd /var/spool/mlmmj/ml/control/ # echo '-' > delimiter # chown vpopmail:vchkpw delimiter # cd /home/vpopmail/domains/programmazione.it/ # echo -e "|/usr/local/bin/mlmmj-recieve -L /var/spool/mlmmj/ml/" > .qmail-ml # cp -a .qmail-ml .qmail-ml-default # cat *-default # chown vpopmail:vchkpw .qmail-ml .qmail-ml-default # chmod 600 .qmail-ml .qmail-ml-default
The following configuration enables VERP (http://cr.yp.to/proto/verp.txt) which is useful for mailing list managers that are able to take advantage of that feature.
This configuration is currently used for using the mlmmj manager with VERP enabled + sendmail.
The hack consists in hooking VERP rewriting in a replacement ruleset for the existing EnvFromSMTP one (called VerpEnvFromSMTP). This is going to work *only* if we are splitting messages with multiple recipients in separate queue files since the macro we are using for the rewriting ($u) is not set when multiple rcpt are present.
The first step consists in forcing envelope splitting, this is done using the QUEUE_GROUP feature, here we are definining r=1 (max 1 rcpt per message) for the default queue group:
QUEUE_GROUP(`mqueue', `P=/var/spool/mqueue, F=f, I=1m, R=2, r=1')
Since we are going to split a lot it's advisable to use the FAST_SPLIT option, additionally we need to enforce return-path inclusion in the local mailer:
define(`confFAST_SPLIT', `100')dnl define(`LOCAL_SHELL_FLAGS', `eu9P')dnl
Then we define a regex map for matching the addresses that we are going to rewrite, in our example we'll rewrite addresses like
<listname+bounces-123@domain.net>
with
%lt;listname+bounces-123-user=foo.net@domain.net>
where user@foo.net is the recipient address of the message. So we need to apply
our verp ruleset *only* to those addresses. Additionally we are also adding the
Delivered-To header:
LOCAL_CONFIG Kmatch_verp regex -m -a@VERP (listname\+bounces\-[0-9]+<@domain\.net\.?>) H?l?Delivered-To: $u
Here's the ruleset, the first half of the ruleset is the existing EnvFromSMTP ruleset present in default sendmail.cf, the seconf half is the VERP stuff:
SVerpEnvFromSMTP R$+ $: $>PseudoToReal $1 sender/recipient common R$* :; <@> $@ list:; special case R$* $: $>MasqSMTP $1 qualify unqual'ed names R$+ $: $>MasqEnv $1 do masquerading R $* $: $(match_verp $1 $) match the address R $* + $* < @ $* . > $* @VERP $: $1 + $2 - $&u < @ $3 . > $4 VERP rewrite it using $u macro and add VERP string for failsafe R $* - < @ $* . > $* VERP $: $1 < @ $2 . > $3 if $u wasn't defined rewrite the address back R $* - < $+ @ $+ > < @ $* . > $* VERP $: $(dequote $1 "-" $2 "=" $3 $) < @ $4 . > $5 replace the "@" in rcpt address with "=" R $* - $+ @ $+ < @ $* . > $* VERP $: $(dequote $1 "-" $2 "=" $3 $) < @ $4 . > $5 replace the "@" in rcpt address with "="
Finally we need to rewrite the mailer definition for the used mailer (typically esmtp) specifying VerpEnvFromSMTP as the sender rewrite ruleset:
MAILER_DEFINITIONS
Mesmtp, P=[IPC], F=mDFMuXa, S=VerpEnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990,
T=DNS/RFC822/SMTP,
A=TCP $h
NOTE: for mailing list servers it's also a good idea keeping existing Delivered-To headers, sendmail needs the following patch for doing this
An installation and configuration guide to mlmmj. This guide includes howtos for the tunables, and also information on how to make mlmmj play nice with different mail servers.
Installing mlmmj is trivial. Simply compile it if you're not using a binary package such as dpkg, rpm or a ports collection from a BSD or Gentoo. To compile, untar the tar-ball and do:
$ ./configure && make && make install
That is it. Now on to making a new list.
To create a new list follow steps 1-5 and optionally you can also do steps 6-10.
recipient_delimiter = +
to /etc/postfix/main.cf. In Exim it can be done by adding
local_part_suffix = +* local_part_suffix_optional
to the "userforward:" and the "localuser:" router in /etc/exim/exim.conf, and also add "local_part_suffix = +*" to the system_aliases function. Also make sure that exim will add the envelope from in the Return-Path: header.
There is a nice FAQ explaining recipient delimiter configuration here
The "delimiter" tunable configures this on a per list basis
In the case of a list called mlmmj-test below /var/spool/mlmmj it makes the
following directories:
/var/spool/mlmmj/mlmmj-test/incoming /var/spool/mlmmj/mlmmj-test/queue /var/spool/mlmmj/mlmmj-test/queue/discarded /var/spool/mlmmj/mlmmj-test/archive /var/spool/mlmmj/mlmmj-test/text /var/spool/mlmmj/mlmmj-test/subconf /var/spool/mlmmj/mlmmj-test/unsubconf /var/spool/mlmmj/mlmmj-test/bounce /var/spool/mlmmj/mlmmj-test/control /var/spool/mlmmj/mlmmj-test/moderation /var/spool/mlmmj/mlmmj-test/subscribers.d /var/spool/mlmmj/mlmmj-test/digesters.d /var/spool/mlmmj/mlmmj-test/nomailsubs.d /var/spool/mlmmj/mlmmj-test/requeue
NOTE: The mailinglist directory (/var/spool/mlmmj/mlmmj-test in our example) have to be owned by the user the mailserver writes as. On some Postfix installations Postfix is run by the user postfix, but still writes files as nobody:nogroup or nobody:nobody
mlmmj-test: "|/usr/bin/mlmmj-recieve -L /var/spool/mlmmj/mlmmj-test"
NOTE: Don't forget newaliases.
"0 */2 * * * /usr/bin/mlmmj-maintd -F -L /var/spool/mlmmj/mlmmj-test"
It should be started as root, as mlmmj-maintd will become the user owning the listdir (/var/spool/mlmmj/mlmmj-test), and log it's last maintenance run to listdir/mlmmj-maintd.lastrun.log.
If you have several lists below /var/spool/mlmmj you can use -d:
/usr/bin/mlmmj-maintd -F -d /var/spool/mlmmj
/usr/bin/mlmmj-sub -L /var/spool/mlmmj/mlmmj-test/ -a joe@domain.tld
$ cat /var/spool/mlmmj/mlmmj-test/control/customheaders
X-Mailinglist: mlmmj-test
Reply-To: mlmmj-test@domain.tld
-- To unsubscribe send a mail to coollist+unsubscribe@lists.domain.net
Just add what you want to a file named "footer" in the same dir as "customheader" (listdir/control/).
Subject: [mlmmj-test] how are we doing?
Simply do
echo "[mlmmj-test]" > control/prefix
The following files can be used for changing the behaviour of a list. The filename is supposed to be below listdir/control. In the case it's a "boolean", the contents of a file does not matter, the mere presence of it, will set the variable to "true". If it's a "normal" file, the first line will be used as value, leaving line 2 and forward ready for commentary etc. If it's possible to specify several entries (one per line), it's marked "list".
If this file exists, all headers of a post to the list is matched against the rules. The first rule to match wins. See access rules for syntax and examples.
When this file is present, a To: header including the recipients emailaddress will be added to outgoing mail. Recommended usage is to remove existing To: headers with delheaders (see above) first.
Here is specified for how long time in seconds an address can bounce before it's unsubscribed. Defaults to 432000 seconds, which is 5 days.
Is the list is open or closed. If it's closed subscription and unsubscription via mail is disabled.
This works like closedlist, except it allows unsubscription by normal means.
These headers are added to every mail coming through. This is the place you want to add Reply-To:, List-Info:, etc headers in case you want such.
In this file is specified *ONE* headertoken to match per line. If the file
consists of:
Received: Message-ID:
Then all occurences of these headers in incoming list mail will be deleted. "From " and "Return-Path:" are deleted no matter what.
This specifies what to use as recipient delimiter for the list. Default is "+".
This file specifies how many seconds will pass before the next digest is sent. Defaults to 604800 seconds, which is 7 days.
This file specifies how many mails can accumulate before digest sending is triggered. Defaults to 50 mails, meaning that if 50 mails arrive to the list before digestinterval have passed, the digest is delivered.
This file contains all addresses which mlmmj sees as listaddresses (see tocc below). The first one is the one used as the primary one, when mlmmj sends out mail.
The functionality
There's a mailing list, , for discussions of any kind with regards to mlmmj. Archive.
Feel free to join in by sending a mail to .
On to the project page
With this option the maximal allowed size of incoming mails can be specified.
How many recipients per mail delivered to the smtp server. Defaults to 100.
Here is specified in bytes how big a mail can be and still be prepared for sending in memory. It's greatly reducing the amount of write system calls to prepare it in memory before sending it, but can also lead to denial of service attacks. Default is 16k (16384 bytes).
If this file is present, the emailaddresses in the file listdir/control/moderators will act as moderators for the list.
When this file is present and subonlypost is enabled, all postings from people who are not subscribed to the list will be moderated.
This switch turns off whether mlmmj sends out notification about postings being denied when it was rejected due to an access rule (see 'access').
If this file exists, the mail won't be saved in the archive but simply deleted.
If this file exists, subscription to the digest version of the mailinglist will be denied. (Useful if you don't want to allow digests and notify users about it).
If this file exists, digest mails won't have a text part with a thread summary.
If this file exists, then retrieving old posts with +get-N is disabled.
If this is set, no reject notifications caused by violation of maxmailsize will be sent.
If this file exists, subscription to the nomail version of the mailinglist will be denied. (Useful if you don't want to allow nomail and notify users about it).
If this file exists, no mail confirmation is needed to subscribe to the list. This should in principle never ever be used, but there is times on local lists etc. where this is useful.
HANDLE WITH CARE!
This switch turns off whether mlmmj sends out notification about postings being denied due to it's a subscribers only posting list (see 'subonlypost').
If this file is present, the owner(s) will get a mail with the address of someone sub/unsubscribing to a mailinglist.
This switch turns off whether mlmmj sends out notification about postings being denied due to the listaddress not being in To: or Cc: (see 'tocc').
The emailaddresses in this file (1 per line) will get mails to listname+owner@listdomain.tld
The prefix for the Subject: line of mails to the list. This will alter the Subject: line, and add a prefix if it's not present elsewhere.
The host specified (IP address or hostname, both works) in this file will be used for relaying the mail sent to the list. Defaults to 127.0.0.1.
In this file a port other than port 25 for connecting to the relayhost can be specified.
If this file is present, subscription will be moderated by owner(s). If there are emailaddresses in this file, then these will be used instead of owner.
If this file exists, then retrieving old posts with +get-N is only possible for subscribers. The tunable 'noget' has precedence.
When this file is present, only people who are subscribed to the list, are allowed to post to it. The check is made against the "From:" header.
If this file is present, the list address does not have to be in the To: or Cc: header of the email to the list.
Enable VERP support. Anything added in this variable will be appended the MAIL FROM: line. If "postfix" is put in the file, it'll make postfix use VERP by adding XVERP=-= to the MAIL FROM: line.
If the file listdir/control/access is present, access control is enabled.
NOTE: the default action is to deny access (reject the mail), so an empty access control file will cause mlmmj to reject all posts, whereas a non-existant file will change nothing, and mlmmj will behave as usual.
Each header in the mail is tested against each rule, rule by rule. That is, all headers are first tested against the first rule, then all headers are tested against the second rule, and so on.
The first rule to match a header decides which action to take - allow, deny or moderate the post.
The syntax is quite simple:
action[ [!]regexp]
IMPORTANT: if "moderate" is used then don't forget to add people who should function as moderators in listdir/control/moderators
First a simple example. This rule set will reject any mail that is NOT plain text, or has a subject that contains "BayStar", and allow anything else:
deny !^Content-Type: text/plain deny ^Subject:.*BayStar allow
To allow only text mails, but have the moderators moderate every html mail one would use this:
allow ^Content-Type: text/plain moderate ^Content-Type: text/html deny
Now on to a more advanced example. Morten can post anything, Mads Martin can post if the subject does not contain "SCO". Everything else is denied:
allow ^From: Morten deny ^Subject:.*SCO allow ^From: Mads Martin deny
The last rule (deny) can be left out, as deny is the default action.
A third example. Deny any mails with "discount", "weightloss", or "bonus" in the subject. Allow PGP signed and plain text mails. Anything else is denied:
deny ^Subject:.*discount deny ^Subject:.*weightloss deny ^Subject:.*bonus allow ^Content-Type: multipart/signed allow ^Content-Type: text/plain
This is a step-by-step guide to run mlmmj with Exim4. The most current version
of this can be found on http://plonk.de/sw/mlmmj/README.exim4.
Notes:
MLMMJ_HOME=/var/spool/mlmmj domainlist mlmmj_domains = list.example.net
domainlist relay_to_domains = other.domain : +mlmmj_domains
delay_warning_condition = ${if match_domain{$domain}{+mlmmj_domains}{no}{yes}}
mlmmj_router:
driver = accept
domains = +mlmmj_domains
require_files = MLMMJ_HOME/${lc::$local_part}
# Use this instead, if you don't want to give Exim rx rights to mlmmj spool.
# Exim will then spawn a new process running under the UID of "mlmmj".
#require_files = mlmmj:MLMMJ_HOME/${lc::$local_part}
local_part_suffix = +*
local_part_suffix_optional
headers_remove = Delivered-To
headers_add = Delivered-To: $local_part$local_part_suffix@$domain
transport = mlmmj_transport
If you want VERP to be done by your MTA, also add this:
verp_router:
driver = dnslookup
domains = !+mlmmj_domains
# we only consider messages sent in through loopback
condition = ${if eq{$sender_host_address}{127.0.0.1}{yes}{no}}
ignore_target_hosts = <; 0.0.0.0; 127.0.0.0/8; ::1/128; fe80::/10; ff00::/8
# only the un-VERPed bounce addresses are handled
senders = \N^.+\+bounces-\d+@.+\N
transport = verp_smtp
To prevent temporary errors for not-existing lists, add !+mlmmj_domains to the
domains condition of the dnslookup router:
dnslookup: driver = dnslookup domains = !+mlmmj_domains : !+local_domains [...]
mlmmj_transport:
driver = pipe
return_path_add
user = mlmmj
group = mlmmj
home_directory = MLMMJ_HOME
current_directory = MLMMJ_HOME
command = /usr/local/bin/mlmmj-recieve -F -L MLMMJ_HOME/${lc:$local_part}
If you want VERP to be done by your MTA, also add this:
verp_smtp:
driver = smtp
# put recipient address into return_path
return_path = ${quote_local_part:${local_part:$return_path}}-\
${original_local_part}=${original_domain}@\
${domain:$return_path}
# must restrict to one recipient at a time
max_rcpt = 1
# Errors-To: may carry old return_path
headers_remove = Errors-To
headers_add = Errors-To: $return_path
$ exim -bt mlmmj-test@your.list.domain mlmmj-test@your.list.domain router = mlmmj_router, transport = mlmmj_transport
If you get different output, run it with -d to see what's going wrong.
If not, you're done!
Jakob Hirsch (jh at plonk dot de)
Using mlmmj with qmail (and vpopmail)
by Fabio Busatto
This mini-HOWTO is a step-by-step guide for using mlmmj with qmail MTA
(http://www.qmail.org/), and it has been successfully tested also with vpopmail
virtual domains (http://www.inter7.com/vpopmail/).
Prerequisites:
Conventions:
Configuration:
# cd ${LISTDIR}/control/; echo '-' > delimiter# echo -e "|${BINDIR}/mlmmj-recieve -L ${LISTDIR}" > ${DQFILE}WARNING: REMEMBER that the delimiter is -, so do not use + when composing mail
addresses for extensions!!!
WARNING: DO NOT USE 'preline' command in dot-qmail files, it will result in
mlmmj to not work properly!!!
Example:
Configuring mlmmj to handle ml@programmazione.it mailing list using qmail as MTA and vpopmail for virtual domain support:
# mlmmj-make-ml.sh -c vpopmail:vchkpw -L ml Creating Directorys below /var/spool/mlmmj. Use '-s spooldir' to change The Domain for the List? [] : programmazione.it The emailaddress of the list owner? [postmaster] : postmaster@programmazione.it The path to texts for the list? [/usr/local/share/mlmmj/text.skel] : chown -R vpopmail:vchkpw /var/spool/mlmmj/ml? [y/n]: y # cd /var/spool/mlmmj/ml/control/ # echo '-' > delimiter # chown vpopmail:vchkpw delimiter # cd /home/vpopmail/domains/programmazione.it/ # echo -e "|/usr/local/bin/mlmmj-recieve -L /var/spool/mlmmj/ml/" > .qmail-ml # cp -a .qmail-ml .qmail-ml-default # cat *-default # chown vpopmail:vchkpw .qmail-ml .qmail-ml-default # chmod 600 .qmail-ml .qmail-ml-default
The following configuration enables VERP (http://cr.yp.to/proto/verp.txt) which is useful for mailing list managers that are able to take advantage of that feature.
This configuration is currently used for using the mlmmj manager with VERP enabled + sendmail.
The hack consists in hooking VERP rewriting in a replacement ruleset for the existing EnvFromSMTP one (called VerpEnvFromSMTP). This is going to work *only* if we are splitting messages with multiple recipients in separate queue files since the macro we are using for the rewriting ($u) is not set when multiple rcpt are present.
The first step consists in forcing envelope splitting, this is done using the QUEUE_GROUP feature, here we are definining r=1 (max 1 rcpt per message) for the default queue group:
QUEUE_GROUP(`mqueue', `P=/var/spool/mqueue, F=f, I=1m, R=2, r=1')
Since we are going to split a lot it's advisable to use the FAST_SPLIT option, additionally we need to enforce return-path inclusion in the local mailer:
define(`confFAST_SPLIT', `100')dnl define(`LOCAL_SHELL_FLAGS', `eu9P')dnl
Then we define a regex map for matching the addresses that we are going to rewrite, in our example we'll rewrite addresses like
<listname+bounces-123@domain.net>
with
%lt;listname+bounces-123-user=foo.net@domain.net>
where user@foo.net is the recipient address of the message. So we need to apply
our verp ruleset *only* to those addresses. Additionally we are also adding the
Delivered-To header:
LOCAL_CONFIG Kmatch_verp regex -m -a@VERP (listname\+bounces\-[0-9]+<@domain\.net\.?>) H?l?Delivered-To: $u
Here's the ruleset, the first half of the ruleset is the existing EnvFromSMTP ruleset present in default sendmail.cf, the seconf half is the VERP stuff:
SVerpEnvFromSMTP R$+ $: $>PseudoToReal $1 sender/recipient common R$* :; <@> $@ list:; special case R$* $: $>MasqSMTP $1 qualify unqual'ed names R$+ $: $>MasqEnv $1 do masquerading R $* $: $(match_verp $1 $) match the address R $* + $* < @ $* . > $* @VERP $: $1 + $2 - $&u < @ $3 . > $4 VERP rewrite it using $u macro and add VERP string for failsafe R $* - < @ $* . > $* VERP $: $1 < @ $2 . > $3 if $u wasn't defined rewrite the address back R $* - < $+ @ $+ > < @ $* . > $* VERP $: $(dequote $1 "-" $2 "=" $3 $) < @ $4 . > $5 replace the "@" in rcpt address with "=" R $* - $+ @ $+ < @ $* . > $* VERP $: $(dequote $1 "-" $2 "=" $3 $) < @ $4 . > $5 replace the "@" in rcpt address with "="
Finally we need to rewrite the mailer definition for the used mailer (typically esmtp) specifying VerpEnvFromSMTP as the sender rewrite ruleset:
MAILER_DEFINITIONS
Mesmtp, P=[IPC], F=mDFMuXa, S=VerpEnvFromSMTP/HdrFromSMTP, R=EnvToSMTP, E=\r\n, L=990,
T=DNS/RFC822/SMTP,
A=TCP $h
NOTE: for mailing list servers it's also a good idea keeping existing Delivered-To headers, sendmail needs the following patch for doing this