OpenSMTPD es una implementación libre del protocolo SMTP, desarrollado por el equipo de OpenBSD (Gilles Chehade, Eric Faurot y Charles Longeau). Su objetivo es convertirse en un servidor de correo seguro y fiable, sin las restricciones de licencia de Postfix y sin la innecesaria complejidad de Sendmail. Puede usarse como servidor principal de correo, pues es estable, rápido, seguro y fácil de configurar y usar, y y soporta dominios y usuarios virtuales. Pretende también ser fiable y respetar los RFC y los estándares siempre que no vaya en detrimento de la seguridad del conjunto del sistema. Su licencia es la más breve, clara y minimalista de todas las licencias libres conocidas: la ISC, actualmente preferida por el proyecto OpenBSD para su propio código.
Tras cinco años de desarrollo, OpenSMTPD ha alcanzado su fase estable, apta para producción, en marzo de 2013 (OpenBSD 5.3). La pretensión es que llegue a reemplazar a Sendmail como el servidor de correo por defecto en OpenBSD.
En este documento veremos una instalación básica, pero en producción, como servidor MX secundario.
OpenSMTPD viene ya instalado en el sistema base, pero no está activado por defecto. Deberemos realizar algunos cambios para reemplazar a Sendmail, que es el MTA que viene activado por defecto en OpenBSD.
Lo primero es asegurarnos que la cola de correo está vacía. A continuación, detenemos sendmail:
# mailq # /etc/rc.d/sendmail stop
Modificamos en /etc/mailer.conf
los wrappers de correo, para que invoquen a nuestro nuevo MTA (smtpd):
sendmail /usr/sbin/smtpctl send-mail /usr/sbin/smtpctl mailq /usr/sbin/smtpctl makemap /usr/libexec/smtpd/makemap newaliases /usr/libexec/smtpd/makemap
Reconstruimos la base de datos de “alias”, añadimos las líneas necesarias para que cuando arranquemos el sistema no se inicie sendmail sino smtpd, e iniciamos manualmente el demonio smtpd:
# newaliases # echo "sendmail_flags=NO" >> /etc/rc.conf.local # echo "smtpd_flags=" >> /etc/rc.conf.local # /etc/rc.d/smtpd start
Antes de nada, conviene aclarar que la sintaxis de las reglas ha ido cambiando a lo largo del tiempo y que se encuentran algunos howtos en la Red con sintaxis antigua, que hace que no le funcione a quien se decide a probarlo y que desespera a los desarrolladores, que sufren quejas innecesarias. Por favor, revisa siempre la documentación oficial, correspondiente a la versión que usas, donde encontrarás la sintaxis actualizada. Aquí empleamos la correspondiente a la primera versión estable (marzo de 2013).
La configuración de SMTPD es muy intuitiva para quien tenga experiencia previa con PF. En lugar de cientos de directivas al estilo de otros MTA, como Postfix, se basa en un sistema de filtrado con sencillas reglas de aceptar/denegar, como en los firewalls. Para cada mensaje procesado, las reglas de filtrado se evalúan en orden secuencial, de principio a fin. La primera regla que coincide decide qué acción debe tomarse. Si no hay ninguna regla que coincida con el mensaje, la acción por defecto es rechazar el mensaje.
Nuestro objetivo es tener un MTA secundario (mx-bk.example.com) para que, en caso de que nuestro MTA principal (mail.example.com) esté inaccesible (por las razones que sean), acepte correos destinados a dominios del MTA principal y los mantenga en su cola todo el tiempo que sea necesario hasta que el MTA principal esté de nuevo operativo. Cuando esté de nuevo operativo, el MTA secundario se los entregará al MTA principal para que los haga llegar al destinatario de forma transparente.
Las reglas para lograr esto son unas pocas, y muy sencillas, y residen en un solo fichero denominado /etc/mail/smtpd.conf
:
## This is the smtpd server system-wide configuration file. ## See smtpd.conf(5) for more information. ## Filter rules are evaluated in sequential order, from first to last. # To accept external mail: listen on all hostname "mx-bk.example.com" ## Maps table aliases db:/etc/mail/aliases.db # table virtuals db:/etc/mail/virtual.db ## local mail delivery accept for local alias <aliases> deliver to mda "procmail -f -" ## Remote delivery mail through a central mail server (mail.example.com) ## It expires: 30 days (it's a backup) accept from any for domain "example.com" relay via smtp://mail.example.com expire 30d
Chequeamos la sintaxis antes de cargar la nueva configuración:
root@host~# smtpd -n configuration OK root@host~# /etc/rc.d/smtpd restart smtpd(ok) smtpd(ok) root@host:~# tail -f /var/log/maillog Mar 27 16:06:40 ms02 smtpd[16818]: info: OpenSMTPD 5.3 starting Mar 27 16:06:40 ms02 smtpd[704]: info: startup
Para testearlo, detenemos el MTA principal y a continuación enviamos un correo (foobar@gmail.com en este ejemplo) a nuestro dominio (fulano@example.com). El MTA remitente (gmail.com), al detectar que el MTA de destino no acepta correo, lo intentará con nuestro MTA secundario. En los logs del MTA secundario (smtpd) deberíamos ver que en efecto recibe y acepta el correo:
Mar 27 22:38:04 ms02 smtpd[8133]: smtp-in: New session 000000034a4b134f from host mail-bk0-f49.google.com [209.85.214.49] Mar 27 22:38:04 ms02 smtpd[8133]: smtp-in: Accepted message b1dc18bb on session 000000034a4b134f: from=<foobar@gmail.com>, size=1297, nrcpts=1, proto=ESMTP Mar 27 22:38:04 ms02 smtpd[8133]: smtp-in: Closing session 000000034a4b134f
El MTA secundario intenta conectarse con el primario, pero no puede (está caído), así que encola el mensaje:
Mar 27 22:38:07 ms02 smtpd[31516]: relay: TempFail for b1dc18bb93f6e053: from=<foobar@gmail.com>, to=<fulano@example.com>, relay=mail.example.com, delay=3s, stat=No MX could be reached
Podemos comprobar con el wrapper mailq
, tradicional de sendmail, que el correo efectivamente está en la cola:
root@mx-bk:~# mailq b1dc18bb93f6e053|inet4|mta||foobar@gmail.com|fulano@example.com|fulano@example.com|1364420284|1367012284|0|1|pending|327|No MX could be reached
También podemos comprobarlo con los comandos nativos de opensmtpd. La salida es idéntica:
root@mx-bk:~# smtpctl show queue b1dc18bb93f6e053|inet4|mta||foobar@gmail.com|fulano@example.com|fulano@example.com|1364420284|1367012284|0|1|pending|165|No MX could be reached
El formato de la cola es semejante al de Packet Filter. Nos muestra el remitente y el destinatario, y las fechas de entrada en la cola y de expiración, en formato Unix, así como el número de reintentos y su estado. Podemos convertir fácilmente las fechas para verificarlas:
root@mx-bk:~# date -r 1364420284 Wed Mar 27 22:38:04 CET 2013 root@mx-bk:~# date -r 1367012284 Fri Apr 26 23:38:04 CEST 2013
Con el ID del correo, podemos programar la entrega de forma inmediata, caso de que el MTA principal ya esté en pie:
root@mx-bk:~# smtpctl schedule b1dc18bb93f6e053 command succeeded
Vemos en los logs que el correo se entrega correctamente al MTA principal:
Mar 27 22:42:46 ms02 smtpd[31516]: relay: Ok for b1dc18bb93f6e053: from=<foobar@gmail.com>, to=<fulano@example.com>, relay=88.198.50.211 (mail.example.com), delay=4m42s, stat=250 2.0.0 Ok: queued as 463D042F048
La cola ya está vacía:
root@mx-bk:~# mailq root@mx-bk:~#
Si hubiéramos querido borrar ese mismo mensaje de la cola (por tratarse de una prueba):
root@mx-bk:~# smtpctl remove b1dc18bb93f6e053 command succeeded