Instalación de Maddy: Servidor de Correo Composable
Maddy es un servidor de correo moderno escrito en Go que implementa SMTP, IMAP y todos los mecanismos de autenticación necesarios en un único binario configurable mediante un lenguaje de configuración declarativo. Su diseño composable permite construir exactamente el pipeline de procesamiento de correo que necesitas, sin la complejidad de coordinar múltiples componentes independientes como Postfix y Dovecot.
Requisitos Previos
- Servidor Linux (Ubuntu 20.04+, Debian 11+, CentOS 8+)
- Mínimo 512 MB de RAM
- IP pública con puerto 25 desbloqueado
- Dominio con acceso a la configuración DNS
- Registro PTR (rDNS) configurado para la IP del servidor
Instalación de Maddy
# Método 1: Binario precompilado (recomendado)
MADDY_VERSION=$(curl -s https://api.github.com/repos/foxcpp/maddy/releases/latest \
| grep '"tag_name"' | cut -d'"' -f4 | sed 's/v//')
wget "https://github.com/foxcpp/maddy/releases/download/v${MADDY_VERSION}/maddy-${MADDY_VERSION}-x86_64-linux-musl.tar.zst"
# Instalar descompresor si es necesario
sudo apt install -y zstd
# Extraer e instalar
tar --zstd -xf maddy-*.tar.zst
sudo cp maddy-*/maddy /usr/local/bin/
sudo chmod +x /usr/local/bin/maddy
# Verificar la instalación
maddy --version
# Método 2: Compilar desde el código fuente
sudo apt install -y golang-go git
git clone https://github.com/foxcpp/maddy.git
cd maddy
make
sudo make install
Crear el usuario del sistema y la estructura de directorios:
# Crear usuario dedicado
sudo useradd -r -s /sbin/nologin -d /var/lib/maddy maddy
# Crear directorios necesarios
sudo mkdir -p /etc/maddy
sudo mkdir -p /var/lib/maddy
sudo mkdir -p /run/maddy
sudo mkdir -p /var/log/maddy
# Establecer propietarios
sudo chown -R maddy:maddy /var/lib/maddy /run/maddy /var/log/maddy
sudo chown root:maddy /etc/maddy
sudo chmod 750 /etc/maddy
# Crear el servicio systemd
sudo tee /etc/systemd/system/maddy.service << 'EOF'
[Unit]
Description=Maddy Mail Server
After=network.target
[Service]
Type=notify
User=maddy
Group=maddy
ExecStart=/usr/local/bin/maddy -config /etc/maddy/maddy.conf
Restart=on-failure
RestartSec=5s
# Permisos especiales para puertos < 1024
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
[Install]
WantedBy=multi-user.target
EOF
sudo systemctl daemon-reload
Configuración SMTP e IMAP
El fichero /etc/maddy/maddy.conf define toda la configuración:
# /etc/maddy/maddy.conf
# Variables de configuración reutilizables
$(hostname) = mail.tudominio.com
$(primary_domain) = tudominio.com
$(local_domains) = $(primary_domain) otrodominio.com
# Almacenamiento de mensajes (buzones IMAP)
storage.imapsql local_mailboxes {
driver sqlite3
dsn /var/lib/maddy/imapsql.db
}
# Tabla de usuarios y contraseñas
table.chain local_rewrites {
optional_step regexp "(.+)\+.+@(.+)" "$1@$2"
optional_step static {
entry postmaster postmaster@$(primary_domain)
}
optional_step file /etc/maddy/aliases
}
auth.pass_table local_authdb {
table file /etc/maddy/credentials
hash bcrypt
hash_rounds 10
}
# Configuración del servidor SMTP entrante
smtp tcp://0.0.0.0:25 {
limits {
all rate 20 1s
all concurrency 10
}
dmarc yes
check {
require_mx_record
dkim
spf
}
source $(local_domains) {
reject 501 5.1.8 "El remitente no está permitido"
}
default_source {
destination postmaster@$(primary_domain) {
deliver_to &local_mailboxes
}
destination $(local_domains) {
deliver_to &local_mailboxes
}
default_destination {
reject 550 5.1.1 "Destinatario no encontrado"
}
}
}
# Submission para envío autenticado
submission tls://0.0.0.0:465 {
auth &local_authdb
source $(local_domains) {
destination $(local_domains) {
deliver_to &local_mailboxes
}
default_destination {
modify {
dkim $(primary_domain) default
}
deliver_to &remote_queue
}
}
default_source {
reject 501 5.1.8 "Remitente no autorizado"
}
}
# Submission STARTTLS (puerto 587)
submission tcp://0.0.0.0:587 {
auth &local_authdb
# ... misma configuración que el bloque anterior
}
# Servidor IMAP
imap tls://0.0.0.0:993 {
auth &local_authdb
storage &local_mailboxes
}
# IMAP con STARTTLS
imap tcp://0.0.0.0:143 {
auth &local_authdb
storage &local_mailboxes
}
# Cola para correos salientes remotos
target.remote outbound_delivery {
limits {
destination rate 20 1s
destination concurrency 10
}
mx_auth {
dane
mtasts {
cache fs
fs_dir /var/lib/maddy/mtasts_cache
}
local_policy {
min_tls_level encrypted
min_mx_level none
}
}
}
queue remote_queue {
target &outbound_delivery
autogenerated_msg_domain $(primary_domain)
bounce {
destination $(local_domains) {
deliver_to &local_mailboxes
}
default_destination {
reject 550 "No se puede hacer bounce"
}
}
}
Automatización TLS con Let's Encrypt
Maddy puede gestionar certificados TLS automáticamente:
# Añadir al fichero maddy.conf la configuración de TLS automático
tls.loader.acme acme_config {
# Directorio de almacenamiento de los certificados ACME
state_dir /var/lib/maddy/acme
# Email de contacto para Let's Encrypt
email [email protected]
# Servidor ACME (Let's Encrypt producción)
ca https://acme-v02.api.letsencrypt.org/directory
# Dominios a certificar
domains mail.tudominio.com
}
# Usar el gestor ACME en los listeners TLS
smtp tls://0.0.0.0:465 {
tls &acme_config
# ... resto de la configuración
}
Para usar certificados existentes de Certbot:
# Obtener certificado con Certbot
sudo certbot certonly --standalone -d mail.tudominio.com
# Copiar certificados al directorio de Maddy
sudo cp /etc/letsencrypt/live/mail.tudominio.com/fullchain.pem \
/etc/maddy/cert.pem
sudo cp /etc/letsencrypt/live/mail.tudominio.com/privkey.pem \
/etc/maddy/key.pem
sudo chown maddy:maddy /etc/maddy/cert.pem /etc/maddy/key.pem
# En maddy.conf, usar los certificados locales
tls.loader.file local_tls {
cert /etc/maddy/cert.pem
key /etc/maddy/key.pem
}
Firma DKIM
# Generar el par de claves DKIM
mkdir -p /etc/maddy/dkim_keys
# Maddy puede generar las claves automáticamente
sudo -u maddy maddy dkim gen \
--domain tudominio.com \
--selector default \
--key-path /etc/maddy/dkim_keys/tudominio.com_default.key
# Ver el registro DNS DKIM que debes añadir
sudo -u maddy maddy dkim show \
--domain tudominio.com \
--selector default \
--key-path /etc/maddy/dkim_keys/tudominio.com_default.key
Configurar la firma DKIM en maddy.conf:
# Módulo de firma DKIM
msgmodify.dkim dkim_signing {
debug no
domain tudominio.com
selector default
key_path /etc/maddy/dkim_keys/tudominio.com_default.key
# Cabeceras que se firman
oversign_fields From, To, Message-ID, Subject, Date
sign_all_sender no
}
# Aplicar la firma DKIM a los correos salientes
submission tls://0.0.0.0:465 {
source $(local_domains) {
default_destination {
modify {
dkim $(primary_domain) default
}
deliver_to &remote_queue
}
}
}
Backends de Almacenamiento
Maddy soporta varios backends para almacenar los buzones:
# SQLite (por defecto - adecuado para pocos usuarios)
storage.imapsql local_mailboxes {
driver sqlite3
dsn /var/lib/maddy/imapsql.db
}
# PostgreSQL (recomendado para producción)
storage.imapsql local_mailboxes {
driver postgres
dsn "host=localhost dbname=maddy user=maddy password=contraseña sslmode=disable"
}
# Gestionar usuarios con la CLI de Maddy
# Crear un nuevo usuario
sudo -u maddy maddy creds create [email protected]
# Listar usuarios existentes
sudo -u maddy maddy creds list
# Cambiar contraseña de un usuario
sudo -u maddy maddy creds set-password [email protected]
# Crear el buzón IMAP para el usuario
sudo -u maddy maddy imap-acct create [email protected]
# Ver buzones de un usuario
sudo -u maddy maddy imap-mboxes list [email protected]
Filtrado de Correo
# Añadir filtrado básico en maddy.conf
# Bloquear dominios de spam conocidos
table.file spam_domains {
file /etc/maddy/spam_domains.txt
}
# Verificaciones en el SMTP entrante
smtp tcp://0.0.0.0:25 {
check {
require_mx_record
dkim
spf
# Verificar que el dominio del remitente existe
require_matching_ehlo
# Limitar el tamaño de los mensajes
max_message_size 50M
}
# Rechazar correos de dominios en lista negra
source !$(lookup spam_domains [address_domain]) {
reject 550 5.7.1 "Tu dominio está en lista negra"
}
# ... resto de la configuración
}
Solución de Problemas
Maddy no arranca - error de permisos:
# Verificar propietarios de ficheros
ls -la /var/lib/maddy /etc/maddy /run/maddy
# Corregir permisos
sudo chown -R maddy:maddy /var/lib/maddy /run/maddy
sudo chown root:maddy /etc/maddy
sudo chmod 750 /etc/maddy
# Ver logs de inicio
sudo journalctl -u maddy -n 50 --no-pager
Error al obtener certificado ACME:
# Verificar que el dominio resuelve a la IP del servidor
dig A mail.tudominio.com
# Verificar que el puerto 80 está accesible (para validación ACME)
sudo ss -tlnp | grep 80
# Si otro servicio usa el puerto 80, detenerlo temporalmente
sudo systemctl stop nginx
sudo systemctl restart maddy
Autenticación IMAP falla:
# Verificar que el usuario existe
sudo -u maddy maddy creds list | grep [email protected]
# Probar la autenticación manualmente
openssl s_client -connect mail.tudominio.com:993
# Luego: 1 LOGIN [email protected] "contraseña"
# Ver logs de autenticación
sudo journalctl -u maddy -f | grep -i "auth\|imap"
Puerto 25 rechaza conexiones:
# Verificar que maddy tiene permisos para usar el puerto
sudo getcap /usr/local/bin/maddy
# Conceder permisos si es necesario
sudo setcap cap_net_bind_service=+ep /usr/local/bin/maddy
# Verificar que el puerto está abierto en el firewall
sudo ufw status | grep 25
sudo ufw allow 25/tcp
Conclusión
Maddy destaca por su enfoque composable que permite construir exactamente el servidor de correo que necesitas mediante la combinación de módulos en un lenguaje de configuración expresivo. La gestión automática de certificados TLS, la firma DKIM integrada y el soporte para múltiples backends de almacenamiento lo convierten en una alternativa moderna y elegante al clásico stack Postfix + Dovecot, especialmente adecuada para implementaciones nuevas donde la simplicidad operacional es prioritaria.


