This commit is contained in:
137
mail-relay/README.md
Normal file
137
mail-relay/README.md
Normal file
@@ -0,0 +1,137 @@
|
|||||||
|
# Mail Relay - SMTP de salida para stacks
|
||||||
|
|
||||||
|
Stack de relay SMTP interno para centralizar el envio de correos de tus apps sin montar un servidor de correo completo.
|
||||||
|
|
||||||
|
## 📋 Descripcion
|
||||||
|
|
||||||
|
Este stack despliega un relay SMTP con Postfix usando `boky/postfix` para:
|
||||||
|
- Recibir correo SMTP desde contenedores internos
|
||||||
|
- Reenviar todo a un proveedor SMTP externo (smarthost)
|
||||||
|
- Firmar con DKIM (autogenerado)
|
||||||
|
- Unificar configuracion de correo para todos los stacks
|
||||||
|
|
||||||
|
No incluye recepcion de correo (MX, IMAP, POP3, webmail).
|
||||||
|
|
||||||
|
## 🚀 Despliegue
|
||||||
|
|
||||||
|
### 1. Preparar rutas y secreto en el host
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo mkdir -p /opt/mail-relay/{queue,opendkim,secrets}
|
||||||
|
sudo chmod 700 /opt/mail-relay/secrets
|
||||||
|
printf '%s' 'CAMBIA_ESTA_PASSWORD_SMTP' | sudo tee /opt/mail-relay/secrets/relayhost_password > /dev/null
|
||||||
|
sudo chmod 600 /opt/mail-relay/secrets/relayhost_password
|
||||||
|
```
|
||||||
|
|
||||||
|
### 2. Desplegar desde Portainer
|
||||||
|
|
||||||
|
1. Ve a **Stacks** -> **Add stack**
|
||||||
|
2. Nombre: `mail-relay`
|
||||||
|
3. Configura el repositorio Git
|
||||||
|
4. Compose path: `mail-relay/docker-compose.yml`
|
||||||
|
5. Carga variables desde `mail-relay/stack.env`
|
||||||
|
6. Ajusta al menos:
|
||||||
|
- `MAIL_RELAY_HOSTNAME`
|
||||||
|
- `MAIL_RELAY_ALLOWED_SENDER_DOMAINS`
|
||||||
|
- `MAIL_RELAY_MASQUERADED_DOMAINS`
|
||||||
|
- `MAIL_RELAY_SMARTHOST`
|
||||||
|
- `MAIL_RELAY_SMARTHOST_USERNAME`
|
||||||
|
7. Deploy del stack
|
||||||
|
|
||||||
|
## ⚙️ Variables importantes
|
||||||
|
|
||||||
|
```env
|
||||||
|
MAIL_RELAY_SMARTHOST=[smtp.proveedor.tld]:587
|
||||||
|
MAIL_RELAY_SMARTHOST_USERNAME=usuario-smtp
|
||||||
|
MAIL_RELAY_SMTP_TLS_SECURITY_LEVEL=encrypt
|
||||||
|
MAIL_RELAY_ALLOWED_SENDER_DOMAINS=tudominio.com
|
||||||
|
MAIL_RELAY_MASQUERADED_DOMAINS=tudominio.com
|
||||||
|
```
|
||||||
|
|
||||||
|
La password SMTP no se pone en `stack.env`; se lee desde el archivo host:
|
||||||
|
|
||||||
|
```text
|
||||||
|
/opt/mail-relay/secrets/relayhost_password
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔌 Conectar otras apps
|
||||||
|
|
||||||
|
En cada stack que deba enviar correo, añade la red externa:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
networks:
|
||||||
|
mail_internal:
|
||||||
|
external: true
|
||||||
|
```
|
||||||
|
|
||||||
|
Y en el servicio de la app:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
services:
|
||||||
|
tu-app:
|
||||||
|
networks:
|
||||||
|
- default
|
||||||
|
- mail_internal
|
||||||
|
```
|
||||||
|
|
||||||
|
Config SMTP en la app:
|
||||||
|
|
||||||
|
```env
|
||||||
|
SMTP_HOST=mail-relay
|
||||||
|
SMTP_PORT=587
|
||||||
|
SMTP_FROM=noreply@tudominio.com
|
||||||
|
```
|
||||||
|
|
||||||
|
## ✅ DNS minimo recomendado
|
||||||
|
|
||||||
|
Para buena entregabilidad en Gmail/Outlook:
|
||||||
|
- SPF
|
||||||
|
- DKIM
|
||||||
|
- DMARC
|
||||||
|
|
||||||
|
### SPF (ejemplo)
|
||||||
|
|
||||||
|
```text
|
||||||
|
v=spf1 include:spf.tu-proveedor.tld ~all
|
||||||
|
```
|
||||||
|
|
||||||
|
### DKIM
|
||||||
|
|
||||||
|
Tras el primer arranque, extrae el TXT generado:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
find /opt/mail-relay/opendkim -type f -name '*.txt' -exec echo '### {}' \; -exec cat {} \;
|
||||||
|
```
|
||||||
|
|
||||||
|
Copia esos valores a tu DNS.
|
||||||
|
|
||||||
|
### DMARC (inicio en monitorizacion)
|
||||||
|
|
||||||
|
```text
|
||||||
|
v=DMARC1; p=none; adkim=s; aspf=s
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🧪 Prueba rapida
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker exec -i mail-relay sendmail -t <<'EOF'
|
||||||
|
From: noreply@tudominio.com
|
||||||
|
To: destino@example.com
|
||||||
|
Subject: prueba mail relay
|
||||||
|
|
||||||
|
Correo de prueba del stack mail-relay.
|
||||||
|
EOF
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🛠️ Troubleshooting
|
||||||
|
|
||||||
|
Ver logs:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
docker logs -f mail-relay
|
||||||
|
```
|
||||||
|
|
||||||
|
Errores tipicos:
|
||||||
|
- `Relay access denied`: revisa `MAIL_RELAY_ALLOWED_SENDER_DOMAINS`
|
||||||
|
- Auth fallida con proveedor: revisa usuario/password SMTP
|
||||||
|
- Rechazo por DNS: valida SPF/DKIM/DMARC
|
||||||
52
mail-relay/docker-compose.yml
Normal file
52
mail-relay/docker-compose.yml
Normal file
@@ -0,0 +1,52 @@
|
|||||||
|
services:
|
||||||
|
mail-relay:
|
||||||
|
image: ${MAIL_RELAY_IMAGE}
|
||||||
|
container_name: mail-relay
|
||||||
|
restart: unless-stopped
|
||||||
|
environment:
|
||||||
|
TZ: ${TZ}
|
||||||
|
LOG_FORMAT: ${MAIL_RELAY_LOG_FORMAT}
|
||||||
|
|
||||||
|
# Hostname del relay
|
||||||
|
POSTFIX_myhostname: ${MAIL_RELAY_HOSTNAME}
|
||||||
|
|
||||||
|
# Solo clientes internos del stack de correo
|
||||||
|
POSTFIX_mynetworks: ${MAIL_RELAY_MYNETWORKS}
|
||||||
|
|
||||||
|
# Dominios permitidos para el sender
|
||||||
|
ALLOWED_SENDER_DOMAINS: ${MAIL_RELAY_ALLOWED_SENDER_DOMAINS}
|
||||||
|
|
||||||
|
# Reescritura de dominio para hosts internos
|
||||||
|
MASQUERADED_DOMAINS: ${MAIL_RELAY_MASQUERADED_DOMAINS}
|
||||||
|
|
||||||
|
# Relay SMTP externo
|
||||||
|
RELAYHOST: ${MAIL_RELAY_SMARTHOST}
|
||||||
|
RELAYHOST_USERNAME: ${MAIL_RELAY_SMARTHOST_USERNAME}
|
||||||
|
RELAYHOST_PASSWORD_FILE: /run/secrets/relayhost_password
|
||||||
|
POSTFIX_smtp_tls_security_level: ${MAIL_RELAY_SMTP_TLS_SECURITY_LEVEL}
|
||||||
|
|
||||||
|
# DKIM
|
||||||
|
DKIM_AUTOGENERATE: ${MAIL_RELAY_DKIM_AUTOGENERATE}
|
||||||
|
DKIM_SELECTOR: ${MAIL_RELAY_DKIM_SELECTOR}
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
- ${MAIL_RELAY_QUEUE_PATH}:/var/spool/postfix:Z
|
||||||
|
- ${MAIL_RELAY_DKIM_KEYS_PATH}:/etc/opendkim/keys:Z
|
||||||
|
- ${MAIL_RELAY_PASSWORD_FILE_PATH}:/run/secrets/relayhost_password:ro,Z
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mail_internal:
|
||||||
|
ipv4_address: ${MAIL_RELAY_IPV4}
|
||||||
|
|
||||||
|
# No publicar puertos al exterior para uso interno entre contenedores.
|
||||||
|
# Descomenta para pruebas desde el host:
|
||||||
|
# ports:
|
||||||
|
# - "127.0.0.1:1587:587"
|
||||||
|
|
||||||
|
networks:
|
||||||
|
mail_internal:
|
||||||
|
name: ${MAIL_RELAY_NETWORK_NAME}
|
||||||
|
driver: bridge
|
||||||
|
ipam:
|
||||||
|
config:
|
||||||
|
- subnet: ${MAIL_RELAY_SUBNET}
|
||||||
29
mail-relay/stack.env
Normal file
29
mail-relay/stack.env
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
##### General #####
|
||||||
|
MAIL_RELAY_IMAGE=boky/postfix:v5.1.0
|
||||||
|
TZ=Europe/Madrid
|
||||||
|
MAIL_RELAY_LOG_FORMAT=plain
|
||||||
|
|
||||||
|
##### Network #####
|
||||||
|
MAIL_RELAY_NETWORK_NAME=mail_internal
|
||||||
|
MAIL_RELAY_SUBNET=10.77.0.0/24
|
||||||
|
MAIL_RELAY_IPV4=10.77.0.10
|
||||||
|
MAIL_RELAY_MYNETWORKS=127.0.0.0/8,10.77.0.0/24
|
||||||
|
|
||||||
|
##### Relay identity #####
|
||||||
|
MAIL_RELAY_HOSTNAME=mail.example.com
|
||||||
|
MAIL_RELAY_ALLOWED_SENDER_DOMAINS=example.com
|
||||||
|
MAIL_RELAY_MASQUERADED_DOMAINS=example.com
|
||||||
|
|
||||||
|
##### Upstream SMTP (smarthost) #####
|
||||||
|
MAIL_RELAY_SMARTHOST=[in-v3.mailjet.com]:587
|
||||||
|
MAIL_RELAY_SMARTHOST_USERNAME=tu-api-key-mailjet
|
||||||
|
MAIL_RELAY_SMTP_TLS_SECURITY_LEVEL=encrypt
|
||||||
|
|
||||||
|
##### DKIM #####
|
||||||
|
MAIL_RELAY_DKIM_AUTOGENERATE=true
|
||||||
|
MAIL_RELAY_DKIM_SELECTOR=mail
|
||||||
|
|
||||||
|
##### Host paths #####
|
||||||
|
MAIL_RELAY_QUEUE_PATH=/opt/mail-relay/queue
|
||||||
|
MAIL_RELAY_DKIM_KEYS_PATH=/opt/mail-relay/opendkim
|
||||||
|
MAIL_RELAY_PASSWORD_FILE_PATH=/opt/mail-relay/secrets/relayhost_password
|
||||||
Reference in New Issue
Block a user