Skip to main content

Mailman



Introdução


Mailman é um software livre e de código aberto utilizado para o gerenciamento de listas de discussões por e-mail. Com ele podemos assinar e participem de listas de discussões por e-mail. O Mailman é usado por muitas organizações, empresas e comunidades online para facilitar a comunicação entre membros e para fornecer uma maneira fácil de gerenciar grandes listas de e-mails. Ele foi desenvolvido em 1998 pelo programador Barry Warsaw e é mantido atualmente pela Free Software Foundation.


O Mailman é distribuído sob a GNU General Public License e escrito na linguagem de programação Python versão 3 após o Mailman versão 2.



Mailman Suite versos Core


O Mailman Suite e o Mailman Core são duas variantes diferentes do software Mailman. O Mailman Core é a versão principal do software, que fornece as funcionalidades básicas de gerenciamento de lista de discussão por e-mail, como: inscrição/desinscrição de membros, moderação de mensagens e gerenciamento de arquivos anexos.


Já o Mailman Suite é uma solução mais completa, mas que também inclui o Mailman Core, juntamente com outras ferramentas complementares, como um servidor web integrado, um gateway de arquivamento, suporte para autenticação do usuário e recursos de gerenciamento de banco de dados. É uma solução de lista de discussão mais completa, que inclui recursos adicionais para gerenciamento e personalização de listas de discussão.



Antes de começar


Para essa doc vou usar o domínio hermodr.com.br, esse também será o nome do servidor e será o nome acessível pela Web.



Instalando Let's Encrypt


Vamos usar a Let's encrypt para gerar os certificados:

# Instale o CertBot:
sudo apt install certbot -y

Gere o certificado:

sudo certbot certonly --standalone --keep --reuse-key
.
.
.
Successfully received certificate.
Certificate is saved at: /etc/letsencrypt/live/hermodr.com.br/fullchain.pem
Key is saved at: /etc/letsencrypt/live/hermodr.com.br/privkey.pem
This certificate expires on 2023-05-18.
These files will be updated when the certificate renews.
Certbot has set up a scheduled task to automatically renew this certificate in the background.

- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
If you like Certbot, please consider supporting our work by:
* Donating to ISRG / Let's Encrypt: https://letsencrypt.org/donate
* Donating to EFF: https://eff.org/donate-le
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -


Instalando as dependências e Banco de dados


Vamos instalar o Mailman Core versão 3. Existem algumas formas de instalar o Mailman 3, vou optar pela Instalação com Virtualenv, para que assim ele fique isolado.

# Instale as dependecias:
$ sudo apt install python3-dev python3-venv sassc lynx build-essential -y

# Instalar banco de dados:
$ sudo apt install postgresql libpq-dev -y

Agora vamos configurar o banco de dados:

# Execute comando "psql" com o usuário "postgres" com privilégios de superusuário:
$ sudo -u postgres psql
could not change directory to "/home/vagrant": Permission denied
psql (14.5 (Ubuntu 14.5-0ubuntu0.22.04.1))
Type "help" for help.

### Crie o banco de dados 'mailman':
postgres=# create database mailman;
CREATE DATABASE

### Crie o banco de dados 'mailmanweb':
postgres=# create database mailmanweb;
CREATE DATABASE

### Crie o usuário para acessar os bancos de dados:
postgres=# create user mailman with encrypted password 'SENHA-User-postgres';
CREATE ROLE

### Dê permissão tatal para o usuário no banco 'mailman':
postgres=# grant all privileges on database mailman to mailman;
GRANT

### Dê permissão tatal para o usuário no banco 'mailmanweb':
postgres=# grant all privileges on database mailmanweb to mailman;
GRANT

### Saia do postgres:
postgres=# \q

Nós criamos duas bases de dados com os nomes mailman e mailmanweb para o Mailman Core e o Mailman Web (Django), respectivamente. Também criamos um novo usuário chamado mailman e concedemos a ele privilégios para ambas as bases de dados.


Se você tiver que mudar a senha no Postgresql pode usar o comando abaixo:

ALTER USER mailman with password 'SENHA';

Vamos criar o usuário no Linux para usar o Mailman:

# Crie o usuário mudando o local do diretório Home dele:
sudo useradd -m -d /opt/mailman -s /usr/bin/bash mailman

# Acerte as permissões:
sudo chown mailman:mailman /opt/mailman
sudo chmod 755 /opt/mailman

# Logue com o usuário:
sudo su - mailman

Vamos criar o virtualenv para rodar o mailman na Home do usuário mailman:

# Crie um ambiente virtual Python chamado 'venv':
python3 -m venv venv

# Ative o virtualenv:
source /opt/mailman/venv/bin/activate

# Agora vamos configurar para sempre ativar o ambiente virtual ao logar com o usuário:
echo 'source /opt/mailman/venv/bin/activate' >> /opt/mailman/.bashrc


Instalando o Mailman 3


O Mailman Core é responsável por enviar e receber e-mails. Ele expõe uma API REST que os clientes podem usar para interagir por meio do protocolo HTTP. A API em si é uma API administrativa e é recomendado que você não a exponha para fora do seu host ou rede confiável.


Para instalar o Mailman Core:

# Logue com o usuário 'mailman' caso não esteja:
sudo su - mailman

# Instale o Mailman juntamente com algumas dependências:
pip3 install wheel mailman psycopg2-binary\<2.9

Isso irá instalar a última versão do Mailman Core e as bibliotecas do Python para o banco de dados Postgresql.

Atualmente, o Django 2.2 ou superior, mas inferior a versão 3.1 requer o psycopg2-binary inferior a versão 2.9. Veja aqui esse problema. Versões posteriores do Django funcionarão com psycopg2-binary 2.9.x.

Agora crie um arquivo de configuração para o Mailman Core:

# Crie a pasta:
sudo mkdir /etc/mailman3

#### Crie o arquivo abaixo (não esqueça de mudar a senha em 'SENHA-User-postgres' e o domínio):
sudo vim /etc/mailman3/mailman.cfg


####### Cole a saída abaixo #######
[paths.here]
var_dir: /opt/mailman/mm/var

[mailman]
layout: here
# 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@hermodr.com.br

[database]
class: mailman.database.postgresql.PostgreSQLDatabase
url: postgresql://mailman:SENHA-User-postgres@localhost/mailman

[archiver.prototype]
enable: yes

# For the HyperKitty archiver.
[archiver.hyperkitty]
class: mailman_hyperkitty.Archiver
enable: yes
configuration: /opt/mailman/mm/mailman-hyperkitty.cfg
# And, create the /opt/mailman/mm/mailman-hyperkitty.cfg file containing
# these settings uncommented
#[general]
#base_url: http://127.0.0.1:8000/archives/
#api_key: Secret_Hyperkitty_API_Key

[shell]
history_file: $var_dir/history.py

[mta]
verp_confirmations: yes
verp_personalized_deliveries: yes
verp_delivery_interval: 1


Configurando serviço


Vamos criar uma serviço do Mailman no SystemD para podermos gerenciar com systemctl e podermos colocar para subir no boot do sistema.

# Crie o arquivo abaixo:
sudo vim /etc/systemd/system/mailman3.service

####### Cole a saída abaixo #######
[Unit]
Description=GNU Mailing List Manager
After=syslog.target network.target postgresql.service

[Service]
Type=forking
PIDFile=/opt/mailman/mm/var/master.pid
User=mailman
Group=mailman
ExecStart=/opt/mailman/venv/bin/mailman start
ExecReload=/opt/mailman/venv/bin/mailman restart
ExecStop=/opt/mailman/venv/bin/mailman stop

[Install]
WantedBy=multi-user.target


Configurando Crontab


Configure o Crontab para o usuário mailman:

# Entre no crontab do user mailman:
sudo -u mailman crontab -e

####### Cole a saída abaixo #######
@daily /opt/mailman/venv/bin/mailman digests --periodic
@daily /opt/mailman/venv/bin/mailman notify
* * * * * /opt/mailman/venv/bin/mailman-web runjobs minutely
0,15,30,45 * * * * /opt/mailman/venv/bin/mailman-web runjobs quarter_hourly
@hourly /opt/mailman/venv/bin/mailman-web runjobs hourly
@daily /opt/mailman/venv/bin/mailman-web runjobs daily
@weekly /opt/mailman/venv/bin/mailman-web runjobs weekly
@monthly /opt/mailman/venv/bin/mailman-web runjobs monthly
@yearly /opt/mailman/venv/bin/mailman-web runjobs yearly


Instale a Interface Web


Vamos instalar a interface Web para acesso as listas e página de administração.

# Logue com o usuário 'mailman':
sudo su - mailman

# Instale os pacotes necessários:
pip install mailman-web mailman-hyperkitty

Agora vamos configura:

# Crie os diretórios abaixo:
sudo mkdir -p /opt/mailman/web/static
sudo mkdir /opt/mailman/web/logs

# Acerte as permissões:
sudo chown -R mailman:mailman /opt/mailman
sudo chmod 755 /opt/mailman

# Crie o arquivo abaixo (não se esqueça de mudar 'SENHA-User-postgres' e o domínio):
sudo vim /etc/mailman3/settings.py


####### Cole a saída abaixo #######
# Mailman Web configuration file.
# /etc/mailman3/settings.py

from mailman_web.settings.base import *
from mailman_web.settings.mailman import *


#: Default list of admins who receive the emails from error logging.
ADMINS = (
('Mailman Suite Admin', 'root@localhost'),
)

# Postgresql database setup.
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'mailmanweb',
'USER': 'mailman',
# TODO: Replace this with the password.
'PASSWORD': 'SENHA-User-postgres',
'HOST': 'localhost',
'PORT': '5432',
}
}

# 'collectstatic' command will copy all the static files here.
# Alias this location from your webserver to `/static`
STATIC_ROOT = '/opt/mailman/web/static'

# enable the 'compress' command.
COMPRESS_ENABLED = True

# Make sure that this directory is created or Django will fail on start.
LOGGING['handlers']['file']['filename'] = '/opt/mailman/web/logs/mailmanweb.log'

#: See https://docs.djangoproject.com/en/dev/ref/settings/#allowed-hosts
ALLOWED_HOSTS = [
"localhost", # Archiving API from Mailman, keep it.
"hermodr.com.br",
"127.0.0.1",
# "lists.your-domain.org",
# 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 = [
# "lists.your-domain.org",
# Add here all production domains you have.
"https://hermodr.com.br",
]

#: 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 = 1

# Set this to a new secret value.
SECRET_KEY = 'SET A NEW KEY'

# Set this to match the api_key setting in
# /opt/mailman/mm/mailman-hyperkitty.cfg (quoted here, not there).
MAILMAN_ARCHIVER_KEY = 'Secret_Hyperkitty_API_Key'

# The sender of emails from Django such as address confirmation requests.
# Set this to a valid email address.
DEFAULT_FROM_EMAIL = 'mailman@hermodr.com.br'

# The sender of error messages from Django. Set this to a valid email
# address.
SERVER_EMAIL = 'mailman@hermodr.com.br'

A opção MAILMAN_ARCHIVER_KEY é usada pelo software de gerenciamento de listas de email chamado Mailman, em conjunto com o software de arquivamento de mensagens Hyperkitty. A variável de configuração contém a chave secreta da API do Hyperkitty, que é usada pelo Mailman para permitir que as mensagens enviadas para uma lista de email sejam arquivadas e visualizadas no Hyperkitty.
A opção SECRET_KEY é frequentemente usada por muitos frameworks e aplicativos web, incluindo o Django, para fornecer um segredo criptográfico usado para autenticar e proteger sessões de usuário, formulários e outras informações sensíveis. A chave secreta é usada para gerar valores de hash e criptografia de dados confidenciais, tornando mais difícil para os invasores comprometerem o sistema. Ao definir uma nova chave, geralmente é recomendado que ela seja exclusiva e complexa para aumentar a segurança do aplicativo.



Configure o WSGI server


O WSGI (Web Server Gateway Interface) é uma especificação que define uma interface padrão entre servidores web e aplicativos web escritos em Python. Um servidor WSGI é um servidor web que implementa essa interface e é capaz de se comunicar com os aplicativos Python que também implementam essa interface.


Ou seja, um servidor WSGI é responsável por receber as solicitações HTTP feitas pelo navegador do usuário e direcioná-las para o aplicativo Python correto. O servidor também é responsável por receber as respostas do aplicativo Python e enviá-las de volta ao navegador do usuário.


Existem vários servidores WSGI disponíveis, incluindo o uWSGI, o Gunicorn e o mod_wsgi do Apache. Cada servidor tem suas próprias características e opções de configuração, mas todos são projetados para trabalhar com aplicativos web Python que seguem a especificação WSGI.


Crie a configuração primeiro para depois instalarmos o `uwsgi` :
# Crie o arquivo abaixo:
sudo vim /etc/mailman3/uwsgi.ini

####### Cole a saída abaixo #######

[uwsgi]
# Port on which uwsgi will be listening.
http-socket = 0.0.0.0:8000
# If running uwsgi from the virtual environment ...
virtualenv = /opt/mailman/venv/

module=mailman_web.wsgi:application
# Set PYTHONPATH
env = PYTHONPATH=/etc/mailman3/
# The default settings module.
env = DJANGO_SETTINGS_MODULE=settings

# Setup default number of processes and threads per process.
master = true
processes = 2
threads = 2

# Setup the django_q related worker processes.
attach-daemon = /opt/mailman/venv/bin/mailman-web qcluster

# Setup the request log.
req-logger = file:/opt/mailman/web/logs/uwsgi.log

# Log qcluster commands separately.
logger = qcluster file:/opt/mailman/web/logs/uwsgi-qcluster.log
log-route = qcluster uwsgi-daemons

# Last log and it logs the rest of the stuff.
logger = file:/opt/mailman/web/logs/uwsgi-error.log

Configure o serviço do mailman-web para subir no boot:

# Crie o arquivo abaixo:
sudo vim /etc/systemd/system/mailmanweb.service

####### Cole a saída abaixo #######
[Unit]
Description=GNU Mailman Web UI
After=syslog.target network.target postgresql.service mailman3.service

[Service]
Environment="PYTHONPATH=/etc/mailman3/"
User=mailman
Group=mailman
ExecStart=/opt/mailman/venv/bin/uwsgi --ini /etc/mailman3/uwsgi.ini
KillSignal=SIGINT

[Install]
WantedBy=multi-user.target

Agora vamos instalar o uwsgi para fazer a comunicação entre o web server e o django:

# Logue com o usuário 'mailman':
sudo su - mailman

# Instale o 'uwsgi':
pip install uwsgi

Agora vamos gerenciar os serviços criados no SystemD:
# Recarregue a configuração do systemd:
sudo systemctl daemon-reload

# Inicie, Habilite e veja o Status do mailman3:
sudo systemctl start mailman3
sudo systemctl enable mailman3

# Inicie, Habilite e veja o Status do mailmanweb:
sudo systemctl start mailmanweb
sudo systemctl enable mailmanweb

Configure a integração do Mailman 3 com o HyperKitty:

# Crie o arquivo abaixo:
sudo vim /opt/mailman/mm/mailman-hyperkitty.cfg

####### Cole a saída abaixo #######
[general]
base_url: http://127.0.0.1:8000/archives/
api_key: Secret_Hyperkitty_API_Key

Agora acerte as chaves nos arquivos: /opt/mailman/mm/mailman-hyperkitty.cfg, /etc/mailman3/settings.py.


Corrija as permissões do usuário 'mailman':

sudo chown -R mailman:mailman /opt/mailman


Instalando e Configurando o MTA


Vamos instalar o Serviço de Email e configurar ele para que o Mailman possa entregar os emails das listas sem nenhum problema. Para essa configuração de servidor de email vamos usar apenas o básico para fazer funcionar o servidor de email, como é um servidor voltado para o Mailman não será necessário adicionar nada além do MTA (dovecot e rspamd não serão necessário).


Porém, vamos trabalhar a fundo para configurar a parte de segurança no servidor de email para não termos nenhuma falha e não deixar o servidor aberto para o mundo. Comece instalando o a aplicação do servidor de email:

# Instale o Postfix:
sudo apt install postfix -y

#### No 'Tipo de servidor de email' deixe como 'internet side'!

Agora vamos configurar o servidor de email, vou deixar a configuração completa, também terá a configuração específica do Mailman:

# Faça um backup da configuração atual do Postfix:
sudo cp /etc/postfix/main.cf /etc/postfix/main.cf.bkp

# Edite e altere a configuração atual:
sudo vim /etc/postfix/main.cf


####### Cole a saída abaixo #######


smtpd_banner = $myhostname ESMTP $mail_name
biff = no

# appending .domain is the MUA's job.
append_dot_mydomain = no

readme_directory = no

# See http://www.postfix.org/COMPATIBILITY_README.html -- default to 3.6 on
# fresh installs.
compatibility_level = 3.6

# appending .domain is the MUA's job.
append_dot_mydomain = no

########################################################
### SMTPD TLS configuration for incoming connections ###
########################################################
smtpd_tls_cert_file=/etc/letsencrypt/live/hermodr.com.br/fullchain.pem
smtpd_tls_key_file=/etc/letsencrypt/live/hermodr.com.br/privkey.pem
smtpd_use_tls = yes
smtpd_tls_security_level = may

smtpd_tls_session_cache_database = btree:${data_directory}/smtpd_scache

smtpd_tls_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1,TLSv1.2,TLSv1.3
smtpd_tls_mandatory_protocols = !SSLv2,!SSLv3,!TLSv1,!TLSv1.1,TLSv1.2,TLSv1.3

smtpd_tls_exclude_ciphers = aNULL,eNULL,EXPORT,DES,RC4,MD5,PSK,aECDH,EDH-DSS-DES-CBC3-SHA,EDH-RSA-DES-CBC3-SHA,KRB5-DES,CBC3-SHA,DES-CBC3-SHA,AES128-SHA,AES256-SHA,AES128-SHA256,AES128-GCM-SHA256,AES256-SHA256,DHE-RSA-DES-CBC3-SHA,AES256-GCM-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDHE-RSA-DES-CBC3-SHA,CAMELLIA256-SHA256,CAMELLIA256-SHA,CAMELLIA128-SHA256,CAMELLIA128-SHA
tls_high_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256
smtpd_tls_mandatory_ciphers = high
smtpd_tls_ciphers = high

# set up EECDH parameters for 192-bits security level (ignored from Postfix version 3.6)
smtpd_tls_dh1024_param_file = /etc/postfix/ssl/ffdhe4096.pem
tls_preempt_cipherlist = yes

tls_ssl_options = NO_TICKET, NO_COMPRESSION, NO_RENEGOTIATION, NO_SESSION_RESUMPTION_ON_RENEGOTIATION

smtpd_tls_eecdh_grade = ultra
tls_eecdh_ultra_curve = secp384r1

disable_vrfy_command = yes
show_user_unknown_table_name = no

########################################################
### SMTP TLS configuration for outcoming connections ###
########################################################
smtp_tls_CApath=/etc/ssl/certs
smtp_tls_session_cache_database = btree:${data_directory}/smtp_scache
smtp_tls_ciphers = high
smtp_tls_mandatory_ciphers = high
smtp_tls_exclude_ciphers = aNULL,eNULL,EXPORT,DES,RC4,MD5,PSK,aECDH,EDH-DSS-DES-CBC3-SHA,EDH-RSA-DES-CBC3-SHA,KRB5-DES,CBC3-SHA,DES-CBC3-SHA,AES128-SHA,AES256-SHA,AES128-SHA256,AES128-GCM-SHA256,AES256-SHA256,DHE-RSA-DES-CBC3-SHA,AES256-GCM-SHA384,ECDHE-ECDSA-DES-CBC3-SHA,ECDHE-RSA-DES-CBC3-SHA,CAMELLIA256-SHA256,CAMELLIA256-SHA,CAMELLIA128-SHA256,CAMELLIA128-SHA
tls_high_cipherlist = ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-RSA-AES128-GCM-SHA256

## DANE-Settings for TLS
smtp_dns_support_level=dnssec
smtp_tls_security_level = dane

#############################
### Mailman configuration ###
#############################

unknown_local_recipient_reject_code = 550
owner_request_special = no

transport_maps =
hash:/opt/mailman/mm/var/data/postfix_lmtp
local_recipient_maps =
hash:/opt/mailman/mm/var/data/postfix_lmtp
relay_domains =
hash:/opt/mailman/mm/var/data/postfix_domains


#############################
### Postfix configuration ###
#############################

smtpd_relay_restrictions = permit_mynetworks permit_sasl_authenticated defer_unauth_destination
myhostname = hermodr.com.br
alias_maps = hash:/etc/aliases
alias_database = hash:/etc/aliases
myorigin = /etc/mailname
mydestination = hermodr.com.br, localhost
relayhost =
mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
mailbox_size_limit = 0
message_size_limit = 28871600
recipient_delimiter = +
inet_interfaces = all
inet_protocols = all


##############################
### OpenDKIM configuration ###
##############################

milter_protocol = 6
milter_mail_macros = i {mail_addr} {client_addr} {client_name} {auth_authen}
milter_default_action = accept
smtpd_milters = inet:127.0.0.1:11332
non_smtpd_milters = $smtpd_milters

Vamos configurar a chave Diff-Hellmann:

# Crie o diretório abaixo:
sudo mkdir /etc/postfix/ssl

# Entre nele:
cd /etc/postfix/ssl

# Baixe a chave:
wget https://raw.githubusercontent.com/internetstandards/dhe_groups/master/ffdhe4096.pem


Instalando e Configurando o Web Server


Vamos instalar e configurar o NGINX com Proxy Reverso para comunicação com o uwsgi via ngx_http_uwsgi_module:

# Instale o nginx:
sudo apt install nginx -y

# Crie a pasta abaixo:
sudo mkdir /etc/nginx/certs

# edite o arquivo abaixo:
sudo vim /etc/nginx/sites-available/default


####### Cole a saída abaixo #######

server {
listen 80 default_server;
listen [::]:80 default_server;
server_name _;
return 301 https://$host$request_uri;
}
server {

listen 443 ssl default_server;
listen [::]:443 ssl default_server;

server_name hermodr.com.br;
location /static/ {
alias /opt/mailman/web/static/;
}

location / {
proxy_pass http://127.0.0.1:8000;
proxy_set_header Host $host;
proxy_set_header X-Forwarded-For $remote_addr;

}

location /rspamd {
allow 127.0.0.1;
allow ::1;
deny all;

rewrite ^/rspamd$ /rspamd/ permanent;
rewrite ^/rspamd/(.*)$ /$1 break;

proxy_pass http://localhost:11334;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}

location /.well-known/acme-challenge/ {
allow all;
}

ssl_certificate /etc/letsencrypt/live/hermodr.com.br/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/hermodr.com.br/privkey.pem;

# Enable HSTS:
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains; preload";

# Enable CSP Header:
add_header Content-Security-Policy "default-src 'self'; frame-src 'self'; frame-ancestors 'self';";

add_header X-Content-Type-Options "nosniff";
add_header Referrer-Policy "no-referrer";

# Enable OCSP stapling:
ssl_stapling on;
ssl_stapling_verify on;
ssl_trusted_certificate /etc/letsencrypt/live/hermodr.com.br/chain.pem;

# TLS Tuning
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256;
ssl_prefer_server_ciphers on;
ssl_dhparam /etc/postfix/ssl/ffdhe4096.pem;
}


# edite o arquivo abaixo:
sudo vim /etc/nginx/nginx.conf


####### Adicione a saída abaixo - A diretiva http já existe #######
http {
server_tokens off; # desabilita a exibição de tokens de servidor
...
}

Reinicie o NGINX:

# Agora restarte o nginx e outros serviços:
$ sudo systemctl restart nginx mailmanweb mailman3 postfix


Configurando usuário administrador no Mailman Web



Vamos executar algumas tarefas específicas relacionadas à interface web do sistema:

# Logue com o usuário 'mailman' caso não esteja:
sudo su - mailman

# Execute as migrações do banco de dados para a interface web do Mailman 3:
mailman-web migrate

# Facilite o carregamento do site:
mailman-web collectstatic

# Reduzir o tamanho total dos arquivos:
mailman-web compress

Veja uma explicação detalhada do que foi feito acima:

mailman-web migrate: Este comando é usado para executar as migrações do banco de dados para a interface web do Mailman 3. As migrações de banco de dados geralmente são necessárias quando há uma atualização de versão ou quando são feitas alterações no esquema do banco de dados.

mailman-web collectstatic: Este comando é usado para coletar os arquivos estáticos da interface web do Mailman 3, como imagens, CSS e JavaScript, e colocá-los em um único diretório para facilitar o carregamento do site. Isso é útil para reduzir o tempo de carregamento da página da web e melhorar o desempenho.

mailman-web compress: Este comando é usado para comprimir os arquivos estáticos da interface web do Mailman 3, o que ajuda a reduzir o tamanho total dos arquivos e, consequentemente, melhora o desempenho do site.

Agora podemos criar criar uma conta no Mailman Web (podemos criar sem executar os passos acima):

# Logue com o usuário 'mailman' caso não esteja:
sudo su - mailman

# Crie a conta:
mailman-web createsuperuser


Outros comandos


Testar envio de email:

# Logue com o usuário 'mailman':
sudo su - mailman

# Teste o envio de email pelo Mailman:
mailman-web sendtestemail jhon@examplo.com.br

Ver informações:

# Logue com o usuário 'mailman':
sudo su - mailman

# Ver informações:
mailman info


Acertando parte de segurança


Vamos confgurar a parte de segurança do Mail Server.



Configurando TLSA


Vamos configurar o TLSA:

# Obtenha o hash para o TLSA usando o certificado:
openssl x509 -noout -pubkey -in /etc/letsencrypt/live/hermodr.com.br/fullchain.pem | openssl rsa -pubin -outform DER 2>/dev/null | sha256sum
9880da323e4ee6f6929f8150903f8046ae94fb03d8884700279b7139f760dfa9 -

Agora no servidor DNS adicione as seguintes entradas:

_25._tcp.hermodr.com.br. IN TLSA (3 1 1 9880da323e4ee6f6929f8150903f8046ae94fb03d8884700279b7139f760dfa9)

_443._tcp.hermodr.com.br. IN TLSA (3 1 1 9880da323e4ee6f6929f8150903f8046ae94fb03d8884700279b7139f760dfa9)

Podemos testar o TLSA com o seguinte comando:

dig +dnssec +multi _25._tcp.hermodr.com.br. TLSA

dig +dnssec +multi _443._tcp.hermodr.com.br. TLSA


Configurando DKIM


Vamos configurar o DKIM via Rspamd:

# Instale o pacote do rspamd:
sudo apt -y install rspamd

# Crie o diretório abaixo:
sudo mkdir /var/lib/rspamd/dkim

# Gere as chaves:
rspamadm dkim_keygen -s '20230217' -b 4096 -d hermodr.com.br -k /var/lib/rspamd/dkim/hermodr.com.br.private > /var/lib/rspamd/dkim/hermodr.com.br.txt

# Corrija as permissões:
chown _rspamd. -R /var/lib/rspamd/dkim

### Cria um arquivo chamado "hermodr.com.br.private", que contém a chave privada do DKIM e outro com o registro DNS.

# Veja o conetúdo do registro DNS:
cat /var/lib/rspamd/dkim/hermodr.com.br.txt
20230217._domainkey IN TXT ( "v=DKIM1; k=rsa; "
"p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmzMcpQnEJkasvTPYXc3NEGwX9v1NNwPDE0VdRvv4CGsRdXBIBThr5eEcxGm7TwxNBXciIMGFIf0ZQK/3pnNZ6yKyssiNK7rIehxZD4zFoRljY37oFqvTG8T6ZvhT21gQqaFMatRlnCVATph9a2WF8/NhxHiZaF/jTOulzo0cjroDx+jyrBtmb5qBeTEaWT/aD+89bb3RXpWpCk"
"6/yNLbw6TGBz9gqtuL0RWHBJzDLuBHMFbRsRkQxxOoxZ6uEIvIeEEhdKZuu2zm+CY4bk5uoddTu+ikA7dCgksudvB4SEOcnqvYwsXbVf1bXGsGCdQIaBWd7a1KoihoUfdhLsLb6YfGA+O0bZo2msumS+u8hNrnirLEa+YZ2LUJ0/69wygm5Iixe6pN0uCe5XCaNIz248hSjZ7IN88Lw3S0VSHnEQvQAq1wjYMWqfXUuFrdKra29npY4Qdv"
"lcyv1IrDfX+yd6LrhmdPiEJvJu50NeSu6aXlCn1kRb6oVWic7hMmnjpTd05cT6CGAZGCGAEB9oOESP5x8Yu2zxxD1I7oRDNSfyQ0mASIWHOvln36dPRolw1xG3IX0X2DC/k4QCuCof6pDjrmX2kKUIuvYcVaea/HM9maP78xNesacxuEI5F6WyNGt3sgRsKBMDZfaz7kajDhBTThF14ErE3dFHIvSoiQ1JECAwEAAQ==" ) ; ----- DKIM key 20230217 for hermodr.com.br

Agora para colocar no servidor DNS, você deve colocar tudo numa única linha e não coloque aspas ", exemplo caso use o site registro.br:

20230217._domainkey IN  TXT v=DKIM1; k=rsa; p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmzMcpQnEJkasvTPYXc3NEGwX9v1NNwPDE0VdRvv4CGsRdXBIBThr5eEcxGm7TwxNBXciIMGFIf0ZQK/3pnNZ6yKyssiNK7rIehxZD4zFoRljY37oFqvTG8T6ZvhT21gQqaFMatRlnCVATph9a2WF8/NhxHiZaF/jTOulzo0cjroDx+jyrBtmb5qBeTEaWT/aD+89bb3RXpWpCk6/yNLbw6TGBz9gqtuL0RWHBJzDLuBHMFbRsRkQxxOoxZ6uEIvIeEEhdKZuu2zm+CY4bk5uoddTu+ikA7dCgksudvB4SEOcnqvYwsXbVf1bXGsGCdQIaBWd7a1KoihoUfdhLsLb6YfGA+O0bZo2msumS+u8hNrnirLEa+YZ2LUJ0/69wygm5Iixe6pN0uCe5XCaNIz248hSjZ7IN88Lw3S0VSHnEQvQAq1wjYMWqfXUuFrdKra29npY4Qdvlcyv1IrDfX+yd6LrhmdPiEJvJu50NeSu6aXlCn1kRb6oVWic7hMmnjpTd05cT6CGAZGCGAEB9oOESP5x8Yu2zxxD1I7oRDNSfyQ0mASIWHOvln36dPRolw1xG3IX0X2DC/k4QCuCof6pDjrmX2kKUIuvYcVaea/HM9maP78xNesacxuEI5F6WyNGt3sgRsKBMDZfaz7kajDhBTThF14ErE3dFHIvSoiQ1JECAwEAAQ==

Podemos testar o DKIM com este site.
Pode usar este outro site para ver se o registro do DKIM está correto!


O comando abaixo retorna o valor do DKIM configurado no DNS:
dig TXT 20230217._domainkey.hermodr.com.br

Um outro teste que podemos fazer é enviar um email para check-auth@verifier.port25.com e ele irá nos retornar um resultado, com isso testamos a assinatura do DKIM:

echo "test dkim" | mail -aFrom:postmaster@hermodr.com.br -s "Test from hermodr" check-auth@verifier.port25.com

O DKIM ainda não está funcional, para isso vamos fazer a parte que falta no tópico de instalação e configuração do Rspamd !



Configurando DMARC


Vamos configurar o DMARC. Você precisa adicionar a seguinte entrada no DNS:

_dmarc.hermodr.com.br   IN TXT  "v=DMARC1; p=reject; rua=mailto:postmaster@hermodr.com.br" 

A política p especifica a ação a ser tomada com os emails que não passam na autenticação. A opção none é recomendada para começar, permitindo que os emails passem mesmo que não sejam autenticados.


O campo rua especifica um endereço de email para o qual relatórios de falhas DMARC serão enviados.


Podemos testar o DMARC com este site! ou usando o comando abaixo:

dig TXT _dmarc.hermodr.com.br


Configurando o SPF


Vamos configurar o DMARC. Você precisa adicionar a seguinte entrada no DNS:

        IN TXT "v=spf1 mx -all"

Podemos testar o SPF com o comando abaixo:

dig TXT hermodr.com.br +short


Configuração completa do DNS


Agora veja como está o DNS com toda a configuração completa:

    A   hermodr.com.br  IPv4

MX hermodr.com.br 5 hermodr.com.br

TXT hermodr.com.br "v=spf1 mx -all"

AAAA hermodr.com.br IPv6

TXT _dmarc.hermodr.com.br "v=DMARC1; p=reject; rua=mailto:postmaster@hermodr.com.br"

TXT 20230217._domainkey.hermodr.com.br "v=DKIM1; h=sha256; k=rsa; s=email; p=MIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAmzMcpQnEJkasvTPYXc3NEGwX9v1NNwPDE0VdRvv4CGsRdXBIBThr5eEcxGm7TwxNBXciIMGFIf0ZQK/3pnNZ6yKyssiNK7rIehxZD4zFoRljY37oFqvTG8T6ZvhT21gQqaFMatRlnCVATph9a2WF8/NhxHiZaF/jTOulzo0cjroDx+jyrBtmb5qBeTEaWT/aD+89bb3RXpWpCk6/yNLbw6TGBz9gqtuL0RWHBJzDLuBHMFbRsRkQxxOoxZ6uEIvIeEEhdKZuu2zm+CY4bk5uoddTu+ikA7dCgksudvB4SEOcnqvYwsXbVf1bXGsGCdQIaBWd7a1KoihoUfdhLsLb6YfGA+O0bZo2msumS+u8hNrnirLEa+YZ2LUJ0/69wygm5Iixe6pN0uCe5XCaNIz248hSjZ7IN88Lw3S0VSHnEQvQAq1wjYMWqfXUuFrdKra29npY4Qdvlcyv1IrDfX+yd6LrhmdPiEJvJu50NeSu6aXlCn1kRb6oVWic7hMmnjpTd05cT6CGAZGCGAEB9oOESP5x8Yu2zxxD1I7oRDNSfyQ0mASIWHOvln36dPRolw1xG3IX0X2DC/k4QCuCof6pDjrmX2kKUIuvYcVaea/HM9maP78xNesacxuEI5F6WyNGt3sgRsKBMDZfaz7kajDhBTThF14ErE3dFHIvSoiQ1JECAwEAAQ=="

TXT _adsp._domainkey.hermodr.com.br "dkim = all"

TLSA _25._tcp.hermodr.com.br 3 1 1 9880da323e4ee6f6929f8150903f8046ae94fb03d8884700279b7139f760dfa9

TLSA _443._tcp.hermodr.com.br. 3 1 1 9880da323e4ee6f6929f8150903f8046ae94fb03d8884700279b7139f760dfa9


Reiniciando os serviços


Agora reinicie todos os serviços:

sudo systemctl restart nginx mailman3 mailmanweb postfix


Criando uma lista


Antes de criarmos a lista, tem alguns passos importantes que devem ser feitos.


  1. Primeiro acesse: https://hermodr.com.br/.
  2. Tente Logar para receber o email de confirmação.
  3. Agora acesse: https://hermodr.com.br/admin
  4. Na aba 'Accounts' clique em 'Email Addresses'.
  5. Marque a caixa de diálogo do primeiro usuário (aqui é mailman).
  6. Em 'Action', deixe a opção 'Mark selectec email addresses as verified'.
  7. Clique em Go.

    Isso fará com que você possa logar com o usuário mailman sem precisar receber um link para confirmar a conta.


Agora vamos acertar o nome do site para nosso domínio:

  1. Na aba 'SITES' clique em 'Sites'.
  2. Clique em 'example.com'.
  3. Em 'Domain name e 'Display name' coloque o nome do domínio, depois clique em SAVE.

Agora vamos começar o processo de criação uma lista, mas antes vamos acertar o domínio no qual nosso mailman vai responder os emails.

  1. Primeiro acesse: https://hermodr.com.br/.
  2. Logue com o usuário.
  3. Clique em Domains, depois em Add Domain.
  4. Em Mail Host coloque o servidor de email que vai responder pelo domínio que estamos cadastrando. No nosso caso é hermodr.com.br.
  5. Em Description coloque uma descrição para esse domínio.
  6. Em Web Host selecione o site que alteramos, só deve ter um nessa etapa para selecionar.
  7. Clique em 'Create Domain'.

Agora vamos criar a lista própriamente dita.

  1. Clique em Lists, depois clique em Create a New List.
  2. Em List Name devemos colocar o nome da lista.
  3. Em Mail Host devemos colocar o domínio, nesse ponto deve ter apenas um.
  4. Em Short Description informe uma pequena descrição para essa lista.
  5. Clique em Create List.

Agora nesse ponto estamos dentro do Perfil da lista que acabamos de criar.

  1. Clique em Settings e depois DMARC Mitigations.
  2. Em DMARC mitigation action deixe como Replace From: with list addresses
  3. Clique em Save changes

    Isso deve ser feito para que o Mailman não mude o Header dos emails em alguns casos, e quando isso acontece, os emails caem em spam.



Clamav


O ClamAV é um software antivírus gratuito e de código aberto para sistemas operacionais Unix, incluindo Linux, macOS e FreeBSD. Ele é projetado para detectar malware, incluindo vírus, cavalos de Troia, worms, spyware e outros tipos de ameaças.


Ele é usado principalmente em servidores de e-mail, servidores de arquivos e em outras situações em que a detecção de malware é necessária. Ele usa uma combinação de assinaturas de vírus e mecanismos heurísticos para detectar malware, e é conhecido por sua alta taxa de detecção e baixo número de falsos positivos.


Vamos instalar e configurar o Clamav.

# Faça instalação dos pacotes abaixo:
sudo apt install -y clamav-daemon clamav

# Pare o processo do freshclam:
systemctl stop clamav-freshclam

# Atualize os bancos de dados de vírus do ClamAV:
sudo freshclam

# Inicie o processo do freshclam novamente:
systemctl start clamav-freshclam clamav-daemon

Para ver a versão do Clamav clamscan --version.
Verificar um arquivo específico em busca de vírus clamscan /path/to/file.


Vamos adicionar algumas assinaturas extras que são mantidas pelo projeto ClamAV Unofficial Signatures (CUS), que é um projeto de código aberto separado que visa fornecer assinaturas de vírus adicionais para o ClamAV. O que vamos fazer em seguida é baixar alguns scripts e configurações necessários para usar as assinaturas de malware extras fornecidas pelo CUS. Quando os scripts são executados, eles baixam as assinaturas mais recentes do CUS e as adicionam ao ClamAV, permitindo que ele detecte uma ampla variedade de ameaças de malware.

# Entre no diretório abaixo:
cd /usr/local/src/

# Baixe a assinatura:
sudo wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/clamav-unofficial-sigs.sh

# "Instale" o script no diretório abaixo com a permissão 0755:
sudo install -m 0755 clamav-unofficial-sigs.sh /usr/local/sbin/clamav-unofficial-sigs.sh

# Crie o diretório abaixo:
sudo mkdir -p /etc/clamav-unofficial-sigs/

# Mude de diretório:
cd /etc/clamav-unofficial-sigs

# Baixe os arquivos de configurações:
sudo wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/config/master.conf -O /etc/clamav-unofficial-sigs/master.conf
sudo wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/config/user.conf -O /etc/clamav-unofficial-sigs/user.conf
sudo wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/config/os/os.ubuntu.conf -O /etc/clamav-unofficial-sigs/os.conf

# Force a atualização das assinaturas de malware fornecidas pelo CUS:
sudo /usr/local/src/clamav-unofficial-sigs.sh --force

# Instale o arquivo de configuração do logrotate:
sudo /usr/local/src/clamav-unofficial-sigs.sh --install-logrotate

# Instale o arquivo de configuração do man:
sudo /usr/local/src/clamav-unofficial-sigs.sh --install-man

# Entre no diretório abaixo:
cd /etc/systemd/system/

# Baixe o '.service' e o '.timer' do CUS:
sudo wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/systemd/clamav-unofficial-sigs.service -O clamav-unofficial-sigs.service
sudo wget https://raw.githubusercontent.com/extremeshok/clamav-unofficial-sigs/master/systemd/clamav-unofficial-sigs.timer -O clamav-unofficial-sigs.timer

# Habilite o '.service' e o '.timer' que acabamos de baixar para iniciar no Boot:
systemctl enable clamav-unofficial-sigs.service
systemctl enable clamav-unofficial-sigs.timer

# Inicie o '.timer':
systemctl start clamav-unofficial-sigs.timer

# Verifique se as assinaturas de malware estão carregadas corretamente:
clamscan --debug 2>&1 /dev/null | grep "loaded"


RSpamD


O Rspamd é um sistema de filtragem e análise de email de código aberto. Ele é projetado para ser executado em servidores de email e é usado para identificar e bloquear spam, vírus e outras ameaças de segurança. O Rspamd é capaz de processar grandes volumes de email e é altamente escalável.


Vamos instalar e configurar o RSpamD para atuar em conjunto com o Clamav.

# Instale o rspamd (já foi instalado):
sudo apt install -y rspamd

# Vamos gerar uma senha criptografada que pode ser usada em arquivos de configuração do Rspamd, para autenticação ou outras finalidades de segurança:
sudo rspamadm pw --encrypt

__________________________________________________________________________________________________
# Crie o arquivo de configuração do 'worker-controller' do Rspamd
sudo vim /etc/rspamd/local.d/worker-controller.inc

### Adicione ao arquivo: ###
password = "xxxxxx";

# Essa variável define uma senha para autenticar conexões ao worker-controller.
# Ela autentica os clientes que desejam se conectar e controlar o worker-controller, como o utilitário "rspamadm".
__________________________________________________________________________________________________

# Vamos criar o 'worker-proxy', ele é um worker do Rspamd que permite que outros servidores de email enviem e-mails para o Rspamd para processamento:
sudo vim /etc/rspamd/local.d/worker-proxy.inc

### Adicione ao arquivo: ###

# End. abaixo do OpenDKIM, permite que o worker-proxy do Rspamd receba conexões de servidores de correio usando o protocolo Milter:
bind_socket = "127.0.0.1:11332";
milter = yes;
timeout = 120s;
upstream "local" {
default = yes;
self_scan = yes;
}
__________________________________________________________________________________________________

# Crie o arquivo usado para configurar o módulo de verificação de vírus do Rspamd:
sudo vim /etc/rspamd/local.d/antivirus.conf

### Adicione ao arquivo: ###

clamav {
scan_mime_parts = false;
symbol = "CLAM_VIRUS";
type = "clamav";
action = "reject";
servers = "/var/run/clamav/clamd.ctl";
}
# Essa configuração acima configura o módulo de verificação de vírus para usar o ClamAV como um scanner de vírus.
__________________________________________________________________________________________________

# Crie o arquivo para configurar o módulo de classificação Bayesiana do Rspamd:
sudo vim /etc/rspamd/local.d/classifier-bayes.conf

### Adicione ao arquivo: ###

backend = "redis";
autolearn = true;
server = "localhost";
# A Cassificação Bayesiana é um método de classificação estatística para análise de spam.
# O trecho de código acima configura o módulo de classificação Bayesiana para usar o Redis como o backend para armazenamento de dados,
# Portanto, precisa instalar o redis 'sudo apt-get install redis-server'.
__________________________________________________________________________________________________

# Crie o arquivo para que o Rspamd possa adicionar cabeçalhos de e-mail personalizados:
sudo vim /etc/rspamd/local.d/milter_headers.conf

### Adicione ao arquivo: ###

# Quais cabeçalhos devem ser adicionados para mensagens autenticadas.
authenticated_headers = ["authentication-results"];
# Adiciona cabeçalhos adicionais às mensagens de spam detectadas pelo Rspamd como: score de spam, o número de regras correspondentes e muito mais.
extended_spam_headers = true;
# O Rspamd deve ou não analisar e adicionar cabeçalhos para mensagens que são enviadas localmente (deve analisar sim).
skip_local = false;
# O Rspamd deve ou não analisar e adicionar cabeçalhos para mensagens autenticadas (deve analisar sim).
skip_authenticated = false;
__________________________________________________________________________________________________

# Crie o arquivo para que o Rspamd possa verificar a validade do registro MX do domínio de um remetente de e-mail:
sudo vim /etc/rspamd/local.d/mx_check.conf

### Adicione ao arquivo: ###

enabled = true;
server = "localhost";
# Server é o servidor DNS que deve ser usado para resolver o registro MX. No caso vamos usar o servidor DNS local.
__________________________________________________________________________________________________

# Vamos configurar os endereços IP locais para nosso server:
sudo vim /etc/rspamd/local.d/options.inc

### Adicione ao arquivo: ###

local_addrs = "127.0.0.0/8, ::ffff:127.0.0.0/104, ::1/128, 75.119.143.187/32, 2a02:c206:2120:1140::1/128";
__________________________________________________________________________________________________

# Crie o arquivo abaixo para configurar a conexão do Rspamd com o servidor Redis:
sudo vim /etc/rspamd/local.d/redis.conf

### Adicione ao arquivo: ###

write_servers = "localhost";
read_servers = "localhost";
# Definir os servidores Redis para gravação e leitura, respectivamente.
__________________________________________________________________________________________________

# Vamos configurar o módulo DKIM no Rspamd:
sudo vim /etc/rspamd/local.d/dkim_signing.conf

### Adicione ao arquivo: ###

domain {
hermodr.com.br {
selector = "20230217";
path = "/var/lib/rspamd/dkim/20230217.private";
}
}
allow_hdrfrom_mismatch = true;
allow_hdrfrom_mismatch_sign_networks = true;
allow_username_mismatch = true;
use_domain = "header";
auth_only = true;
use_esld = true;
__________________________________________________________________________________________________

# Entre no diretório abaixo:
cd /etc/rspamd/local.d/

# Crie o link abaixo:
sudo ln -s dkim_signing.conf arc.conf
## O ARC (Authenticated Received Chain) usa a mesma configuração que o DKIM (DomainKeys Identified Mail) no Rspamd.

# Agora reinicie o rspamd:
sudo systemctl restart rspamd

Como dependência dessa configuração vamos instalar o Redis:

# Instale o redis:
sudo apt-get install redis-server -y


Fontes


https://list.org/

https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/docs/install.html

https://docs.mailman3.org/en/latest/install/virtualenv.html#virtualenv-install

https://docs.mailman3.org/en/latest/migration.html

https://docs.mailman3.org/en/latest/migration.html

REST API Documentation

https://docs.mailman3.org/projects/mailman/en/latest/src/mailman/config/docs/config.html

https://www.mail-archive.com/mailman-users@python.org/msg74439.html

https://easydmarc.com/blog/how-to-configure-dkim-opendkim-with-postfix/

https://thecustomizewindows.com/2016/09/steps-create-add-dane-tlsa-record/

https://mytechiethoughts.com/linux/implementing-dane-with-certbot-using-lets-encrypt/

https://www.huque.com/bin/gen_tlsa

https://www.sidn.nl/en/news-and-blogs/hands-on-implementing-dane-in-postfix

https://www.checktls.com/

https://www.digitalocean.com/community/tutorials/how-to-install-and-configure-dkim-with-postfix-on-debian-wheezy

https://www.adonai.eti.br/2017/12/conf-o-dkim-postfix-debian-9/

https://lists.mailman3.org/archives/list/mailman-users@mailman3.org/thread/GMKO2SWDT3FXA6BWGOCLBSIYEDGXMD5F/

https://www.rspamd.com/doc/modules/dkim_signing.html#dkim-key-management