Mailman3 kasutamine PostgreSQL, Postfix, Docker ja operatsioonisüsteemiga Debian

Allikas: Imre kasutab arvutit
Mine navigeerimisribaleMine otsikasti

Sissejuhatus

Käesolev teksti kirjeldab Mailman3 lahenduse kasutamist PostgreSQL, Postfix ja operatsioonisüsteemi Debian põhisel dockerhostil.

Tööpõhimõte

Mailman3 lahenduse suurt pilti kujutab selline joonis

                    internet
             
                       |               nginx http frontend       väline smtp relee           dh-mailman3
                       |             https://lists.moraal.ee/         postfix
                       |  tulemüür                                                                        
                    ___|___                  _______                  _______                  _______   mailman-core
                   |       |                |       |                |       |                |       |  mailman-web
                   |       |                |       |                |       |                |       |  postfix
                   |_______|                |_______|                |_______|                |_______|
                       |                        |                        |                        |
                       |                        |                        |                        |
                -------|------------------------|------------------------|------------------------|--------

kus

  • nginx http frontend - brauser pöördub mailman3 poole (nt mailman3 haldaja, listi liige loeb arhiivi)
  • väline smtp relee - interneti postimasinad saadavab kirju sisse, mailman3 saadab kirju välja

Mailman3 sisemine tööjaotus

  • mailman3 koosneb kahest suuremast komponendist - mailman-core ja mailman-web
  • mailman-core tegeleb nö smtp protokolli teemadega (nt tegeleb listi saabunud kirja remailimisega)
  • mailman-web tegeleb nö http protokolli teemadega (nt teenindab haldaja tegevusi webgui haldusliidese kaudu)
  • mailmam-core ja -web suhtlevad omavahel üle api liidese
  • https://docs.mailman3.org/en/latest/architecture.html

dh-mailman dockerhostis töötavad protsessid

  • dh enda peal - postfix
  • konteiner 1 - postgresql andmebaas
  • konteiner 2 - mailman-core
  • konteiner 3 - mailman-web

Dockerhost - konteinerid

Töötav süsteem

root@dh-mm3:~# docker compose ls
NAME                STATUS              CONFIG FILES
dc                  running(3)          /srv/mm3/dc/docker-compose-mm3.yaml

ja konteinerid

root@dh-mm3:~# docker ps
CONTAINER ID   IMAGE                      COMMAND                  CREATED       STATUS                 PORTS                                                                   NAMES
6a1c3671a779   maxking/mailman-web:0.4    "docker-entrypoint.s…"   5 weeks ago   Up 5 weeks             0.0.0.0:8000->8000/tcp, [::]:8000->8000/tcp, 127.0.0.1:8080->8080/tcp   mailman-web
569e0068374f   maxking/mailman-core:0.4   "docker-entrypoint.s…"   5 weeks ago   Up 5 weeks             127.0.0.1:8001->8001/tcp, 127.0.0.1:8024->8024/tcp                      mailman-core
61558e0fd1cf   postgres:12-alpine         "docker-entrypoint.s…"   5 weeks ago   Up 5 weeks (healthy)   5432/tcp                                                                dc-database-1

Käsundamine, tundub, et lahendus elab ilusti üle 'stop ja start' ning 'down ja up', nt

root@dh-mm3:~# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml down
[+] Running 4/4
 ✔ Container mailman-web    Removed                                                                                                                                                                                                     1.5s 
 ✔ Container mailman-core   Removed                                                                                                                                                                                                     2.2s 
 ✔ Container dc-database-1  Removed                                                                                                                                                                                                     0.5s 
 ✔ Network dc_mailman       Removed                                                                                                                                                                                                     0.2s 

root@dh-mm3:~# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml up -d
[+] Running 4/4
 ✔ Network dc_mailman       Created                                                                                                                                                                                                     0.0s 
 ✔ Container dc-database-1  Healthy                                                                                                                                                                                                    11.6s 
 ✔ Container mailman-core   Started                                                                                                                                                                                                    11.1s 
 ✔ Container mailman-web    Started        


Dockerhost - postfix

Dockerhost postfix protsessil on äärmiselt oluline ülesanne - ta kinnitub dünaamiliselt moodustatud transport/domains/recipients osakonna külge

# cat /etc/postfix/main.cf
...

transport_maps =
    regexp:/opt/mailman/core/var/data/postfix_lmtp
local_recipient_maps =
    regexp:/opt/mailman/core/var/data/postfix_lmtp
relay_domains =
    regexp:/opt/mailman/core/var/data/postfix_domains

kus nt

root@dh-mm3:/opt# cat /opt/mailman/core/var/data/postfix_lmtp 
# AUTOMATICALLY GENERATED BY MAILMAN ON 2025-05-11 10:17:24
#
# This file is generated by Mailman, and is kept in sync with the binary hash
# file.  YOU SHOULD NOT MANUALLY EDIT THIS FILE unless you know what you're
# doing, and can keep the two files properly in sync.  If you screw it up,
# you're on your own.
    
# Aliases which are visible only in the @lists.moraal.ee domain.
/^aktiiv@lists\.moraal\.ee$/                  lmtp:[10.19.199.3]:8024
/^aktiiv-bounces(\+.*)?@lists\.moraal\.ee$/   lmtp:[10.19.199.3]:8024
/^aktiiv-confirm(\+.*)?@lists\.moraal\.ee$/   lmtp:[10.19.199.3]:8024
/^aktiiv-join@lists\.moraal\.ee$/             lmtp:[10.19.199.3]:8024
/^aktiiv-leave@lists\.moraal\.ee$/            lmtp:[10.19.199.3]:8024
/^aktiiv-owner@lists\.moraal\.ee$/            lmtp:[10.19.199.3]:8024
/^aktiiv-request@lists\.moraal\.ee$/          lmtp:[10.19.199.3]:8024
/^aktiiv-subscribe@lists\.moraal\.ee$/        lmtp:[10.19.199.3]:8024
/^aktiiv-unsubscribe@lists\.moraal\.ee$/      lmtp:[10.19.199.3]:8024

kus

  • 10.19.199.3 on konteineri ip aadress, see on dünaamiline (postfix saab konteinerite tekkimisel käigult sellest õigesti aadressist teada) - kui vahel postfix ei saa kirjaldest lahti siis maksab teha postfixile reload

Võrk

Docker compose tekitab oma võrgu dc_mailman

root@dh-mm3:~# docker network ls
NETWORK ID     NAME         DRIVER    SCOPE
f42bb4849b5d   bridge       bridge    local
13e2d239b91c   dc_mailman   bridge    local
3568663fc123   host         host      local
b868a3ebef76   none         null      local

Mount volumes

Mount volume'id puuduvad (kõik on nn bind volumeid)

root@dh-mm3:~# docker volume ls
DRIVER    VOLUME NAME
root@dh-mm3:~# 

Andmebaas

oot@dh-mm3:~# docker exec -it dc-database-1 bash
61558e0fd1cf:/# psql -U mailman mailmandb
psql (12.22)
Type "help" for help.

mailmandb=# \l+
                                                                 List of databases
   Name    |  Owner  | Encoding |  Collate   |   Ctype    |  Access privileges  |  Size   | Tablespace |                Description                 
-----------+---------+----------+------------+------------+---------------------+---------+------------+--------------------------------------------
 mailmandb | mailman | UTF8     | en_US.utf8 | en_US.utf8 |                     | 13 MB   | pg_default | 
 postgres  | mailman | UTF8     | en_US.utf8 | en_US.utf8 |                     | 8001 kB | pg_default | default administrative connection database
 template0 | mailman | UTF8     | en_US.utf8 | en_US.utf8 | =c/mailman         +| 7857 kB | pg_default | unmodifiable empty database
           |         |          |            |            | mailman=CTc/mailman |         |            | 
 template1 | mailman | UTF8     | en_US.utf8 | en_US.utf8 | =c/mailman         +| 7857 kB | pg_default | default template for new databases
           |         |          |            |            | mailman=CTc/mailman |         |            | 
(4 rows)

mailmandb=# \c mailmandb
You are now connected to database "mailmandb" as user "mailman".
mailmandb=# \dt+
                                    List of relations
 Schema |               Name                | Type  |  Owner  |    Size    | Description 
--------+-----------------------------------+-------+---------+------------+-------------
 public | _request                          | table | mailman | 16 kB      | 
 public | acceptablealias                   | table | mailman | 8192 bytes | 
 public | account_emailaddress              | table | mailman | 8192 bytes | 
 public | account_emailconfirmation         | table | mailman | 0 bytes    | 
 public | address                           | table | mailman | 16 kB      | 
 public | alembic_version                   | table | mailman | 8192 bytes | 
 public | auth_group                        | table | mailman | 0 bytes    | 
 public | auth_group_permissions            | table | mailman | 0 bytes    | 
 public | auth_permission                   | table | mailman | 40 kB      | 
 public | auth_user                         | table | mailman | 16 kB      | 
 public | auth_user_groups                  | table | mailman | 0 bytes    | 
 public | auth_user_user_permissions        | table | mailman | 0 bytes    | 
 public | autoresponserecord                | table | mailman | 8192 bytes | 
 public | ban                               | table | mailman | 8192 bytes | 
...

Logid

root@dh-mm3:~# find /opt/mailman/ -mmin -5 -name \*log -ls
   262280   1164 -rw-rw----   1 messagebus 65533     1190473 May 10 21:56 /opt/mailman/core/var/logs/mailman.log
   262282   2116 -rw-rw----   1 messagebus 65533     2163695 May 10 21:55 /opt/mailman/core/var/logs/smtp.log
   264082  27776 -rw-r-----   1 messagebus crontab  28442324 May 10 21:55 /opt/mailman/web/logs/uwsgi-error.log
   264083      4 -rw-r-----   1 messagebus crontab      1261 May 10 21:55 /opt/mailman/web/logs/uwsgi-qcluster.log
   264084   1236 -rw-r--r--   1 messagebus crontab   1265623 May 10 21:56 /opt/mailman/web/logs/uwsgi.log
   264081   1208 -rw-r-----   1 messagebus crontab   1236271 May 10 21:55 /opt/mailman/web/logs/uwsgi-cron.log

Docker põhise mailman3 lahenduse ettevalmistamine

Dockerhost

  • Debian v. 12
  • Docker CE

Dockerhost failisüsteemid

root@dh-mm3:~# df -t ext4 -T -h
Filesystem                      Type  Size  Used Avail Use% Mounted on
/dev/mapper/system-root         ext4  7.3G  5.4G  1.5G  79% /
/dev/mapper/data-opt            ext4  5.9G  322M  5.2G   6% /opt
/dev/mapper/data-var_lib_docker ext4   16G  4.0G   11G  27% /var/lib/docker

Välised abistavad komponendid

  • tulemüür
  • väline smtp relee (mis võtab internetist kirju vastu ja saadab kirju internetti edasi)
  • väline http proxy

Docker põhise mailman3 lahenduse käivitamine

Docker compose

root@dh-mm3:~# cat /srv/mm3/dc/docker-compose-mm3.yaml 
services:
  mailman-core:
    image: maxking/mailman-core:0.5.2 # Use a specific version tag (tag latest is not published)
    container_name: mailman-core
    hostname: mailman-core
    restart: unless-stopped
    volumes:
    - /opt/mailman/core:/opt/mailman/
    stop_grace_period: 30s
    links:
    - database:database
    depends_on:
      database:
        condition: service_healthy
    environment:
    - DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
    - DATABASE_TYPE=postgres
    - DATABASE_CLASS=mailman.database.postgresql.PostgreSQLDatabase
    - HYPERKITTY_API_KEY=someapikey
    - SMTP_HOST=192.168.1.250
    - SMTP_PORT=25
    - MTA=postfix
    ports:
    - "127.0.0.1:8001:8001" # API
    - "127.0.0.1:8024:8024" # LMTP - incoming emails
    networks:
      mailman:

  mailman-web:
    image: maxking/mailman-web:0.5.2 # Use a specific version tag (tag latest is not published)
    container_name: mailman-web
    hostname: mailman-web
    restart: unless-stopped
    depends_on:
      database:
        condition: service_healthy
    links:
    - mailman-core:mailman-core
    - database:database
    volumes:
    - /opt/mailman/web:/opt/mailman-web-data
    environment:
    - DATABASE_TYPE=postgres
    - DATABASE_URL=postgresql://mailman:mailmanpass@database/mailmandb
    - HYPERKITTY_API_KEY=someapikey
    - SERVE_FROM_DOMAIN=lists.moraal.ee
    - MAILMAN_ADMIN_USER=admin
    - MAILMAN_ADMIN_EMAIL=imre@auul.pri.ee
    - SECRET_KEY=salajanevoti
    - UWSGI_STATIC_MAP=/static=/opt/mailman-web-data/static
    - SMTP_HOST=192.168.1.250
    - SMTP_PORT=25
    ports:
    - "8000:8000" # HTTP
    - "127.0.0.1:8080:8080" # uwsgi
    networks:
      mailman:

  database:
    restart: unless-stopped
    environment:
    - POSTGRES_DB=mailmandb
    - POSTGRES_USER=mailman
    - POSTGRES_PASSWORD=mailmanpass
    image: postgres:16-alpine
    volumes:
    - /opt/mailman/database:/var/lib/postgresql/data
    healthcheck:
      test: ["CMD-SHELL", "pg_isready --dbname mailmandb --username mailman"]
      interval: 10s
      timeout: 5s
      retries: 5
    networks:
      mailman:

networks:
  mailman:
    driver: bridge
    ipam:
      driver: default
      config:
      -
        subnet: 10.19.199.0/24

kus

  • lähtepunktiks on kasutatud docker-compose.yaml aadressilt https://github.com/maxking/docker-mailman/blob/main/docker-compose.yaml
  • image - kasutatakse mailman tõmmise versioon 0.5.2
  • image - kasutatakse postgresql tõmmise versiooni 16 (millegipärast postgresql v. 17 annab vigu)
  • database juurde on lisatud 'restart: unless-stopped'
  • mailman-web juurde on lisatud samuti SMTP_HOST ja SMTP_PORT keskkonnamuutujad

Persistent andmete jaoks tekitatakse kataloogid

# cd /opt
# mkdir -p mailman/core mailman/web mailman/database

Paigaldise lähtestamine

# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml down
# cd /opt
# rm -rf mailman/core/* mailman/web/* mailman/database/*
# docker compose -f /srv/mm3/dc/docker-compose-mm3.yaml up -d

Django admin liides

Aadressil https://lists.moraal.ee/admin asub Django stiilis admin liides, seal saab muu hulgas hallata mailman-web osakonna kasutajaid

20250511-mm3-django-01.png

kus

  • TODO

Selleks, et usaldada nt konkreetse listi haldamist kellelegi tuleb talle teha nö django keskkonnas kasutaja.

mailman-web kasutaja tekitamiks tuleb /admin liideses liikuda vastakus paneeli Users, seejärel paremal üleval pressida 'add user' ning täita vorm. Seejärel lisada eposti aadress vasakul paneelis Accounts -> Email addresses.

Väline smtp proxy

Postfix

root@post-relay:/etc/postfix# egrep "^transport_maps|^virtual_mailbox_maps" main.cf
virtual_mailbox_maps = ldap:/etc/postfix/virtual_mailbox_maps.ldap, hash:/etc/postfix/virtual_mailbox_maps.txt
transport_maps = hash:/etc/postfix/transport_maps.txt

transport maps

root@post-relay:/etc/postfix# tail -n 1 transport_maps.txt
lists.moraal.ee :[192.168.1.29]

ning virtual_mailbox_maps

root@post-relay:/etc/postfix# tail -n 2 virtual_mailbox_maps.txt
kyla@lists.moraal.ee x
aktiiv@lists.moraal.ee x

Väline http proxy

Kasutades nginx tarkvara välise proksina sobib selline lõik

..

server {
    listen 80;
    server_name lists.moraal.ee;
    root /var/www/html;

    if ($request_uri !~ /.well-known) {
      return 302 https://lists.moraal.ee/;
    }
}

...

server {
    listen 443;
    server_name lists.moraal.ee;
    ssl on;
    ssl_certificate /etc/letsencrypt/live/lists.moraal.ee/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/lists.moraal.ee/privkey.pem;
    ssl_session_timeout 5m;
    ssl_session_cache shared:SSL:10m;
    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_prefer_server_ciphers on;
    ssl_ciphers AES256+EECDH:AES256+EDH:!aNULL;
    ssl_dhparam /etc/nginx/serdid/dhparam.pem;
    client_max_body_size 25m;

    ssl_stapling on;
    ssl_stapling_verify on;
    resolver 10.192.0.53 valid=300s;
    resolver_timeout 10s;

    access_log /var/log/nginx/access-lists.moraal.ee-443.log http_logi;

#    location /accounts/signup/ {
#      return 403;
#    }

    location / {
      proxy_set_header Host $http_host;
      proxy_set_header X-Real-IP $remote_addr;
      proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
      proxy_set_header X-Forwarded-Proto $scheme;
      proxy_pass http://192.168.1.29:8000;
      proxy_connect_timeout       900;
      proxy_send_timeout          900;
      proxy_read_timeout          900;
      send_timeout                900;
    }
}

Mailman3 kasutamine

Esmakordseks sisselogimiseks sobib lähtuda docker-compose.yaml failid esitatud andmetest

..
   - MAILMAN_ADMIN_USER=admin
   - MAILMAN_ADMIN_EMAIL=imre@auul.pri.ee
...

ja minna webgui lehele, presside Sign-In ja Forgot your password, ning näidata admin kasutaja eposti aadress. Seejärel vaadata dockerhost sabast

root@dh-mm3:/opt# mailq
-Queue ID-  --Size-- ----Arrival Time---- -Sender/Recipient-------
EB8414CBAB*     985 Sat May 10 23:02:36  postorius@lists.moraal.ee
                                         imre@auul.pri.ee

-- 0 Kbytes in 1 Request.

ning küsida sabas oleva kirja sisu

root@dh-mm3:/opt# postcat -q EB8414CBAB
..
Subject: [lists.moraal.ee] Password Reset Email
From: postorius@lists.moraal.ee
To: imre@auul.pri.ee
Date: Sat, 10 May 2025 20:02:36 -0000
Message-ID: <174690735695.408.10898178246709869715@mailman-web>

Hello from lists.moraal.ee!

You're receiving this email because you or someone else has requested a password reset for your user account.
It can be safely ignored if you did not request a password reset. Click the link below to reset your password.

https://lists.moraal.ee/accounts/password/reset/key/1-cplroc-bb94dfb5f3a93ff204bd69664014c775/

In case you forgot, your username is admin.
...

Seejärel saadetakse üks confirmation kiri, sellega talitada sarnaselt ja saabki webgui peale admin kasutajaga logida sisse.

Uue listi domeeni lisamine

Valitakse webgui liideses

Domains -> Add New Domain

ning täidetakse lahtrid

  • Mail Host - lists.moraal.ee
  • Description -
  • Alias Domain - tühi
  • Web Host - TODO

Uue listi lisamine

Uue listi lisamiseks webgui pealt avatakse

Lists -> Create New List

ning täidetakse lahtrid

  • List Name - test-1-listinimi
  • Mail Host - lists.moraal.ee
  • Initial list owner address - imre@auul.pri.ee
  • Advertise this list -
  • List Style - Ordinary
  • Short Description -

Seejärel dmarc-dkim kvaliteedi tõstmiseks muudetakse Template'i

Listi nimi -> Templates -> New Template

ning valitakse

  • Name - [list:member:regular:footer] - The footer for a regular (non-digest) message.
  • Data - tühi

Seejärel Settings muudetakse

  • Subject prefix - tühi

Message Acceptance -> Message Size - 20000 kB

Ning listi eemaldamine avalikust nimekirjast

Settings -> List Identity -> Show list on index page - No

Avaliku arhiivi väljalülitus

Settings -> Archiving -> Archive Policy - Private archives

Listi liikmete haldamine

Listi liikmete haldamiseks valitakse

Mass operations -> Mass subscriptions

ning täita lahtrid

  • Emails to mass subscribe - esitada rea kaupa listi liikmete eposti aadressid
  • Pre confirm - linnutada
  • Pre approved - linnutada
  • Pre verified - linnutada
  • Send welcome message - No

Sellisel viisil toimetades ei kaasne listi liikme jaoks mingeid teavitusi ega vajadust midagi kinnitada. St järgmisena saab asuda listi kasutama, st saab osa listi saadetud kirjadest.

Listile custom omaniku tekitamine

  • moodustada django /admin keskkonnas kasutaja - vt ülevalt poolt punkt 'Django admin liides'
  • seostada mailman-web keskkonnas kasutaja konkreetse listiga

Listi kirja omadused

Listi poolt edasi toimetatud kirjedel paistavad lõppkasutaja st listi liikme postkastis muu hulgas sellised listindusele iseloomulikud päised

X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header
X-Mailman-Version: 3.3.10
Precedence: list
List-Id: Küla <kyla.lists.moraal.ee>
Archived-At: <https://lists.moraal.ee/hyperkitty/list/kyla@lists.moraal.ee/message/HVW3GLLEQ7WWXXRTOLWI65ZAWL5ADTXT/>
List-Archive: <https://lists.moraal.ee/hyperkitty/list/kyla@lists.moraal.ee/>
List-Help: <mailto:kyla-request@lists.moraal.ee?subject=help>
List-Owner: <mailto:kyla-owner@lists.moraal.ee>
List-Post: <mailto:kyla@lists.moraal.ee>
List-Subscribe: <mailto:kyla-join@lists.moraal.ee>
List-Unsubscribe: <mailto:kyla-leave@lists.moraal.ee>

Kasulikud lisamaterjalid