Esta pagina se ve mejor con JavaScript habilitado

Sistema de correo con Postfix-Dovecot-MySQL-OpenDKIM

 ·  🎃 kr0m

En esta ocasión os traigo material de primera, vamos a montar un sistema de correo con el cual el receptor del mail podrá cerciorarse de que el origen del email somos nosotros y no otra persona suplantando nuestra identidad.

Para ello utilizaremos SPF y DKIM:

  • SPF: Entrada TXT en la zona DNS del dominio que se está utilizando para enviar mails donde se indican las ips de los servidores SMTP del dominio
  • DKIM: Firma criptográfica publicada en un registro TXT del dominio, firmando con la clave pública en el servidor el receptor será capaz de comprobar que el email es nuestro leyendo la clave pública del DNS
  • MX: Entrada DNS en la que se indica a que equipo se debe enviar el correo entrante para ese dominio

NOTA: La firma consiste en cifrar con la clave privada del servidor el md5 de las cabeceras y el cuerpo del email, el receptor mediante la clave pública publicada en los DNS puede asegurarse de que esos datos no han sido alterados como tiene un MD5 totalmente fiable puede  calcularlo él localmente, si el recibido y el calculado coinciden el email es correcto. Para que esto falle se debería de llegar a hackear el servidor DNS alterando la clave pública de dicho dominio.

Para el envío de emails se ha optado por Postfix por su rapidez, para el acceso a los emails se ha optado por Dovecot por estar centrado en la seguridad desde la base, los dos sistemas utilizarán una base de datos MySQL para la autenticación pero teniendo en cuenta que Postfix empleará DovecotSASL como backend de autenticación, es decir Postfix no accederá directamente a la base de datos si no que realizará la petición mediante SASL a Dovecot y este consultará la DB.

Compilamos Postfix con soporte para MySQL y DovecotSASL:

vi /etc/portage/package.use/postfix

=mail-mta/postfix-2.10.2 mysql dovecot-sasl
emerge -av mail-mta/postfix
vi /etc/portage/package.use/dovecot
=net-mail/dovecot-2.2.5 mysql
emerge -av dovecot

Configuramos Dovecot:

emerge --config dovecot
chmod 600 /etc/dovecot/dovecot.conf

Las conexiones IMAP irán cifradas con un certificado autofirmado, así que debemos generar la petición de certificado y firmarnosla:

cd /etc/ssl/dovecot/
openssl genrsa -out mail.alfaexploit.com.key 2048
openssl req -new -key mail.alfaexploit.com.key -out mail.alfaexploit.com.csr
openssl x509 -req -days 3650 -in mail.alfaexploit.com.csr -signkey mail.alfaexploit.com.key -out mail.alfaexploit.com.crt
cat mail.alfaexploit.com.key » mail.alfaexploit.com.pem
cat mail.alfaexploit.com.crt » mail.alfaexploit.com.pem
chmod 400 mail.alfaexploit.com.*

Yo personalmente tengo preferencia por el protocolo IMAP así que deshabilito el resto:

vi /etc/dovecot/dovecot.conf

#protocols = imap pop3 lmtp
protocols = imap
listen = *
dict {
  #quota = mysql:/etc/dovecot/dovecot-dict-sql.conf.ext
  #expire = sqlite:/etc/dovecot/dovecot-dict-sql.conf.ext
}
!include conf.d/*.conf
!include_try local.conf

disable_plaintext_auth = yes
ssl = yes
ssl_cert =</etc/ssl/dovecot/mail.alfaexploit.com.pem
ssl_key =</etc/ssl/dovecot/mail.alfaexploit.com.key
mail_location = maildir:~/.maildir
vi /etc/dovecot/conf.d/10-ssl.conf
ssl = yes
ssl_cert = </etc/ssl/dovecot/mail.alfaexploit.com.pem
ssl_key = </etc/ssl/dovecot/mail.alfaexploit.com.key

NOTA: ntpclient no funciona muy bien en combinación de Dovecot, es preferible utilizar ntpd y asegurarse que el script de dovecot requiera ntpd antes de arrancar.

emerge -av ntp
vi /etc/init.d/dovecot
depend() {
        need localmount ntpd

Configuramos la base de datos de usuarios MySQL.

Si es una instalación nueva asignamos un password(cuidado con los carácteres extraños):

openssl rand -base64 12
emerge -av mysql
emerge --config mysql

Creamos la base de datos y la tabla:

CREATE database postfix CHARACTER SET utf8 COLLATE utf8_general_ci;
USE postfix;
CREATE TABLE users ( username VARCHAR(128) NOT NULL, domain VARCHAR(128) NOT NULL, password VARCHAR(64) NOT NULL, home VARCHAR(255) NOT NULL, uid INTEGER NOT NULL, gid INTEGER NOT NULL, active CHAR(1) DEFAULT 'Y' NOT NULL );

Creamos el usuario de acceso a la base de datos:

use mysql GRANT ALL PRIVILEGES ON postfix.* TO postfix@localhost IDENTIFIED BY 'XXXXXXX';
FLUSH RIVILEGES;

Configuramos el modo en que Dovecot debe consultar la DB:

vi /etc/dovecot/dovecot-sql.conf.ext

driver = mysql
connect = dbname=postfix user=postfix host=localhost password=XXXXXXX
default_pass_scheme = PLAIN
password_query = SELECT password FROM users WHERE username = '%u'
user_query = SELECT home, uid, gid FROM users WHERE username = '%u'
vi /etc/dovecot/conf.d/10-master.conf
service imap-login {
  inet_listener imap {
    #port = 143
  }
  inet_listener imaps {
    #port = 993
    #ssl = yes
  }
}

service pop3-login {
  inet_listener pop3 {
    #port = 110
  }
  inet_listener pop3s {
    #port = 995
    #ssl = yes
  }
}

service lmtp {
  unix_listener lmtp {
    #mode = 0666
  }
}

service auth {
  unix_listener auth-userdb {
  }

  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0666
    user = postfix
    group = postfix
  }
}

service auth-worker {
}

service dict {
  unix_listener dict {
  }
}

Habilitamos el auto creado de directorios:

vi /etc/dovecot/conf.d/20-imap.conf

protocol imap {
mail_plugins = $mail_plugins autocreate
}

plugin {
autocreate = Trash
autocreate2 = Junk
autocreate3 = Drafts
autocreate4 = Sent
autosubscribe = Trash
autosubscribe2 = Junk
autosubscribe3 = Drafts
autosubscribe4 = Sent
}

Vaciamos la config auth-system:

> /etc/dovecot/conf.d/auth-system.conf.ext

useradd -m -G users,wheel -s /bin/bash user00
grep user00 /etc/passwd –> UID
grep user00 /etc/group –> GID

mysql -u root -p
use postfix
INSERT INTO users (username, domain, password, home, uid, gid, active) VALUES ('user00@alfaexploit.com', 'alfaexploit.com', 'XXXXXXXX', '/home/user00', 'UID', 'GID', 'Y');

Generamos el certificado autofirmado del Postfix:

cd /etc/ssl/postfix
openssl genrsa -out mail.alfaexploit.com.key 2048
openssl req -new -key mail.alfaexploit.com.key -out mail.alfaexploit.com.csr
openssl x509 -req -days 3650 -in mail.alfaexploit.com.csr -signkey mail.alfaexploit.com.key -out mail.alfaexploit.com.crt
cat mail.alfaexploit.com.key » mail.alfaexploit.com.pem
cat mail.alfaexploit.com.crt » mail.alfaexploit.com.pem
chmod 400 mail.alfaexploit.com.*

Configuramos Postfix para que utilice Dovecot como autenticador mediante SASL, Dovecot se conectará a la base de datos MySQL:

vi /etc/postfix/main.cf

queue_directory = /var/spool/postfix
command_directory = /usr/sbin
daemon_directory = /usr/libexec/postfix
data_directory = /var/lib/postfix
mail_owner = postfix
myhostname = mail.alfaexploit.com
mydomain = alfaexploit.com
inet_interfaces = all
mydestination = $myhostname, localhost.$mydomain, localhost, $mydomain
unknown_local_recipient_reject_code = 550
mynetworks = 127.0.0.0/8
home_mailbox = .maildir/
debug_peer_level = 2
debugger_command =
         PATH=/bin:/usr/bin:/usr/local/bin:/usr/X11R6/bin
         ddd $daemon_directory/$process_name $process_id & sleep 5
sendmail_path = /usr/sbin/sendmail
newaliases_path = /usr/bin/newaliases
mailq_path = /usr/bin/mailq
setgid_group = postdrop
html_directory = no
manpage_directory = /usr/share/man
sample_directory = /etc/postfix
readme_directory = no
inet_protocols = ipv4
local_destination_concurrency_limit = 2
default_destination_concurrency_limit = 10

# AUTENTICACION EMPLEANDO DOVECOT:
smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_sasl_authenticated_header = yes
smtpd_sasl_security_options = noanonymous
smtpd_sasl_local_domain = alfaexploit.com
local_header_rewrite_clients = permit_mynetworks
broken_sasl_auth_clients = yes
smtpd_authorized_xforward_hosts = $mynetworks

# Parametro de filtrado relay en postfix >=2.10
smtpd_relay_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination
#smtpd_recipient_restrictions = permit_mynetworks, permit_sasl_authenticated, reject_unauth_destination

# TLS stuff - Enable if you want to use SMTP over SSL
smtpd_use_tls = yes
smtpd_tls_key_file = /etc/ssl/postfix/mail.alfaexploit.com.key
smtpd_tls_cert_file = /etc/ssl/postfix/mail.alfaexploit.com.pem
#mtpd_tls_CAfile = /etc/ssl/postfix/cacert.pem
smtpd_tls_loglevel = 0
smtpd_tls_received_header = yes
smtpd_tls_session_cache_timeout = 3600s
tls_random_source = dev:/dev/urandom
local_recipient_maps =
alias_maps = hash:/etc/mail/aliases

# INFGb de adjuntos:
message_size_limit = 0
mailbox_size_limit = 0

Ponemos postfix en verbose para hacer pruebas:

vi /etc/postfix/master.cf

smtp      inet  n       -       n       -       -       smtpd -v

Compilamos las librerias SASL:

emerge -av dev-libs/cyrus-sasl
/etc/init.d/saslauthd start
rc-update add saslauthd default

Añadimos un alias del usuario root:

vi /etc/mail/aliases

root:            user00@alfaexploit.com
postmap /etc/mail/aliases
/etc/init.d/postfix restart

Para que los servidores de mail puedan hacer la entrega del mail a nuestro PostFix hay que configurar una entrada MX con la ip del PostFix, dependiendo de si tenemos nuestro propio servidor DNS o si dependemos de uno externo se hará editando directamente la zona o a través del panel web del ISP, para comprobar que la configuración es correcta:

dig @8.8.8.8 MX alfaexploit.com

alfaexploit.com. 21600 IN MX 1 mail.alfaexploit.com.
dig @8.8.8.8 mail.alfaexploit.com
mail.alfaexploit.com. 21600 IN A A.B.C.D

NOTA: Si no configuramos bien las entradas DNS y realizamos una query esta quedará cacheada en los servers DNS a los que les hayamos hecho la petición, aunque rectifiquemos el error el dns no se propagará hasta que la caché venza, en el ejemplo anterior la caché es de 21600s.

Añadimos todos los servicios configurados al runlevel default:

rc-update add mysql default
rc-update add postfix default
rc-update add dovecot default
rc-update add ntpd default

En este momento ya podríamos enviar y recibir email, en thunderbird por lo menos la config sería:

STARTTLS -- Contraseña normal

Ahora nos preocuparemos de la configuración de OpenDKIM:

emerge -av opendkim

NOTA: El opendkim-genkey de los repos parece que genera las entradas de DNS un poco raras.

La versión utilizada:

opendkim-genkey v2.7.4

Así que yo utilizaré este script anterior que se seguro que funciona correctamente, si no os fiais de mi script(no deberiáis de fiaros nunca de nadie) siempre podéis utilizar el recién instalado que seguramente funcione correctamente o revisar el código fuente comprobando que no hace nada raro.

Generamos la clave pública y la privada:

cd /root
./opendkim-genkey -s smtp -d alfaexploit.com
cp smtp.* /etc/opendkim/

El contenido de smtp.txt debería de ser algo parecido a esto:

smtp._domainkey IN TXT "v=DKIM1; r=postmaster; g=*; k=rsa;
p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADdDSs33fds3s42sDS3DSFEG54GHJHJKL9WeUF2QK4o+HC9kNkN3M3LdXdCQxtDBb5afEOrk9wQjSqJre6v2sa4fGGG4343f0fsdfsdf5FAynjoVza8oSV5qXeGmqUGetEUQZV4qSO0oE5IOmLHNPStuQUgCuBIdPv9dVkWXpLHd1wIDAQAB"; ----- DKIM dkm for alfaexploit.com

Configuramos el dominio en OpenDKIM:

vi /etc/opendkim/opendkim.conf

Syslog                  yes
SyslogSuccess           yes
Canonicalization    relaxed/relaxed
Domain          alfaexploit.com
Selector        smtp
KeyFile         /etc/opendkim/smtp.private
Socket                  inet:8891@localhost
ReportAddress           sys@alfaexploit.com
SendReports             yes
PidFile /var/run/opendkim/opendkim.pid
UserID milter
Statistics /var/lib/opendkim/stats.dat

Configuramos PostFix para que utilize un milter(filtro) en este caso OpenDKIM:

vi /etc/postfix/main.cf

mydomain = alfaexploit.com

# Milter Configuration:
milter_default_action = accept
milter_protocol = 6

smtpd_milters = unix:/var/run/dk-filter/dk-filter.sock, inet:127.0.0.1:8891
non_smtpd_milters =

NOTA: El milter versión depende de la versión de postfix, podemos saber la versión con:

postconf -d mail_version

mail_version = 2.10.2
# Postfix ≥ 2.6
milter_protocol = 6
# 2.3 ≤ Postfix ≤ 2.5
milter_protocol = 2

NOTA: El tamaño máximo de todas las entradas DNS no puede exceder 512 bytes, en caso de utilizar varios sistemas de firmado de emails deberíamos de configurar la misma key para los dos sistemas ;)

Arrancamos el servicio de OpenDKIM y lo añadimos al runlevel default:

/etc/init.d/opendkim restart
/etc/init.d/postfix restart

rc-update add opendkim default
rc-update add postfix default

Ahora publicaremos una entrada TXT en la zona DNS del dominio en cuestión con el contenido de:

cd /etc/opendkim/
cat smtp.txt

Podemos comprobar que se ha publicado correctamente mediante:

dig @8.8.8.8 TXT smtp._domainkey.alfaexploit.com

Deshabilitamos el debug de Postfix:

vi /etc/postfix/master.cf

smtp      inet  n       -       n       -       -       smtpd
/etc/init.d/postfix restart

Otro factor a tener en cuenta es que la ip y el nombre de nuestro servidor de mail cuadren la directa y la reverse:

dig mail.alfaexploit.com

mail.alfaexploit.com. 59 IN A A.B.C.D
host A.B.C.D
D.C.B.A....... domain name pointer mail.alfaexploit.com.

Esto se consigue configurando la reverse del siguiente modo en caso de tener delegada la resolución en un servidor nuestro:

vi /etc/bind/C.B.A.zone

D IN PTR mail.alfaexploit.com.

Si la resolución la hace un ISP tendremos que configurarlo mediante la interfaz web proporcionada por este, la verdad es que es raro que nos deleguen la resolución inversa a no ser que nos llevemos muy bien con nuestro ISP.


Finalmente configuraremos los registros DNS-SPF para que cuando gmail, hotmail… reciban e-mails de nuestro dominio pueda comprobar que efectivamente fué enviado desde uno de nuestros servidores.

Configuramos una entrada TXT en la zona del dominio con el siguiente contenido:

alfaexploit.com. 86400 IN TXT "v=spf1 mx ip4:A.B.C.D -all
alfaexploit.com. 86400 IN TXT "spf2.0/mfrom,pra ip4:A.B.C.D -all"
dig @8.8.8.8 TXT alfaexploit.com

En la entrada anterior estamos indicando que nuestro servidor tiene la ip A.B.C.D y no queremos que se acepten mail de ninguna otra IP(-all), cabe destacar que los registros spf permiten hacer includes de otras entradas TXT por lo tanto podemos mitigar la limitación de los 512 bytes por registro TXT del DNS.

Con esto seremos capaces de entrar en bandeja de entrada en la mayoría de sistemas de mail como gmail, hotmail y demás siempre y cuando no nos pasemos espameando ;)

Si te ha gustado el artículo puedes invitarme a un RedBull aquí