Integrate mlmmj mailing list manager in iRedMail (LDAP backends)

Attention

Check out the lightweight on-premises email archiving software developed by iRedMail team: Spider Email Archiver.

Summary

In iRedMail-0.9.8, we integrate mlmmj (http://mlmmj.org) - a simple and slim mailing list manager. It uses very few resources, and requires no daemons, easy to install, configure and manage. if offers a great set of features, including:

With mlmmj integration, you can create as many mailing lists as you want. End user can subscribe to mailing list listname@domain.dom by sending email to listname+subscribe@domain.com, unsubscribe from the list by sending email to listname+unsubscribe@domain.com. Of course you can disable the subscription and unsubscription with a setting.

iRedMail team also developes a simple RESTful API server called mlmmjadmin to help manage mailing lists, it also offers script tool to manage mailing lists from command line.

We will show you how to integrate both mlmmj and mlmmjadmin in this tutorial.

Backup LDAP data first

Although we don't modify any existing LDAP data in this tutorial, but it's a good idea to backup it now before you adding any new mailing lists.

Install mlmmj and other required package

Attention

# RHEL/CentOS 7
yum install mlmmj uwsgi uwsgi-plugin-python36 uwsgi-logger-syslog python3-requests python3-ldap

# RHEL/CentOS 8
yum install mlmmj python3-pip3 python3-requests python3-ldap
pip3 install uwsgi
# Debian 9
apt-get install mlmmj uwsgi uwsgi-plugin-python3 python3-requests python3-pyldap

# Other Debian/Ubuntu releases
apt-get install mlmmj uwsgi uwsgi-plugin-python3 python3-requests python3-ldap
cd /usr/ports/mail/mlmmj
make install clean
cd /usr/ports/www/uwsgi
make install clean
cd /usr/ports/www/py-requests
make install clean
pkg_add mlmmj altermime py3-ldap

Create required system account

mlmmj will be ran as user mlmmj and group mlmmj, all mailing list data will be stored under its home directory /var/vmail/mlmmj:

On Linux or OpenBSD:

groupadd mlmmj
useradd -m -g mlmmj -d /var/vmail/mlmmj -s /sbin/nologin mlmmj
mkdir /var/vmail/mlmmj-archive
chown -R mlmmj:mlmmj /var/vmail/mlmmj /var/vmail/mlmmj-archive
chmod -R 0700 /var/vmail/mlmmj /var/vmail/mlmmj-archive
chmod 0755 /var/vmail           # Make sure this directory is accessible by other users

On FreeBSD:

pw groupadd mlmmj
pw useradd mlmmj -m -g mlmmj -s /sbin/nologin -d /var/vmail/mlmmj
mkdir /var/vmail/mlmmj-archive
chown -R mlmmj:mlmmj /var/vmail/mlmmj /var/vmail/mlmmj-archive
chmod -R 0700 /var/vmail/mlmmj /var/vmail/mlmmj-archive
chmod 0755 /var/vmail           # Make sure this directory is accessible by other users

Postfix integration

Attention

# ${nexthop} is '%d/%u' in transport ('mlmmj:%d/%u')
mlmmj   unix  -       n       n       -       -       pipe
    flags=ORhu user=mlmmj argv=/usr/bin/mlmmj-amime-receive -L /var/vmail/mlmmj/${nexthop}
mlmmj_destination_recipient_limit = 1
query_filter     = (&(accountStatus=active)(!(domainStatus=disabled))(enabledService=mail)(enabledService=deliver)(|(&(objectClass=mailUser)(|(memberOfGroup=%s)(shadowAddress=%s)))(&(memberOfGroup=%s)(!(shadowAddress=%s))(|(objectClass=mailExternalUser)(&(objectClass=mailList)(!(enabledService=mlmmj)))(objectClass=mailAlias)))(&(objectClass=mailList)(enabledService=mlmmj)(|(mail=%s)(shadowAddress=%s)))))
search_base     = domainName=%d,o=domains,dc=xx,dc=xx
scope           = sub
query_filter    = (&(|(objectClass=mailUser)(&(objectClass=mailList)(enabledService=mlmmj)))(|(mail=%s)(shadowAddress=%s))(accountStatus=active)(!(domainStatus=disabled))(enabledService=mail))

Attention

mlmmj doesn't support signature signing very well, so we follow mlmmj official document and create this script to sign signature properly with command altermime. All iRedMail installation should have command altermime (package AlterMIME) available, so you don't need to install it manually

On Linux:

cd /usr/bin/
wget https://github.com/iredmail/iRedMail/raw/1.0/samples/mlmmj/mlmmj-amime-receive
chown mlmmj:mlmmj mlmmj-amime-receive
chmod 0550 mlmmj-amime-receive

On FreeBSD or OpenBSD:

cd /usr/local/bin/
wget https://github.com/iredmail/iRedMail/raw/1.0/samples/mlmmj/mlmmj-amime-receive
chown mlmmj:mlmmj mlmmj-amime-receive
chmod 0550 mlmmj-amime-receive

Amavisd Integration

We need Amavisd to listen on one more port 10027, it will be used to scan spam/virus for emails posted to mailing list.

$inet_socket_port = [10024, 10026, 10027, 9998];
$interface_policy{'10027'} = 'MLMMJ';
$policy_bank{'MLMMJ'} = {
    originating => 1,           # declare that mail was submitted by our smtp client
    allow_disclaimers => 0,     # mailing list should use footer text instead.
    enable_dkim_signing => 1,   # sign DKIm signature
    smtpd_discard_ehlo_keywords => ['8BITMIME'],
    terminate_dsn_on_notify_success => 0,  # don't remove NOTIFY=SUCCESS option
    bypass_spam_checks_maps => [1],     # don't check spam
    bypass_virus_checks_maps => [1],    # don't check virus
    bypass_banned_checks_maps => [1],   # don't check banned file names and types
    bypass_header_checks_maps => [1],   # don't check bad header
};

Now restart Amavisd and Postfix service, mlmmj mailing list manager is now fully integrated.

We will setup mlmmjadmin program to make managing mailing lists easier.

Setup mlmmjadmin: RESTful API server used to manage mlmmj mailing lists

cd /root/
wget https://github.com/iredmail/mlmmjadmin/archive/3.1.5.tar.gz
tar zxf 3.1.5.tar.gz -C /opt
rm -f 3.1.5.tar.gz
ln -s /opt/mlmmjadmin-3.1.5 /opt/mlmmjadmin
cd /opt/mlmmjadmin
cp settings.py.sample settings.py
chown mlmmj:mlmmj settings.py
chmod 0400 settings.py
# On Linux/FreBSD
$ eval </dev/urandom tr -dc A-Za-z0-9 | (head -c $1 &>/dev/null || head -c 32)
43a89b7aa34354089e629ed9f9be0b3b

# On OpenBSD
$ eval </dev/random tr -cd [:alnum:] | fold -w 32 | head -1
43a89b7aa34354089e629ed9f9be0b3b
api_auth_tokens = ['43a89b7aa34354089e629ed9f9be0b3b']

You can add as many token as you want for different API clients. For example:

api_auth_tokens = ['43a89b7aa34354089e629ed9f9be0b3b', '703ed37b20243d7c51c56ce6cd90e94c']
backend_api = 'bk_none'
backend_cli = 'bk_iredmail_ldap'
backend_api = 'bk_iredmail_ldap'
backend_cli = 'bk_iredmail_ldap'
iredmail_ldap_uri = 'ldap://127.0.0.1'
iredmail_ldap_basedn = 'o=domains,dc=XXX,dc=XXX'
iredmail_ldap_bind_dn = 'cn=vmailadmin,dc=XXX,dc=XXX'
iredmail_ldap_bind_password = 'xxxxxxxx'
MLMMJ_SPOOL_DIR = '/var/vmail/mlmmj'
MLMMJ_ARCHIVE_DIR = '/var/vmail/mlmmj-archive'
MLMMJ_DEFAULT_PROFILE_SETTINGS.update({'smtp_port': 10027})
MLMMJ_SKEL_DIR = '/usr/local/share/mlmmj/text.skel'
#
# For RHEL/CentOS 6
#
cp /opt/mlmmjadmin/rc_scripts/mlmmjadmin.rhel /etc/init.d/mlmmjadmin
chmod 0755 /etc/init.d/mlmmjadmin
chkconfig --level 345 mlmmjadmin on

#
# For RHEL/CentOS 7
#
perl -pi -e 's#python,#python36,#' /opt/mlmmjadmin/rc_scripts/uwsgi/rhel.ini
cp /opt/mlmmjadmin/rc_scripts/systemd/rhel.service /lib/systemd/system/mlmmjadmin.service
chmod 0644 /lib/systemd/system/mlmmjadmin.service
systemctl daemon-reload
systemctl enable mlmmjadmin

#
# For Debian 8, Ubuntu 14.04 and earlier releases which does NOT use systemd
#
cp /opt/mlmmjadmin/rc_scripts/mlmmjadmin.debian /etc/init.d/mlmmjadmin
chmod 0755 /etc/init.d/mlmmjadmin
update-rc.d mlmmjadmin defaults

#
# For Debian 9 and Ubuntu 16.04 which uses systemd
#
cp /opt/mlmmjadmin/rc_scripts/systemd/debian.service /lib/systemd/system/mlmmjadmin.service
chmod 0644 /lib/systemd/system/mlmmjadmin.service
systemctl daemon-reload
systemctl enable mlmmjadmin

#
# For FreeBSD
#
cp /opt/mlmmjadmin/rc_scripts/mlmmjadmin.freebsd /usr/local/etc/rc.d/mlmmjadmin
chmod 0755 /usr/local/etc/rc.d/mlmmjadmin
echo 'mlmmjadmin_enable=YES' >> /etc/rc.conf.local

#
# For OpenBSD
#
cp /opt/mlmmjadmin/rc_scripts/mlmmjadmin.openbsd /etc/rc.d/mlmmjadmin
chmod 0755 /etc/rc.d/mlmmjadmin
rcctl enable mlmmjadmin
#
# For RHEL/CentOS
#
mkdir /var/log/mlmmjadmin
chown root:root /var/log/mlmmjadmin
chmod 0755 /var/log/mlmmjadmin

#
# For Debian
#
mkdir /var/log/mlmmjadmin
chown root:adm /var/log/mlmmjadmin
chmod 0755 /var/log/mlmmjadmin

#
# For Ubuntu
#
mkdir /var/log/mlmmjadmin
chown syslog:adm /var/log/mlmmjadmin
chmod 0755 /var/log/mlmmjadmin

#
# For OpenBSD/FreeBSD
#
mkdir /var/log/mlmmjadmin
chown root:wheel /var/log/mlmmjadmin
chmod 0755 /var/log/mlmmjadmin

For Linux

cp /opt/mlmmjadmin/samples/rsyslog/mlmmjadmin.conf /etc/rsyslog.d/
service rsyslog restart

For OpenBSD, please append below lines in /etc/syslog.conf:

!!mlmmjadmin
local5.*            /var/log/mlmmjadmin/mlmmjadmin.log

For FreeBSD, please append below lines in /etc/syslog.conf:

!mlmmjadmin
local5.*            /var/log/mlmmjadmin/mlmmjadmin.log
#
# On Linux/FreeBSD:
#
service mlmmjadmin restart

#
# On OpenBSD
#
rcctl start mlmmjadmin

On Linux, you can check the port number with command netstat or ss like below:

netstat -ntlp | grep 7790
ss -ntlp | grep 7790

On FreeBSD/OpenBSD, run:

netstat -anl -p tcp | grep 7790

Manage subscribeable mailing lists

Please read document Manage subscribeable mailing lists.

References

See Also