Mailman3 kasutamine PostgreSQL, Postfix, Docker ja operatsioonisüsteemiga Debian
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
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>