Installare Mailman3 in un server con qmail e vpopmail

19 giugno 2024 by Roberto Puzzanghera 0 commenti

Mailman è un software libero per la gestione delle discussioni via mail e le liste di distribuzione. Mailman è integrato con il web, al fine di semplificare agli utenti la gestione degli account e agli ai proprietari (owners) l'amministrazione delle liste. Mailman comprende come parte integrante il sistema di archiviazione, il processamento automatico dei rimbalzi (bounce), il filtro dei contenuti, la spedizione dei digest, filtri anti spam, e altro.

Mailman è un software libero distribuitosotto la GNU General Public License, e scritto nel linguaggio di programmazione Python.

Indice


Se si è alla ricerca di qualcosa di più completo e avanzato rispetto al software per le mailing list software ezmlm che va di default con qmail, Mailman è sicuramente una delle migliori scelte.

All'inizio può essere difficile orientarsi persino nella documentazione ufficiale per trovare un buon punto di partenza per una installazione completa.

Questo è il punto di partenza che mi sento di consigliare io (aggiungerò link specifici man mano che andremo avanti nell'installazione):

Preparazione dell'ambiente virtuale

  • Maggiori informazioni qui

Il modulo venv supporta la creazione di “ambienti virtuali” leggeri, ognuno con proprio insieme di pacchetti Python indipendente installato nella loro site directory. Un ambiente virtuale viene creato sopra una installazione di Python esistente nel proprio OS, nota come il python di “base” dell'ambiente virtuale, e può essere opzionalmente isolato dai pacchetti Python già presenti del sistema operativo, pertanto solo quelli installati nell'ambiente virtuale saranno disponibili.

Aggiungere l'utente mailman:

groupadd mailman
useradd -g mailman -d /usr/local/mailman mailman
mkdir /usr/local/mailman
chown -R mailman:mailman /usr/local/mailman

La cartella home dell'utente mailman /usr/local/mailman sarà il contenitore dove risiederà l'ambiente virtuale che dobbiamo costruire.

La sua creazione deve essere fatta come utente mailman:

su - mailman

Prima di tutto è necessario creare il file .profile per l'utente mailman, di modo che la prossima volta che si utilizzerà il comando pip esso sarà preso dal suo ambiente virtuale (per renderlo operativo fare lo stesso dalla linea di comando oppure uscire dalla shell e poi rientrare):

echo "export PATH=~/bin:\$PATH" > .profile

Creare l'ambiente virtuale:

python3 -m venv --upgrade-deps /usr/local/mailman

In questo modo abbiamo creato l'ambiente virtuale in /usr/local/mailman. Sempre come utente mailman attivare l'ambiente virtuale:

cd
source bin/activate

Il prompt dei comandi sarà a questo punto cambiato di aspetto per informarci che siamo entrati dentro l'ambiente virtuale.

(mailman) mailman@qmail:~$

L'attivazione dell'ambiente virtuale anteporrà la cartella /usr/local/mailman al proprio PATH, di modo che il comando python usi l'interprete  python dell'ambiente virtuale e si possano lanciare gli script senza usare il loro path completo.

Si tenga presente che si deve attivare l'ambiente vistuale ogni volta che si deve fare una (dis)installazione o aggiornamento di un pacchetto python. Per fare la disattivazione è sufficiente usare il comando deactivate.

Il resto di questa documentazione assumerà quasi sempre che l'ambiente vistuale sia attivato. Se lo deve essere oppure no sarà visibile da un (mailman) prima del prompt $. Sarà anche dato per scontato che l'attivazione venga fatta dall'utente mailman.

Installazione di Mailman core

Non uscire dall'ambiente virtuale perchè è ora necessario fare l'installazione di Mailman core usando il comando pip, che è una copia di pip3 nell'ambiente virtuale.

(mailman)$ pip install mailman

Questo comando installerà Mailman core nell'ambiente virtuale con tutti i suoi prerequisiti. Se tutto è a posto terminerà con un messaggio  "Successfully installed" seguito dalla lista dei pacchetti installati.

Digitando mailman info verranno mostrati i dettagli e la versione di Mailman.

Configurazione

Per default Mailman cercherà il file di configurazione nella cartella ~/var/etc directory. Siccome preferisco usare ~/etc (anche per i successivi file di configurazione che verranno dopo), è necessaria qualche modifica. Ad esempio è necessario definire la variabile di ambiente MAILMAN_CONFIG_FILE nel file .profile:

su - mailman
source bin/activate
(mailman)$ cat >> ~/.profile << __EOF__
export MAILMAN_CONFIG_FILE=~/etc/mailman.cfg
export PYTHONPATH=~/etc
export PYTHONHOME=~/
__EOF__

Creare la directory etc

(mailman)$ mkdir -p ~/etc

Ora creare il file ~/etc/mailman.cfg, che sovrascrive le impostazioni mostrate in schema.cfg.

(mailman)$ cat >> ~/etc/mailman.cfg << __EOF__
[devmode] 
enabled: no 

[mailman] 
# This address is the "site owner" address.  Certain messages which must be 
# delivered to a human, but which can't be delivered to a list owner (e.g. a 
# bounce from a list owner), will be sent to this address.  It should point to 
# a human. 
site_owner: postmaster@mydomain.tld 

# The default language for this server. 
default_language: en 

[paths.master] 
var_dir: /usr/local/mailman/var 

[logging.database] 
level: warn 

[logging.debug] 
path: debug.log 
level: warn 

[logging.http] 
level: warn 

[logging.smtp] 
path: smtp.log 
level: info 

[language.it] 
description: Italian 
charset: utf-8 
enabled: yes

[mta] 
# https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/docs/mta.html#qmail 
# 
# NullMTA is just implementing the interface and thus satisfying Mailman 
# without doing anything fancy 
incoming: mailman.mta.null.NullMTA 
# Mailman should not be run as root. 
# Use any convenient port > 1024.  8024 is a convention, but can be 
# changed if there is a conflict with other software using that port. 
lmtp_host: 127.0.0.1 
lmtp_port: 8024 
# This will listen on localhost:8024 with LMTP and deliver outgoing messages to localhost:25. 

# How to connect to the outgoing MTA.  If smtp_user and smtp_pass is given, 
# then Mailman will attempt to log into the MTA when making a new connection. 
#smtp_host: 10.0.0.4

# Some list posts and mail to the -owner address may contain DomainKey or 
# DomainKeys Identified Mail (DKIM) signature headers <http://www.dkim.org/>. 
# Various list transformations to the message such as adding a list header or 
# footer or scrubbing attachments or even reply-to munging can break these 
# signatures.  It is generally felt that these signatures have value, even if 
# broken and even if the outgoing message is resigned.  However, some sites 
# may wish to remove these headers by setting this to 'yes'. 
remove_dkim_headers: no
__EOF__

Modificare la lingua preferita e l'indirizzo mail del proprietario del sito.

Mettere in sicurezza il file mailman.cfg poichè dovrà poi contenere la password di accesso al database:

chmod o-r ~/etc/mailman.cfg

Collegamento di qmail a Mailman

I seguenti comandi vanno digitati come root, quindi usciamo dalla shell mailman (exit).

Per il momento ospiteremo le liste in un dominio virtuale separato da quelli usati per la posta ordinaria, ad esempio lists.mydomain.tld. Se in seguito si vorrà aggiungere un altro dominio oppure un dominio di vpopmail già usato per la posta ordinaria leggere più sotto verso la fine di questo articolo. Useremo il file /var/qmail/control/virtualdomains per legare l'utente mailman al dominio lists.mydomain.tld:

echo lists.mydomain.tld:mailman >> /var/qmail/control/virtualdomains

E' necessario tenere presente che questo dominio virtuale non va creato con il solito programma  vadddomain, dal momento che esso esiste solo per legarlo a mailman e la sua definizione è diversa dai domini ordinari di vpopmail, i cui utenti hanno delle mailbox. In questo contesto, mailman è un utente di qmail/vpopmail che non ha niente a che vedere con la sua controparte nello spazio utenti di Linux, anche se il nome mailman è in comune.

Assicurarsi di aver impstato SPF, DKIM e DMARC per il dominio lists.mydomain.tld.

Aggiungere lists.mydomain.tld a rcpthosts così che qmail-smtpd accetti la posta per questo dominio. Non aggiungerlo a control/locals altrimenti il file virtualdomains sarà ignorato e il programma  Mailman non potrà essere lanciato.

echo lists.mydomain.tld >> /var/qmail/control/rcpthosts

Le impostazioni necessarie a far funzionare Mailman con qmail sono già nel file mailman.cfg che abbiamo creato prima:

[mta]
# NullMTA is just implementing the interface and thus satisfying Mailman 
# without doing anything fancy. Default would be postfix otherwise.
incoming: mailman.mta.null.NullMTA 

# Use any convenient port > 1024.  8024 is a convention, but can be 
# changed if there is a conflict with other software using that port.
# This will listen on localhost:8024 with LMTP and deliver outgoing messages
# to localhost:25. 
lmtp_port: 8024

Lo script qmail-lmtp nella cartella contrib è usato per comunicare a Mailman quante parti (separate dal trattino) dell'indirizzo di destinazione devono essere filtrate. Noi non useremo quello disponibile nella cartella contrib perchè non funziona con mailman3, come spiegato qui, dove ho però trovato una patch per risolvere il problema. In breve, qmail-local invia dei caratteri LF di terminazione della riga, mentre il protocollo SMTP richiede la serie di caratteri CRLF, e ciò causa una interruzione della conversazione SMTP tra qmail e Mailman con l'errore: "Line too long (see RFC5321 4.5.3.1.6)". Secondo quanto dice uno sviluppatore il file qmail-lmtp modificato che andremo a usare potrebbe avere dei risultati imprevisti quando vengono spediti dei binari che contengono caratteri \n e \r (ciò richiederebbe una patch di qmail-local oppure una ulteriore revisione di qmail-lmtp). Detto questo, tutto sembra funzionare a dovere qui nel mio server.

(mailman)$ wget -O ~/qmail-lmtp https://notes.sagredo.eu/files/qmail/mailman/qmail-lmtp

Inserire ora il richiamo allo script nel file dot-qmail di default

(mailman)$ echo "|~/qmail-lmtp 8024 1" > ~/.qmail-default

Il primo argomento specifica la porta LMTP di Mailman.

Poichè i messaggi locali sono inviati da vpopmail all'utente mailman, è necessario assegnare a vpopmail i privilegi di lettura del file ~/mailman/.qmail-default, che contiene le informazioni relative al programma che si farà carico della consegna del messaggio, ovvero Mailman:

(mailman)$ chmod 644 ~/.qmail-default

Mailman invierà via SMTP alla nostra qmail MTA moltissime mail simultanee e, se si è abilitato un limite al numero massimo di destinatari per messaggio, è necessario controllare che quel limite non sia inferiore al numero di messaggi che solitamente una lista deve far uscire. In particolare, se si sta usando la patch qmail-maxrcpt già incorporato nel mio pacchetto qmail, controllare il limite impostato nel file qmail/control/maxrcpt. Si può ora (versione 2024.06.08 in poi) impostare la variabile DISABLE_MAXRCPT nelle proprie tcprules per disabilitare il limite per i soli IP locali, ad esempio.

Infine dobbiamo evitare di lanciare i filtri di simscan quando qmail riceve messaggi dal servizio LMTP di Mailman, cosa che potrebbe causare errori di verifica DKIM. Modificare di conseguenza le proprie tcprules aggiungendo una regola QMAILQUEUE="/var/qmail/bin/qmail-queue" agli IP locali, per esempio:

127.:allow,RELAYCLIENT="",DISABLE_MAXRCPT="",QMAILQUEUE="/var/qmail/bin/qmail-queue"
0.0.0.0:allow,RELAYCLIENT="",DISABLE_MAXRCPT="",QMAILQUEUE="/var/qmail/bin/qmail-queue" 
10.0.0.:allow,RELAYCLIENT="",QMAILQUEUE="/var/qmail/bin/qmail-queue" 

Compilare quindi le tcprules con il comando qmailctl cdb.

Impostazione di MySQL

Mailman necessita di un database relazionale per assicurare la persistenza dei dati. postgres è il database raccomandato. Se si preferisce usare SQLite procedere oltre questo paragrafo, dato che questo è il database di default. Per usare MySQL, installare prima il modulo pymysql:

(mailman)$ pip install pymysql

Quindi creare il database MySQL e l'utente mailman:

CREATE USER 'mailman'@'localhost' IDENTIFIED VIA mysql_native_password USING '***';
GRANT USAGE ON *.* TO 'mailman'@'localhost' REQUIRE NONE WITH MAX_QUERIES_PER_HOUR 0 MAX_CONNECTIONS_PER_HOUR 0 MAX_UPDATES_PER_HOUR 0 MAX_USER_CONNECTIONS 0;
CREATE DATABASE IF NOT EXISTS `mailman` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON `mailman`.* TO 'mailman'@'localhost';

Naturalmente sarà necessario cambiare localhost se MySQL è installato altrove nella rete.

Aggiungere le impostazioni del database al file ~/etc/mailman.cfg

(mailman)$ cat >> ~/etc/mailman.cfg << __EOF__

[database] 
class: mailman.database.mysql.MySQLDatabase 
url: mysql+pymysql://mailman:password@localhost/mailman?charset=utf8mb4&use_unicode=1
__EOF__

Avvare Mailman

Per avviare o fermare il server si può digitare mailman start/stop come utente mailman. Se il proprio OS è basato su systemd riferirsi alla documentazione ufficiale qui, altrimenti scaricare lo script di avvio, renderlo eseguibile e caricarlo nel proprio file rc.local.

Quanto segue deve essere fatto come utente root

wget -O /usr/local/bin/mmctl https://notes.sagredo.eu/files/qmail/mailman/mmctl
chmod +x /usr/local/bin/mmctl
mmctl start

Lo script di avvio richiede di cambiare directory su ~mailman a causa di un bug.

Se il comando mmctl info non restituisce errori significa che Mailman core è configurato correttamente:

# mmctl info 
GNU Mailman 3.3.9 (Tom Sawyer) 
Python 3.9.19 (main, Mar 20 2024, 14:44:21)  
[GCC 11.2.0] 
config file: /usr/local/mailman/var/etc/mailman.cfg 
db url: mysql+pymysql://mailman:password@localhost/mailman?charset=utf8mb4&use_unicode=1 
devmode: DISABLED 
REST root url: http://localhost:8001/3.1/ 
REST credentials: restadmin:restpass

Si può fare lo stesso test come utente mailman in modalità attivata digitando mailman info.

Si può interagire con Mailman dalla linea di comando digitando mailman shell (help() per un aiuto interattivo), ma sarà più semplice fare le cose utilizzando l'interfaccia grafica Postorius.

Cronjobs

Mailman richiede alcuni cronjob per azioni periodiche. Aggiungere quanto segue al cronjob come utente mailman (su - mailman && crontab -e)

@daily ID=mailman  source /usr/local/mailman/bin/activate && /usr/local/mailman/bin/mailman -C /usr/local/mailman/etc/mailman.cfg notify >> /usr/local/mailman/var/logs/cron.log 2>&1
@daily ID=mailman  source /usr/local/mailman/bin/activate && /usr/local/mailman/bin/mailman -C /usr/local/mailman/etc/mailman.cfg digests --periodic >> /usr/local/mailman/var/logs/cron.log 2>&1

Installare Mailman Web UI

Postorius e Hyperkitty sono rispettivamente l'interfaccia web e l'archiviatore ufficiale di Mailman. Mailman-web è un pacchetto singolo che consente di installarli entrambi. Si può ovviamente lanciare Mailmann3 senza di esso, ma la maggior parte della gente preferisce usare l'interfaccia web per cambiare le impostazioni delle liste, vedere le informazioni sulle liste disponibili, e fare le iscrizioni o le cancellazioni degli utenti. Django è l'ambiante python usato per costruire le interfacce web Postorius e Hyperkitty.

Torniamo nell'ambiente virtuale perchè dobbiamo installare Mailman web:

su - mailman
source bin/activate
(mailman)$ pip install mysqlclient mailman-web mailman-hyperkitty pylibmc

Useremo anche qui MySQL ma in un nuovo database mailman_web, il cui proprietario sarà ancora l'utente mailman, che già ha i privilegi per il database mailman che abbiamo creato prima:

CREATE DATABASE `mailman_web` CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
GRANT ALL PRIVILEGES ON `mailman_web`.* TO 'mailman'@'localhost';

Il parametro CHARACTER SET utf8mb4 è importante. In MariaDB non è il default quando si crea un database.

Il file ~/settings.py conterrà le impostazioni di Mailman web. Scaricare e modificare:

(mailman)$ wget -O ~/etc/settings.py https://notes.sagredo.eu/files/qmail/mailman/settings.py
(mailman)$ chmod o-r ~/etc/settings.py

E' importante aggiungere il proprio dominio alle variabili ALLOWED_HOSTS e CSRF_TRUSTED_ORIGINS. Qui lists.mydomain.tld è il sito web usato per ospitare Mailman, non necessariamente quello che contiene le mailing list.

#: See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts 
ALLOWED_HOSTS = [ 
   "localhost",  # Archiving API from Mailman, keep it. 
   "127.0.0.1", 
   "0.0.0.0", 
   "lists.mydomain.tld", 
   # Add here all production domains you have. 
]

#: See https://docs.djangoproject.com/en/dev/ref/settings/#csrf-trusted-origins 
#: For Django <4.0 these are of the form 'lists.example.com' or 
#: '.example.com' to include subdomains and for Django >=4.0 they include 
#: the scheme as in 'https://lists.example.com' or 'https://*.example.com'. 
CSRF_TRUSTED_ORIGINS = [ 
   "http://lists.mydomain.tld",
   "https://lists.mydomain.tld", 
   # "lists.your-domain.org", 
   # Add here all production domains you have. 
]

Aggiungere la locazione del file di configurazione al .profile dell'utente mailman (il default sarebbe altrimenti /etc/settings.py):

(mailman)$ cat >> ~/.profile << __EOF__
export DJANGO_SETTINGS_MODULE=~/etc/settings 
__EOF__

Prestare attenzione alla variabile SITE_ID. E' l'ID del sito Django servito, ovvero quello che ospita le pagine web del pannello di controllo Mailman web.

#: Current Django Site being served. This is used to customize the web host 
#: being used to serve the current website. For more details about Django 
#: site, see: https://docs.djangoproject.com/en/dev/ref/contrib/sites/ 
SITE_ID = 2

Quando si aprirà per la prima volta l'interfaccia Mailman web, si avrà un sito example.com già creato con SITE_ID = 1 che si potrebbe voler cancellare e sostituire con mydomain.tld, che avrà invece SITE_ID = 2 o qualcos'altro. Inserire questo valore in settings.py, che sarà presumibilmente 2.

Creare la directory che ospiterà i file di Mailman web:

mkdir -p ~/web/logs

Nei prossimi comandi  dovremo passare a mailman-web alcune variabili. Non mi è chiaro perchè non le legga dalle variabili di ambiente (env).

Impostare lo schema per le componenti Mailman:

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web migrate

Copiare i file statici (css, js, images) in STATIC_ROOT:

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web collectstatic

Comprimere i vari file CSS (è necessario il pacchetto sass):

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web compress

Aggiornare il catalogo dei linguaggi supportati:

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web compilemessages

Ora impostare l'account di amministrazione principale. superuser è considerato il proprietario del sito e ha accesso a tutti i domini, a tutte le  mailing list e alle loro impostazioni. Ti sarà richiesto di inserire una mail valida e di confermarla. Non usare un account come  postmaster@lists.mydomain.tld perchè sarebbe difficile recuperare la mail di conferma. Usare piuttosto qualcosa come postmaster@mydomain.tld.

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web createsuperuser

Configurazione di memcached

L'installazione dei pacchetti memcached e pylibmc fatta prima è raccomandata per risolvere un problema secondo il quale la cancellazione di voci dall'archivio manda in crash il sistema Django (maggiori informazioni qui), problema che può essere per l'appunto risolto con l'installazione di un sistema di caching che sia comune tra tutti i workers. L'installazione di memcached può essere agevolmente fatta mediante un pacchetto del proprio OS e non è trattata qui; assicurarsi però che la porta dove esso è in ascolto sia la 11211 e che sia eseguito all'avvio del sistema. Le impostazioni di memcached sono già salvate nel file settings.py che abbiamo scaricato prima:

# Using the cache infrastructure can significantly improve performance on a 
# production setup. This is an example with a local Memcached server. 
# pip install pylibmc 
CACHES = { 
   'default': { 
       'BACKEND': 'django.core.cache.backends.memcached.PyLibMCCache', 
       'LOCATION': '127.0.0.1:11211', 
   } 
}

Installazione del server WSGI

WSGI fa in modo che Django lavori dietro apache o un altro web server. Come già detto Django è l'ambiente web basato su python usato per costruire Postorius e Hyperkitty.

(mailman)$ pip install uwsgi

Scaricare il file di configurazione (non è necessaria alcuna modifica):

wget -O ~/etc/uwsgi.ini https://notes.sagredo.eu/files/qmail/mailman/uwsgi.ini

Testare (uscire con ^C):

(mailman)$ uwsgi --ini ~/etc/uwsgi.ini

Script di avvio

Gli utenti sotto systemd dovrebbero riferirsi alla documentazione ufficiale qui (è uno stacco breve da questa guida). Gli altri possono usare questo mio script:

wget -O /usr/local/bin/uwsgictl https://notes.sagredo.eu/files/qmail/mailman/uwsgi.ini
chmod +x /usr/local/bin/uwsgictl

Aggiungerlo al proprio rc.local o init.d. Testare come utente root:

# uwsgictl  
Usage: /usr/local/bin/uwsgictl {start|stop|restart|reload|force-reload} 
# uwsgictl start 
Starting uWSGI Server[uWSGI] getting INI configuration from /usr/local/mailman/etc/uwsgi.ini

I file log sia per UWSGI che Mailman Web sono nella cartella ~/web/logs.

Installazione del programma di ricerca testi (Xapian)

Per installare si xapian-core che xapian-bindings nell'ambiente virtuale è necessario prima controllare il numero dell'ultima versione nel sito dei sorgenti e poi passarlo come argomento allo script di installazione:

(mailman)$ wget https://raw.githubusercontent.com/notanumber/xapian-haystack/master/install_xapian.sh
(mailman)$ sh install_xapian.sh 1.4.25

Installare Xapian-Haystack:

pip install xapian-haystack

Ricostruire gli indici (forzare):

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web rebuild_index
WARNING: This will irreparably remove EVERYTHING from your search index in connection 'default'. 
Your choices after this are to restore from backups or rebuild via the `rebuild_index` command. 
Are you sure you wish to continue? [y/N] Y 
Removing all documents from your index because you said so. 
All documents removed. 
Indexing 11 emails

Le seguenti impostazioni sono già all'interno del file ~/etc/settings.py che abbiamo scaricato prima:

# xapian (full text search) 
HAYSTACK_CONNECTIONS = { 
   'default': { 
       'HAYSTACK_XAPIAN_LANGUAGE': 'en', 
       'ENGINE': 'xapian_backend.XapianEngine', 
       'PATH': "/usr/local/mailman/web/xapian_index" 
   }, 
}

Si può cambiare la lingua modificando la variabile HAYSTACK_XAPIAN_LANGUAGE. La lista delle lingue disponibili può essere trovata qui.

Ora riavviare il server (gli utenti con systemd faranno diversamente):

uwsgictl restart

Impostazione dei cronjob per Mailman Web

Come utente mailman modificare il crontab (crontab -e) e installare i seguenti cronjobs:

@hourly            ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs hourly         >/dev/null 2>&1 
@daily             ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs daily          >/dev/null 2>&1 
@weekly            ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs weekly         >/dev/null 2>&1 
@monthly           ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs monthly        >/dev/null 2>&1 
@yearly            ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs yearly         >/dev/null 2>&1 
* * * * *          ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs minutely       >/dev/null 2>&1 
2,17,32,47 * * * * ID=mailman  PYTHONPATH=/usr/local/mailman/etc/ DJANGO_SETTINGS_MODULE=settings /usr/local/mailman/bin/mailman-web runjobs quarter_hourly >/dev/null 2>&1

Testare:

(mailman)$ PYTHONPATH=~/etc/ DJANGO_SETTINGS_MODULE=settings mailman-web runjobs -l             
Job List: 11 jobs 
appname           - jobname                - when    - help 
-------------------------------------------------------------------------------- 
django_extensions - cache_cleanup          - daily   - Cache (db) cleanup Job 
django_extensions - daily_cleanup          - daily   - Django Daily Cleanup Job 
hyperkitty        - empty_threads          - monthly - Remove empty threads 
hyperkitty        - new_lists_from_mailman - hourly  - Import new lists from Mailman 
hyperkitty        - orphan_emails          - daily   - Reattach orphan emails 
hyperkitty        - recent_threads_cache   - daily   - Refresh the recent threads cache 
hyperkitty        - sync_mailman           - daily   - Sync user and list properties with Mailman 
hyperkitty        - thread_order_depth     - yearly  - Compute thread order and depth for all threads 
hyperkitty        - thread_starting_email  - hourly  - Find the starting email when it is missing 
hyperkitty        - update_and_clean_index - monthly - Update the full-text index and clean old entries 
hyperkitty        - update_index           - hourly  - Update the full-text index

L'archiviatore HyperKitty

HyperKitty è l'applicazione che fornisce l'accesso agli archivi di Mailman, e che interagisce con le liste. Per connettere HyperKitty con Mailman, queste sono le righe già presenti nel proprio mailman.cfg che abbiamo installato prima:

# For the HyperKitty archiver. 
[archiver.hyperkitty] 
class: mailman_hyperkitty.Archiver 
enable: yes 
configuration: /usr/local/mailman/etc/mailman-hyperkitty.cfg

Ora creare il file mailman-hyperkitty.cfg (scarica)

(mailman)$ cat > ~/etc/mailman-hyperkitty.cfg << __EOF__
# This is the mailman extension configuration file to enable HyperKitty as an 
# archiver. Remember to add the following lines in the mailman.cfg file: 
# 
# [archiver.hyperkitty] 
# class: mailman_hyperkitty.Archiver 
# enable: yes 
# configuration: /path/to/here/mailman-hyperkitty.cfg 
# 

[general] 
# This is your HyperKitty installation, preferably on the localhost. This 
# address will be used by Mailman to forward incoming emails to HyperKitty 
# for archiving. It does not need to be publicly available, in fact it's 
# better if it is not. 
# However, if your Mailman installation is accessed via HTTPS, the URL needs 
# to match your SSL certificate (e.g. https://lists.example.com/hyperkitty). 
base_url: http://lists.mydomain.tld/archives/ 

# The shared api_key, must be identical except for quoting to the value of 
# MAILMAN_ARCHIVER_KEY in HyperKitty's settings. 
api_key: xxxxxxxxxxxxxxxxxxx
__EOF__

E' importante che il valore di api_key corrisponda al valore MAILMAN_ARCHIVER_KEY in settings.py. Modificare anche la variabile base_url.

Configurazione di Apache

Ecco un esempio di apache virtual host. mod_proxy deve essere abilitato:

Define MMDIR /usr/local/mailman 
Define MMDOMAIN lists.mydomain.tld

<VirtualHost *:443> 
 ServerName  ${MMDOMAIN}
 # Include SSL stuff

 CustomLog ${LOGDIR}/${MMDOMAIN}.log combined 
 ErrorLog  ${LOGDIR}/${MMDOMAIN}_error.log 

 Alias /static "${MMDIR}/web/static" 
 Alias /favicon.ico $MMDIR/web/static/hyperkitty/img/favicon.ico 
 <Directory "${MMDIR}/web/static"> 
   Require all granted 
 </Directory> 

 <IfModule mod_rewrite.c> 
   RewriteEngine On 
   # redirects / calls to /mailman3 
   RewriteRule ^/$ https://${MMDOMAIN}/mailman3 [R=302,L] 
 </IfModule> 

 <IfModule mod_proxy.c> 
   SSLProxyEngine On 
   ProxyRequests Off 
   ProxyPreserveHost On 
   ProxyPass "/mailman3"     "http://127.0.0.1:8000/mailman3" 
   ProxyPass "/archives"     "http://127.0.0.1:8000/archives" 
   ProxyPass "/accounts"     "http://127.0.0.1:8000/accounts" 
   ProxyPass "/admin"        "http://127.0.0.1:8000/admin" 
   ProxyPass "/user-profile" "http://127.0.0.1:8000/user-profile" 
   ProxyPassMatch ^/static/ ! 
 </IfModule> 
</VirtualHost>

Una volta finito, navigare su https://lists.mydomain.org/mailman3 e loggarsi con l'account superuser. Quindi confermare la mail di superuser e loggarsi di nuovo.

logrotate

Questo è il file logrotate per ruotare i log sia di Mailman che di Mailman web:

cat > /etc/logrotate.d/mailman << __EOF__
#mailman 
/usr/local/mailman/var/logs/*.log { 
  missingok 
  sharedscripts 
  su mailman mailman 
  postrotate 
    # /usr/local/bin/mmctl reopen &>/dev/null || true # users with no systemd
    cd /usr/local/mailman 
    sudo -u mailman /usr/local/mailman/bin/mailman -C /usr/local/mailman/etc/mailman.cfg reopen &>/dev/null || true
  endscript 
} 

# mailman-web 
/usr/local/mailman/web/logs/*.log { 
  hourly 
  missingok 
  notifempty 
  delaycompress 
  su mailman mailman 
}
__EOF__

Aggiungere domini

Con le precedenti istruzioni tutte le liste appartengono tutte a uno stesso dominio (lists.mydomain.tld negli esempi). Cosa è necessario fare se si vuole creare liste su altri domini, per esempio otherdomain.tld?

Creare un utente Linux e collegare il dominio virtuale otherdomain.tld a questo utente:

useradd -d /home/username username
mkdir -p /home/username
chown -R username:users /home/username
echo otherdomain.tld:username >> /var/qmail/control/virtualdomains

In questo modo qmail cercherà il file dot-qmail che è responsabile per la gestione del recapito dei messaggi in mailbox nella cartella home di quell'utente. Pertanto dobbiamo salvare lì le istruzioni per chiamare il servizio LMTP di Mailman:

echo "|/usr/local/mailman/qmail-lmtp 8024 1" > /home/username/.qmail-default
chown username:users /home/username/.qmail-default

Si potrebbe pensare di ottenere lo stesso risultato semplicemente creando un alias /var/qmail/alias/.qmail-username-default ma questo metodo non funzionerebbe, perchè qmail passerebbe a Mailman il destinatario username-listname@otherdomain.tld invece di listname@otherdomain.tld e si otterrebbe l'errore "mailbox not found".

Come sappiamo Django contempla una gestione dei “siti”. E' un collegamento per associare oggetti e funzionalità a particolari siti web ed è un posto dove tenere i nomi dei domini e vedere quali sono i domini dei siti di Django. Dovremmo aver già creato il sito lists.mydomain.tld site con SITE_ID=2. Quando si creano le liste per il nuovo dominio nel pannello di controllo di Postorius, sarà necessario scegliere lists.mydomain.tld come loro "Web server".

Aggiungere mailing list al proprio dominio di posta principale

Probabilmente ti starai chiedendo se si possa definire una lista come list@mydomain.tld, dove mydomain.tld è un dominio con utenti qmail/vpopmail e con i loro file .qmail-default già esistenti. La risposta è sì. Basta creare il file dot-qmail con il nome che si vuole assegnare alla lista, chiamare Mailman al solito modo e il gioco è fatto:

echo "|/usr/local/mailman/qmail-lmtp 8024 1" > ~vpopmail/domains/mydomain.tld/.qmail-list

Problemi noti

  • Mailman web va in crash con l'errore "AttributeError: 'NoneType' object has no attribute 'thread'" quando si clicca sul bottone "Reattach this conversation" nel'archivio HyperKitty. Ho aperto un ticket qui.
  • Come già detto, lo script originale qmail-lmpt non funziona con Mailman3 perchè qmail-local invia caratteri LF a fine riga, mentre gli standard SMTP richiedono caratteri CRLF, pertanto la conversazione SMTP tra qmail e Mailman termina con l'errore: "Line too long (see RFC5321 4.5.3.1.6)". Il file qmail-lmtp modificato che stiamo usando può avere risultati imprevisti quando vengono spediti binari con caratteri \n o \r, secondo quanto scrive uno sviluppatore in questa conversazione. Detto questo, tutto funziona bene nel mio server.

Istruzioni per il proprietario della lista

Se i vostri utenti vi chiedono un manuale per l'amministratore della lista, si può suggerire questo video guida (in inglese), che copre tutti gli aspetti.

Il manuale per il membro della lista è invece nella guida ufficiale qui (in inglese).

Aggiungi un commento