Configurando un servidor de correo

Introducción

Como desarrollador me parece importante tener el control de mi servicio de correo y no depender de terceros. Además de ahorrar dinero (usar servicio de correo con un dominio personalizado siempre tiene un costo), me permite simplificar los backups y mejorar la privacidad de mis comunicaciones. Al alojar mi propio servidor de correo, tengo visibilidad total sobre quién accede a mis datos, cómo se almacenan y cuánto tiempo se retienen, sin estar sujeto a los términos de servicio de un proveedor externo que pueden cambiar en cualquier momento.

No necesito un servicio de correo demasiado complejo, necesito algo básico, por lo que no es necesario abrir puertos para IMAP y POP. Además, puedo mantener el puerto 25 de salida siempre cerrado, y que se abra dinámicamente solo cuando vaya a enviar un correo (que creo que va a ser muy ocasional). De esta manera simplifico la seguridad y la infraestructura de mi correo. También lo pienso porque a largo plazo quiero montar una empresa o fundación y quiero demostrar que es posible ahorrar mucho si se simplifican las cosas. Las grandes corporaciones tienen problemas de ineficiencia y de sobregasto porque sobrecomplican la infraestructura en la que se sostienen. Una infraestructura pequeña, programas que actúen de manera primitiva y eficiente, sin ocupar mucha memoria, sin necesitar demasiados casos a los cuales acudir, sin duda es una gran respuesta para mostrar que existe un camino que prioriza un modo de eficiencia distinto, donde no se necesita un sistema de colaboración jerarquizado y atomizado en cargos.

SMTP

Cuando se habla de correos electrónicos se habla de SMTP, que es el estandar de mensajería por correo. SMTP fue creada en el año https://www.rfc-editor.org/rfc/rfc5321

La reputación de las direcciones IP

Cualquier computadora con el puerto 25 abierto puede enviar correo usando SMTP. El problema es que las grandes compañías no aceptan correos de cualquier IP por seguridad y para evitar el spam. Por eso mismo, muchos proveedores cloud y VPS no permiten abrir el puerto 25 saliente para enviar correo, pues si sus usuarios empezaran a usar sus direcciones IP para enviar spam, estas perderían reputación ante los grandes servicios de correo. Por otro lado, las direcciones IP domésticas tampoco gozan de buena reputación para enviar correo y serán directamente rechazadas.

La reputación aplica para enviar correos, no para recibirlos. Por eso los proovedores cloud tienen el puerto 25 abierto para recibir correo y también se podría usar la IP de una red doméstica para recibir correo sin problemas.

El dominio y DNS

Acabo de descubrir que, con SMTP puro, cualquier dirección IP puede hacerse pasar por cualquier dominio y usuario sin ningún tipo de restricción. Por eso, con el tiempo se han ido incorporando medidas que no forman parte del protocolo original y que buscan corregir, al menos en parte, estas vulnerabilidades. Casi todas dependen de un tipo de registro DNS llamado TXT, que, como su nombre indica, devuelve texto cuando se le hace una consulta.

Funciona así: cuando un servicio de correo recibe un mensaje, realiza varias consultas DNS que devuelven texto, y ese texto le permite verificar si el emisor proviene de un servidor legítimo o no. Las consultas son las siguientes:

  • SPF (Sender Policy Framework): el servicio receptor consulta el registro TXT del dominio del remitente y obtiene una lista de IPs autorizadas para enviar correo en su nombre. Si la IP del servidor emisor no está en esa lista, el correo es sospechoso.

  • DKIM (DomainKeys Identified Mail): el servidor emisor firma criptográficamente cada mensaje con una clave privada. El servicio receptor consulta el registro TXT del dominio para obtener la clave pública y verifica que la firma es válida. Si alguien modificó el mensaje en tránsito, la firma no coincide.

  • DMARC (Domain-based Message Authentication, Reporting and Conformance): el servicio receptor consulta el registro TXT _dmarc.dominio.com y obtiene la política del dominio: qué hacer si SPF o DKIM fallan. Las opciones son none (solo reportar), quarantine (mandar a spam) o reject (rechazar directamente).

El problema para mi caso es que no tenía ninguna de estos tres registros configurados en mi DNS, lo cual hace mucho más fácil para los hackers usar mi dominio para enviar spam. Por eso, decidí usar SPF y DMARC para decirle a los servicios de correo que bloqueen cualquier recepción de correo desde mi dominio y así mantenerlo límpio y con una buena reputación.

A continuación muestro en una tabla los registros que agregué:

Type Name Content
TXT * "v=spf1 -all"
TXT _dmarc "v=DMARC1; p=reject; rua..."
TXT @ "v=spf1 -all"

IMAP — Por qué no usarlo

Se podría pensar que lo más lógico para manejar los correos que me llegan al servidor desde mis dispositivos sería usar IMAP y conectarlo a algún cliente de correo. Sin embargo, esto me parece que trae muchas complicaciones innecesarias. Por ahora el correo lo usaré muy poco: solo necesito tener un buzón desde donde recibir códigos de seguridad y poder crear cuentas en diferentes plataformas usando mi dominio. Para eso me basta con leer directamente el formato Maildir con un lector de correos básico en mi servidor o bien leer los archivos en texto plano. No necesito más. Si en un futuro necesitase ver mi correo más frecuentemente, podría crear una pequeña aplicación que leyera los correos en tiempo real usando TCP básico con cifrado asimétrico; sería súper seguro y simple. Y bueno, si el correo empezara a necesitar muchas más cosas, contrataría un servicio de terceros que garantice cierta privacidad, como lo puede ser Proton.

Los Estándares de buzón de correo – Mbox y Maildir

Existen dos estándares para guardar el buzón de correo en la computadora: Mailbox y Maildir.

Mbox

Mbox es el formato más antiguo de los dos. Se trata de un archivo de texto en donde los correos se concatenan uno tras otro. Cada mensaje se separa con el una línea que empieza con From para separar cada mensaje.

Maildir

Maildir crea un directorio Maildir en donde cada correo se recibe como un archivo diferente independiente dentro de una estructura de carpeta. El buzón de Maildir se organiza en tres subdirectorios:

  • tmp/: donde se escribe el mensaje mientras llega, antes de confirmarse.
  • new/: mensajes recibidos pero que aún no se han leído.
  • cur/: mensajes leídos.

Elección Personal

Entre las dos opciones elijo Maildir: al guardar cada correo en un archivo separado, un fallo afecta solo a un mensaje y nunca al buzón completo. Además evita bloqueos, agiliza el borrado y simplifica los respaldos.

Configurar OpenSMTP

Creo que OpenSMTP es la mejor opción para mí porque es muy liviano y sencillo de usar. Mostraré como lo instalé y configuré en mi servidor Ubuntu.

  1. Instalar OpenSMTP con sudo apt install opensmtpd
  2. Editar el archivo/etc/smtpd.conf. Yo lo dejé así:
#       $OpenBSD: smtpd.conf,v 1.10 2018/05/24 11:40:17 gilles Exp $

# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.

#table aliases file:/etc/aliases

# Users Table
table accounts file:/etc/mail/accounts

# Domains Table
table domains file:/etc/mail/domains

# To also accept external mail over IPv4 or IPv6,
# respectively replace "listen on localhost" with:
#
# listen on 0.0.0.0
# listen on ::
listen on localhost
listen on 1.1.1.1

action "receive" maildir "/var/mail/%{dest.domain}/%{dest.user}/Maildir" virtual <accounts>
action "send" relay

# Rules
match for local action "receive"
match from any for domain <domains> action "receive"
#match from local for any action "send"

Creo que todo es bastante entendible salvo las tablas. Las tablas permiten añadir listas de datos para controlar el comportamiento de SMTP.

En el caso de la tabla domains, la uso para definir sobre qué dominios se recibe correo. Si un mensaje no pertenece a alguno de los dominios de la lista, el servidor simplemente lo rechaza.

La segunda tabla se llama virtual. Por defecto, el servidor de correo asocia cada destinatario con un usuario del sistema y le entrega el correo directamente. Como este enfoque resulta algo arcaico, no lo usaré. En su lugar empleo virtual, que permite vincular el nombre de cada destinatario a cualquier usuario del sistema. En este caso, todas las direcciones de destino apuntan al usuario mail, que ya viene incluido en Linux.

Muestro un ejemplo de como podría ser la tabla /etc/mail/accounts:

# Accounts
caballo@equitacion.com mail
koala@perezita.net mail
leon@selva.org mail

La tabla de dominios contiene un único valor; en realidad funciona más como una lista.

Muestro un ejemplo de cómo podría ser la tabla /etc/mail/domains:

# Domains
equitacion.com
perezita.net
selva.org

Con esto todo esta más o menos configurado.

  1. Chequear configuración usando smtpd -n.
  2. Reiniciar el servidor usando sudo systemctl restart opensmtpd

Mutt - Cliente de Maildir y Mailbox

Mutt es un cliente de correo de texto que es bastante simple de usar y sobretodo me gusta porque permite leer el correo en directorios personalizados.

Abrir correo en directorio un personalizado

Por defecto mutt busca el correo en los directorios /home/user/Mail o bien en /var/user/Mail. Para cambiar a una carpeta personalizada se debe usar:

mutt -f ./directorio

Desactivar advertencia de falta de carpeta Mail de usuario

Al iniciarse, mutt busca el correo en los directorios mencionados anteriormente, incluso cuando se ha seleccionado un directorio personalizado. Si esos directorios no existen, muestra una advertencia indicando que la carpeta no se encuentra y pregunta si se desea crearla.

Para eliminar esta advertencia en todos los usuarios del sistema, basta con modificar el archivo /etc/Muttrc y fijar la carpeta en /dev/null.

# Disable message warning that the user folder doesn't exist
set folder=/dev/null

Abrir Mutt como mail

Por defecto, al ejecutar mutt el programa se inicia con el usuario de la sesión actual. Si se necesita que se ejecute como el usuario mail, se puede forzar mediante sudo:

sudo -u mail mutt -f .

Cambiar de usuario requiere privilegios de root, por lo que el comando anterior solicitará una contraseña cada vez que se ejecute. Para evitarlo, se puede crear un archivo de configuración dentro de /etc/sudoers.d, siguiendo la convención de nombre usuario-comando. En este caso se llamará usuario-mutt:

usuario ALL=(mail) NOPASSWD: /usr/bin/mutt

Con esta regla, al ejecutar sudo -u mail mutt ... el sistema ya no pedirá ninguna contraseña.

Como último paso, se puede un alias para no tener que anteponer sudo -u mail manualmente en cada ejecución:

alias mutt="sudo -u mail mutt"

A partir de ahora, basta con escribir mutt para que el programa se ejecute como el usuario mail.