Introduction
This tutorial is all about mailman3 software for creating and managing mailing lists and archives. It goes in-depth on how to install mailman3 in a Debian or Ubuntu OS and migrate existing lists from older mailman versions. It assumes that postfix (a Mail Transport Agent, aka MTA) and mailutils are already installed in the system and configured, and the system can send emails, e.g the root user is sending admin related emails. It also assumes that python3, postgresql and apache2 are installed in the system too. Postfix is one of the possible MTA to be configured with mailman3. Detailed steps for configuring a fresh postfix install and few other MTA options, are included in the CHEAT SHEET note 1. The tutorial is intended specifically for sysadmins and users who are curious of how machines and networks work in general.
Enjoy the geeky reading!
Install Dependency Libraries
We enter the remote server and become root user to do system updates:
$ ssh user@server -i
Once we are on the remote server we do the following (as well all the rest of the commands are meant to be ran on the remote server):
$ sudo su
We give our password and we do the updates:
# apt update && apt upgrade
Then we can install some system-wide dependencies:
# apt-get install build-essential libssl-dev libffi-dev
break down of the above libraries:
build-essential: GNU debugger, g++/GNU compiler and other tools for compiling software.
libssl-dev: portion of OpenSSL which supports TLS protocol and depends on libcrypto, a C API.
libffi-dev: the glue between the interpreter program (python in this case) and the compiled code, for values of arguments to be converted and passed in run-time between the two programs. [Note 3]
Install party goes on:
# apt install python3-dev python3-venv lynx
break down of the above libraries:
python3-dev: tools for extending the python interpreter and building python modules.
python3-venv: a tool to create virtual environment to isolate a python project's dependencies from the OS main python libraries.
lynx: An HTML to plaintext converter like lynx is required by Mailman Core for converting emails to plaintext.
Then install rust from source, which is needed for python Cryptography library later on.
curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh
Ensure that rust is installed:
# rust --version
The above script will also install cargo, which is a package manager, so it fetches any extra dependencies needed for a rustic program, and a builder for rustic programs to be compiled.
[Note 2]
We need also sassc: Syntactically Awesome Stylesheets or Sass is an extension of CSS, which allows using variables, nested rules etc. Here we install a C/C++ flavor needed for Hyperkitty archiver that uses sass to generate its CSS styles. https://sass-lang.com/. For the sass installation for debian, download from source and make a symbolic link to /usr/local/bin
# cd /usr/local/lib [Note 4]
# wget https://github.com/sass/dart-sass/releases/download/1.32.5/dart-sass-1.32.5-linux-x64.tar.gz
# tar -xf dart-sass-1.32.5-linux-x64.tar.gz
# chmod -R 755 dart-sass
# ln -s /usr/local/lib/dart-sass/sass /usr/local/bin/sass
# rm -f dart-sass-1.32.5-linux-x64.tar.gz
Ref: Note 5
GNU mailman wiki suggests to install also:
Fail2ban for blocking IP addresses that have too many connection failures.
# apt install fail2ban
Memcached for Django caches in memory, in order to render mailman's front-end UI faster.
# apt install memcached
After installation check that is running at port 11211 with
# service memcached status
Output of memcached should show an active status:
# memcached.service - memcached daemon
Loaded: loaded (/lib/systemd/system/memcached.service; enabled; vendor preset: enabled)
Active: active (running) since Sun 2021-08-29 15:08:13 EEST; 3h 29min ago
Later we see how to add the CACHES configuration in the mailman settings.py.
Gettext for supporting internationalization and localization, needed for multilingual environments.
# apt install gettext
See configuration settings in CHEAT SHEET [Notes 6, 7, 8]
System Configurations
Create a postgresql or mysql database
Here is an example with postgresql. We replace the names according to our likes and available system paths. Enter the postgresql user and initiate the psql shell (psql command requests the postgres user password which was configured during the postgresql setup). When creating the database, we can opt for setting up a tablespace where the database objects are stored. This is handy when we want to migrate the database because we ran out of disk space. Or when we want to optimize performance. E.g, make use of a fast solid state device (SSD) available as a mounted volume.
# sudo su postgresql
$ psql
> CREATE TABLESPACE mailman_vol LOCATION '/ssd1/postgresql/data';
> CREATE DATABASE mailman_db OWNER mailman TABLESPACE mailman_vol;
> exit;
Setup mailman user and virtualenv
# useradd -m -d /opt/mailman -s /usr/bin/bash mailman
# sudo su mailman
Enter mailman directory, create a virtualenv and activate it:
$ cd ; python3 -m venv venv
$ source /opt/mailman/venv/bin/activate
Note: we can add the above command in .bashrc under mailman's home, so every time we enter this user, the virtualenv gets activated automagically.
Install Mailman and other python libraries
(venv)$ pip install wheel mailman
if project connects to a postgresql database then we need also:
(venv)$ pip install psycopg2-binary
Install front-end UI and archiver
(venv)$ pip install mailman-web mailman-hyperkitty
mailman-web provides hyperkitty and postorius which are built atop Django, a Python based web framework. It also provides shortcuts to django admin commands. Later we will create a superuser that has all permissions for administering the lists and can enter the admin area via the browser.
Install the following for mailman-web application to be able to talk with apache2 server (here we opt for gunicorn, other option is uWSGI) and a python client for Django to connect to memcached:
(venv)$ pip install gunicorn pylibmc
Configurations
Mailman
Exit mailman user and as root we create a new dir:
# mkdir -p /etc/mailman3/
We make owner of this directory the mailman user:
# chown -R mailman:mailman /etc/mailman3
and under it, we create the files mailman.cfg and settings.py.
Under /opt/mailman/mm we create the file mailman-hyperkitty.cfg ('mm' or other name of our choice, it is a new directory to park hyperkitty configuration and logs).
In the mailman.cfg edit the archiver directive as following:
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /opt/mailman/mm/mailman-hyperkitty.cfg
And in mailman-hyperkitty.cfg:
# The base_url should correspond with the apache2 links we configure later
base_url: http://localhost/archives
# Shared API key, must be the identical to the value the same as in the /etc/mailman3/settings.py
api_key: SecretArchiverAPIKey
For a settings.py sample see in the CHEAT SHEET. The important setting to add, which allows automated correspondence from the site manager:
DEFAULT_FROM_EMAIL = 'lists@sdomain-name.org' or 'user@localhost'
And for activating the memcached we need to add:
'default': {
'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache',
'LOCATION': os.environ.get('CACHE_LOCATION','127.0.0.1:11211'),
}
}
Note 1: django's global settings is located in /opt/mailman/venv/lib/python3.7/site-packages/django/conf/global_settings.py. These are imported in the /etc/mailman3/settings.py and they get overwritten if declared again in the latter file.
Note 2: If we want to use an external mail service than the localhost, we need also to set:
EMAIL_HOST =
EMAIL_PORT = 25
EMAIL_HOST_USER =
EMAIL_HOST_PASSWORD =
Extra options to set in case they are needed:
EMAIL_TIMEOUT =