pop_email-dondocker

Servidor de correo electrónico con contenedores Docker

Hemos explicado como distribuir contenedores docker (Redes con varios host)entre varios host para que tu aplicación crezca o como crear contenedores docker con MongoDB para tus aplicación pero los contenedores docker no solo sirven para ejecutar tus aplicaciones.

En algunas ocasiones antes de instalar una librería o cualquier utilidad la instalo antes en un contenedor y compruebo como funciona.

Otra de las cosas para las que uso docker y que va a centrar el contenido de este post es para tener un servidor de correo electrónico con contenedores Docker. He tenido malas experiencias configurando este tipo de servidores.

Por explicar un poco de cultura general un servidor de correo tradicional (hablamos de software libre) se descompone básicamente en:

  • Servicio de MTA: normalmente solemos usar postfix o exim se encarga básicamente de enviar y recibir correo comunicandose con otros servidores.
  • Sistema de acceso a los correos: uso dos protocolos distintos POP3 o IMAP. El software más común para estas tareas es Dovecot.
  • Servicio LDA: suele hacerlo el propio Dovecot y su función es mover correos que están en cola a los buzones locales de cada usuario.
  • Antispam: es un servicio que detecta si el correo es o no legítimo para el usuario de destino. Es una de las partes más importantes del sistema: ¿quién no recibe spam?. El software más usado es Spamassassin.
  • Antivirus: otro servicio vital y se encarga de escanear cada correo que llega con adjuntos para ver si este es o no un virus. Existen opciones como ClamAV o Amavis que gestiona virus y Antispam

Aunque parezca lioso, todavía faltan más elementos como podría ser el protocolo o método para autenticar a los usuarios (en servidores pequeños se usa un fichero plano o mysql y en grandes empresas usan LDAP) También la disponibilidad del clásico webmail por si no queremos configurar un cliente de correo electrónico, eso implicaría disponer de un servidor web y RoundCube o SquirrelMAil ambos webmail de software libre.

Todos los componentes del servidor SMTP

Con todos estos elementos bien configurados y sincronizados dispondremos de un servicio de correo, que llegados a este punto parece más sencillo contratar el servicio que ponernos con ello. Pero gracias a los contenedores docker esto no va a ser necesario.

SMTP con tvial/docker-mailserver

Este contenedor es un todo en uno o mejor dicho un casi todo en uno porque no tendremos algunos servicios como webmail o una forma de gestionar un gran volumen de usuarios. A cambio vamos a poder configurar un servidor SMTP con una linea, al estilo docker.

Esta imagen trae un par de servicios que no hemos comentado antes:

  • LetsEncript, un sistema para renovar y mantener certificados TLS. Facilita mucho el mantenimiento ya que últimamente se tienende a usar las versiones seguras de los protocolos IMAPS o SMTPS con certificados.
  • OpenDKIM, es una implementación gratuita de DKIM que sirve para evitar que nos falsifiquen el campo From: de los correos. Es una firma criptográfica para cada cuenta de correo.

Lo primero será descargarnos el contenedor:

>_ docker pull tvial/docker-mailserver

Ahora solo tenemos que levantar el servidor facilitando los puertos correspondientes para cada servicio.

Los puertos son:

  • 25, es el puerto estandar para el servicio SMTP
  • 143, para el IMAP
  • 143, para el I587, puerto para el SMTP
  • 143, para el I993, puerto para el IMAP seguro o IMAPS

Con estos puertos vamos a configurar el fichero docker-compose.yml para que sea más sencillo crear la máquina.

version: '2'

services:
  mail:
    image: tvial/docker-mailserver:latest
    hostname: mx
    domainname: midominio.com
    container_name: mail
    ports:
    - "25:25"
    - "143:143"
    - "587:587"
    - "993:993"
    volumes:
    - maildata:/var/mail
    - ./config/:/tmp/docker-mailserver/

volumes:
  maildata:
    driver: local

Ahora simplemente arrancamos la máquina:

>_ docker-compose up -d

Esto arrancará los servicios pero no hemos configurado ninguna cuenta todavía. Como hemos explicado antes el contenedor no usa ningún servicio para registrar los usuarios o dominios y lo hace directamente sobre un fichero. Pero este fichero tiene un formato peculiar ya que encripta los password por lo cual no podemos escribirlo directamente.

Para ello contamos con el comando doveadm que entre las opciones de las que dispone, está la opción de generar contraseñas que usaremos para tal efecto. (Otras opciones de doveadm).

>_ doveadm pw -s schema -u user -p password 

Este comando devuelve el password encriptado con una de las tres opciones disponibles:

  • BLF-CRYPT: Usa criptografía Blowfish considerada como muy segura. El password empieza con $2a$.
  • SHA512-CRYPT: Sistema de encriptación muy potente. Empieza con $6$
  • SHA256-CRYPT: Sistema de encriptación muy potente. Empieza con $5$
  • MD5-CRYPT: Es el método usado en linux para el fichero /etc/shadow. Será el método que usemos. El password empieza por $1$.

El script de arranque usa un fichero postfix-accounts.cf para usarlo en la configuración y que cargar los usuarios. Por tanto para crear el usuario podemos usar el propio contenedor de esta forma:

>_ mkdir -p config
>_ docker run --rm \
  -e MAIL_USER=user1@domain.tld \
  -e MAIL_PASS=mypassword \
  -ti tvial/docker-mailserver:latest \
  /bin/sh -c 'echo "$MAIL_USER|$(doveadm pw -s CRAM-MD5 -u $MAIL_USER -p $MAIL_PASS)"' >> config/postfix-accounts.cf

De esta manera cuando reiniciamos el contenedor utilizará esa configuración y añadiremos al nuevo usuario.

El sistema es limitado si tuviésemos administrar muchos dominios con cientos de cuentas. Para estos casos el sistema no sería eficiente y tendríamos que pensar en acoplar una base de datos o LDAP.

Verificar el funcionamiento

Puede ser una de los servicios más complejos de verificar. Para ello vamos a usar los comandos de SMTP y IMAP. Por otro lado vamos a obviar todo lo que tiene que ver entre comunicación de servidores y resolución de registros mx

La primera verificación que vamos a hacer es comprobar como un hosts nos envía un correo. La cuenta con la que vamos a probar debe existir ya que nuestro servidor tiene entre sus reglas el que exista la cuenta y esté asociada al dominio que dice.

>_ dig dominio-mi-cuenta.com MX
ns2.dominio-mi-cuenta.com.      65414   IN  A   0.0.0.1
ns1.dominio-mi-cuenta.com.      64508   IN  A   0.0.0.10

Ahora nos conectamos a nuestro contenedor usando telnet al puerto SMTP

>_ telnet 172.17.0.4 25
EHLO ns2.dominio-mi-cuenta.com 
250-PIPELINING
250-SIZE 21851332
250-VRFY
250-ETRN
.....
MAIL FROM:<cuenta@dominio-mi-cuenta.com>
250 2.1.0 Ok
RCPT TO:<cuenta-probar@dominio-prueba.com>
250 2.1.0 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Esto es una prueba
.
250 2.0.0 Ok: queued as EF3ADE7ED
quit

Con esto hemos simulado un envío de cuenta@dominio-mi-cuenta.com a cuenta-probar@dominio-prueba.com. Ahora vamos a probar el envío desde el servidor. Tenemos que tener en cuenta que el destino puede tener métodos antispam que nos dificulte el enviarle correos. Por ello se recomiendo no usar destinos como Gmail o Hotmail porque aunque lleguemos a encolar un correo el antispam lo para.

>_ telnet 172.17.0.3 25
Trying 172.17.0.3...
Connected to 172.17.0.3.
Escape character is '^]'.
220 mail.domain.com ESMTP Postfix (Ubuntu)
EHLO seldon
250-mail.domain.com
250-PIPELINING
250-AUTH PLAIN LOGIN
...
250 DSN
AUTH LOGIN
334 VXNlcm5hbWU6
ZGVtb0BkYmJveC5jb20=
334 UGFzc3dvcmQ6
MTIzNDU2
235 2.7.0 Authentication successful
MAIL FROM:<demo@dbbox.com>
250 2.1.0 Ok
RCPT TO:<cuenta@gmail.com>
250 2.1.5 Ok
DATA
354 End data with <CR><LF>.<CR><LF>
Subject: Es una prueba
El oso y el madroño
del mundo
.
250 2.0.0 Ok: queued as B0023717
quit
221 2.0.0 Bye
Connection closed by foreign host.

Tanto el usuario como ZGVtb0BkYmJveC5jb20= y contraseña MTIzNDU2 están convertidos a base64, podemos hacerlo así:

>_ echo -n ‘demo@dbbox.com’ | base64

Para comprobar el IMAP vamos a usar openssl por la encriptacion:

>_ openssl s_client -connect 172.17.0.3:143 -starttls imap
. OK Pre-login capabilities listed, post-login capabilities have more.
a login demo@dbbox.com 123456
a OK Logged in
a list "" "*"
* LIST (\HasNoChildren \Trash) "." Trash
* LIST (\HasNoChildren \Sent) "." Sent
* LIST (\HasNoChildren \Drafts) "." Drafts
* LIST (\HasNoChildren) "." INBOX
a OK List completed.
a select INBOX
* FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
* OK [PERMANENTFLAGS (\Answered \Flagged \Deleted \Seen \Draft \*)] Flags permitted.
* 1 EXISTS
* 1 RECENT
* OK [UNSEEN 1] First unseen.
* OK [UIDVALIDITY 1465058954] UIDs valid
* OK [UIDNEXT 2] Predicted next UID
* OK [NOMODSEQ] No permanent modsequences
a OK [READ-WRITE] Select completed (0.001 secs).

Con esto verificamos que hay un mensaje disponible en INBOX que es el que mandamos al principio. Con estas pruebas verificamos que podemos enviar, recibir mensajes y luego leer los mensajes con un cliente IMAP.

El siguiente paso es ponerlo en producción y configurar los registros MX de los dominios para que los otros servidores sepan cual es el host de nuestro dominio.

Como siempre gracias por leer nuestros post y nos gustaría que nos comentaras que te ha parecido el post.

One thought on “Servidor de correo electrónico con contenedores Docker

  • hotmail correo

    You ought to take part in a contest for one of the finest websites on the net.
    I will highly recommend this site!

    Responder

Leave a comment

Tu dirección de correo electrónico no será publicada. Los campos necesarios están marcados *