Big Bang !

This commit is contained in:
mco-system 2023-03-04 13:48:33 +11:00
commit 4acd363b71
1 changed files with 293 additions and 0 deletions

293
README.md Normal file
View File

@ -0,0 +1,293 @@
# Migration *Mailman2* vers *Mailman3*
## Installation de *Mailman3* via Docker et docker-compose
### Limites et Pré-requis
#### Limites
Cette procédure ne traite que du cas suivant:
- Serveur *SMTP* utilisé: *Postfix*
- Système de base de données utilisée: *Postgres*
- Serveur mandataire inverse `Apache Httpd`
#### Prérequis
1. Un système Linux fonctionnel sur lequel
- sont installés les paquets suivants:
- git
- postfix
- docker
- docker-compose (Un binaire souvent bien plus récent que celui proposé par le gestionnaire de paquets de la distribution peut être installé [directement à partir du dépôt Git](https://github.com/docker/compose/releases/).)
2. L'accès à un serveur *SMTP*, idéalement *Postfix*
3. L'accès à une base de données *Postgres*
### Installation
1. Cloner le dépôt suivant:
- https://github.com/maxking/docker-mailman
```bash
git clone https://github.com/maxking/docker-mailman
```
2. Éditer le fichier `docker-compose.yaml` (Il est probablement possible de faire la même chose à l'aide d'un fichier `.env` ou `docker-compose.override.yaml`)
- Pour le service `mailman-core`:
- Renseigner les variables d'environnement suivantes:
| Variable | Commentaire (valeur) |
| ------------------ | ---------------------------------- |
| MTA | Le type de MTA utilisé (`postfix`) |
| SMTP_HOST | Le FQDN du serveur SMTP utilisé |
| SMTP_PORT | Le port du serveur SMTP utilisé (`25`) |
| DATABASE_URL | Le DSN d'accès à la base de données `postgresql://<user>:<password>@<host>:<port>/<database>` |
| DATABASE_TYPE | `postgres`) |
| DATABASE_CLASS | `mailman.database.postgresql.PostgreSQLDatabase` |
| HYPERKITTY_API_KEY | Random encodé en base64: ie `head -c 64 /dev/random \| base64` |
- Définir le volume `/opt/mailman/mailman/core:/opt/mailman/`
Le volume est un volume *local bind*, le répertoire `/opt/mailman/mailman/core` devra être être crée sur la machine hôte hébergeant le container. Le répertoire peut prendre n'importe quelle valeur adaptée à la situation.
- Définir la politique de redémarrage du service à `always`
- Pour le service `mailman-web`:
- Renseigner les variables d'environnement suivantes:
| Variable | Commentaire |
| --------------------- | ------------------------------------ |
| SMTP_HOST | Le FQDN du serveur SMTP utilisé |
| SMTP_PORT | Le port du serveur SMTP utilisé (`25`) |
| DJANGO_ALLOWED_HOSTS | Le FQDN par lequel sera accédée l'interface web i.e: `lists.example.com` |
| SERVE_FROM_DOMAIN | | Le FQDN par lequel sera accédée l'interface web i.e: `lists.example.com` |
| DATABASE_URL | Le DSN d'accès à la base de données `postgresql://<user>:<password>@<host>:<port>/<database>` |
| DATABASE_TYPE | `postgres` |
| HYPERKITTY_API_KEY | La même clef que définie pour le service `mailman-core` |
| SECRET_KEY | Random encodé en base64: ie `head -c 64 /dev/random \| base64` |
| MAILMAN_ADMIN_USER | Le nom d'utilisateur de l'administrateur par défaut |
| MAILMAN_ADMIN_EMAIL | L'adresse de courriel valide de l'administrateur |
- Définir le volume `/opt/mailman/mailman/web:/opt/mailman-web-data`
Le volume est un volume *local bind*, le répertoire `/opt/mailman/mailman/web` devra être être créé sur la machine hôte hébergeant le container (voir plus bas). Le répertoire peut prendre n'importe quelle valeur adaptée à la situation.
- Définir la politique de redémarrage du service à `always`
- Modifier la commande d'exécution du container en ajoutant l'option `--check-static` avec pour argument le volume contenant les fichiers statiques
```yaml
command: ["uwsgi", "--ini", "/opt/mailman-web/uwsgi.ini", "--check-static", "/opt/mailman-web-data"]
```
- Définir l'interface réseau d'écoute du service web en ajustant les `ports` du conteneur
```yaml
ports:
- "192.168.1.2:8000:8000" # HTTP (on suppose que l'adresse LAN de l'hôte est 192.168.1.2)
- "127.0.0.1:8080:8080" # uwsgi (reste en écoute sur l'interface loopback)
```
3. Créer les répertoires qui serviront de volumes aux containers
```bash
mkdir -p /opt/mailman/mailman/core /opt/mailman/mailman/web
chown root: /opt/mailman/mailman/core /opt/mailman/mailman/web
chmod 755 /opt/mailman/mailman/core /opt/mailman/mailman/web
```
#### Exemple de configuration du service `mailman-core`
```yaml
mailman-core:
image: maxking/mailman-core:0.4
restart: always
container_name: mailman-core
hostname: mailman-core
volumes:
- /opt/mailman/mailman/core:/opt/mailman/
stop_grace_period: 30s
environment:
- MTA=postfix
- SMTP_HOST=smtp.example.com
- SMTP_PORT=25
- DATABASE_URL=postgresql://user:password@database_host/database
- DATABASE_TYPE=postgres
- DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
- HYPERKITTY_API_KEY=1+wZYpHz0d9F+rItSSWuwby09R04ZLm19xONOdutzsJc/irGaWnuhO4NTIKTicEC57CG0+QsjHbf/YbNsBZhsA==
ports:
- "127.0.0.1:8001:8001" # API
- "127.0.0.1:8024:8024" # LMTP - incoming emails
networks:
mailman:
```
#### Exemple de configuration du service `mailman-web`
```yaml
mailman-web:
image: maxking/mailman-web:0.4
restart: always
container_name: mailman-web
hostname: mailman-web
links:
- mailman-core:mailman-core
volumes:
- /opt/mailman3/mailman/web:/opt/mailman-web-data
environment:
- SMTP_HOST=smtp.example.com
- SMTP_PORT=25
- DJANGO_ALLOWED_HOSTS=lists.example.com
- DATABASE_TYPE=postgres
- DATABASE_URL=postgresql://user:password@database_host/database
- SERVE_FROM_DOMAIN=lists.example.com
- MAILMAN_ADMIN_USER=admin
- SECRET_KEY=ArtYpfQ7pfcekjA3+uv0xG0n6QlXXQ0Ywk1cP5Pks3R7WIGovBdWiSZ10aDhpjbS3h4GVUX4is/Do0b90Rkx7w==
- MAILMAN_ADMIN_EMAIL=admin@exampple.com
- HYPERKITTY_API_KEY=1+wZYpHz0d9F+rItSSWuwby09R04ZLm19xONOdutzsJc/irGaWnuhO4NTIKTicEC57CG0+QsjHbf/YbNsBZhsA==
ports:
- "192.168.1.2:8000:8000" # HTTP
- "127.0.0.1:8080:8080" # uwsgi
command: ["uwsgi", "--ini", "/opt/mailman-web/uwsgi.ini", "--check-static", "/opt/mailman-web-data"]
networks:
mailman:
```
### Démarrage des containers
- Démarrer les containers à l'aide la commande suivante:
```bash
docker-compose up -d
```
**Note**:
- La création d'un service système permettant le redémarrage du conteneur est laissé au bon soin de l'administrateur du système :)
- Les conteneurs prennent un certains temps pour démarrer, notamment la première fois.
- L'interface d'administration des listes sera accessible sur l'adresse *IP* définie dans les ports du service `mailman-web` (`192.168.1.2`).
### Trouble shooting
Les logs sont accessibles à l'aide de la commande suivante:
```bash
docker-compose logs
```
Pour voir les logs défiler en direct, utiliser l'option `-f`
```bash
docker-compose logs -f
```
### Documentation officielle et références
- [https://github.com/maxking/docker-mailman](https://github.com/maxking/docker-mailman)
- [https://docs.mailman3.org/en/latest/](https://docs.mailman3.org/en/latest/)
## Configuration du serveur mandataire inverse (*reverse-proxy*)
Le service proposé par les conteneurs ne propose pas de chiffrement *SSL/TLS*. Un serveur mandataire inverse est donc nécesaire pour accéder au service via *https*.
Le serveur mandataire n'a pas nécessité à être installé sur l'hôte hébergeant les conteneurs.
Le fichier de configuration d'un hôte virtuel *Apache* est fourni tel quel. À vous de l'adapter à votre cas.
À noter que `192.168.1.1` est l'adresse *IP* du serveur mandataire inverse pas celle de l'hôte hébergeant les conteneurs qui est défini par la variable `BACKEND_HOST`.
```apache
<VirtualHost 192.168.1.1:80>
# ReverseProxy with https redirect template
# Written by Doug Le Tough
# ######################
Define FQDN lists.example.com
Define BACKEND_HOST mailman-backend.local
Define BACKEND_PORT 8000
ServerName ${FQDN}
### All HTTP requests are converted to HTTPS requests
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule (.*) https://%{HTTP_HOST}%{REQUEST_URI}
</IfModule>
ErrorLog "/var/log/httpd/${FQDN}_error.log"
CustomLog "/var/log/httpd/${FQDN}_access.log" Combined
</VirtualHost>
<VirtualHost 192.168.1.1:443>
Header always set Strict-Transport-Security "max-age=63072000; includeSubDomains"
ServerName ${FQDN}
ProxyPreserveHost On
SSLEngine on
SSLCertificateFile /etc/dehydrated/certs/${FQDN}/cert.pem
SSLCertificateKeyFile /etc/dehydrated/certs/${FQDN}/privkey.pem
SSLCertificateChainFile /etc/dehydrated/certs/${FQDN}/fullchain.pem
RequestHeader set X_FORWARDED_PROTO 'https'
ProxyPass / http://${BACKEND_HOST}:${BACKEND_PORT}/
ProxyPassReverse / http://${BACKEND_HOST}:${BACKEND_PORT}/
ErrorLog "/var/log/httpd/${FQDN}_error.log"
CustomLog "/var/log/httpd/${FQDN}_access.log" Combined
</VirtualHost>
```
### Configuration de *Postfix*
1. Modifier le fichier de configuration principale de *Postfix* (`/etc/postfix/main.cf`) de manière à
- prendre en charge le réseau des containers (`172.19.199.0/24`)
```postfix
mynetworks = 172.19.199.0/24, 127.0.0.0/8, 192.168.1.0/24, <Les autres réseaux supportés par l'instance postfix>
```
- prendre en charge la liste des domaines et adresse de destinations des listes confiugurée dans *Mailman3*
```postfix
transport_maps =
regexp:/opt/mailman/mailman/core/var/data/postfix_lmtp
local_recipient_maps =
regexp:/opt/mailman/mailman/core/var/data/postfix_lmtp
relay_domains =
regexp:/opt/mailman/mailman/core/var/data/postfix_domains
```
- Redémarrer le service *Postfix* pour prendre en compte les modifications.
## Export, création et import des listes et utilisateurs
1. Se connecter via *SSH* sur l'hôte hébergrant *Mailman2* et exporter la liste des utilisateurs pour chacune des listes à l'aide du script suivant
```bash
for LIST in $(list_lists | awk '{print $1}' | sed -e 1d); do
echo $LIST;
list_members $LIST > ${LIST}.txt
done
```
Un fichier texte contenant la liste des utilisateurs sera créé dansle répertoire courant pour chacune des listes définies dans *Mailman2*.
2. Accéder à l'interface d'administration *web* de *Mailman3* à l'aide de l'URL définie sur le serveur mandataire inverse.
- Pour chacune des listes dont le nom s'est affiché à l'étape précédante:
- Créer et configurer une liste du même nom
- Dans `Paramètres / Atténuations DMARC`:
- Bien vérifier que `Atténuation DMARC inconditionnelle` est à `oui`
- Dans `Opérations goupées / Abonnement en masse`:
- Copier la liste des utilisateurs dans le champs `Adresses de courriel à inscrire en nombre`
- Cocher `Pré-confirmé`, `Pré-approuvées` et `Pré-vérifiées` pour ne pas obliger les utilisateur à confirmer la création de leur compte
- Décocher `Invitation`
- Sélectionner `Non` à `Envoyer un message d'accueil` pour ne pas spammer les utilisateurs avec un courriel de bienvenue.
- Cliquer sur `Subscribe users`