7.3.3.5. Acreditación del remitente

En los mensajes de correo hay dos remitentes que pueden coincidir o no:

Remitente del sobre (Envelope sender)

Es el remitente cuya dirección se declara durante el envío del correo a través del comando MAIL FROM. Esta es la dirección a la que el servidor destinatario contestara en caso de que se haya producido un problema en la entrega. Por tanto, no forma parte del mensaje original, pero el servidor la añade a través del campo de cabecera Return-Path:.

Dirección del mensaje

Es la dirección que aparece en el campo de cabecera From:. Por lo general, es tomada por el lector final del mensaje como la dirección del remitente, ya que el campo Return-Path: rara vez se muestra en los clientes de correo.

El protocolo de correo, por su propio diseño, se presta a que un malicioso (frecuentemente un spammer) falsee cualquiera de las dos direcciones, port lo que para detectar estas falsificaciones, se han desarrollado una serie de protocolos que, si no los observamos en nuestro servidor, pueden levantar en otros servidores la desconfianza sobre nuestros mensajes.

7.3.3.5.1. SPF

7.3.3.5.1.1. Concepto

Este protocolo, desarrollado en el RFC 7208, permite al dueño de un dominio definir cuáles son los servidores que utiliza para enviar mensajes de correo de tal dominio1. La información se publica a través de un registro DNS que se describirá más adelante.

Con este protocolo, los servidores destinatarios comprueban si la IP del servidor remitente es alguna de las acreditadas a través del registro SPF correspondiente al dominio de la dirección del remitente del sobre. Trasladando esta explicación a un ejemplo, podríamos ilustrarlo del siguiente modo:

El dueño de la cuenta pepe@gmail.com usará los mecanismos que le proporciona su proveedor de correo (SMTP o el webmail gmail.google.com) para enviar un mensaje a paco@example.com. Esto implica que sea una máquina de Gmail la que se encargue de entregar el mensaje al servidor smtp.example.com. Éste, al recibir el mensaje, registrará la IP de la máquina remitente y, como la dirección del sobre es pepe@gmail.com, para certificar que realmente tal IP es de una máquina de Gmail, realizará las siguientes consultas DNS:

  • ¿Quiénes son las máquinas que se encargan de enviar mensajes del dominio gmail.com?

    # dig +nocmd +noall +answer gmail.com TXT
    gmail.com.              176     IN      TXT     "v=spf1 redirect=_spf.google.com"
    

    Bien, la respuesta no es concluyente. El registro nos dice, simplemente, que lo que diga otro registro.

  • Vale. Pues, ¿qué es lo que dice este registro?

    # dig +nocmd +noall +answer _spf.google.com TXT
    _spf.google.com.        299     IN      TXT     "v=spf1 include:_netblocks.google.com include:_netblocks2.google.com include:_netblocks3.google.com ~all"
    

    La respuesta sigue sin ser del todo concluyente. Nos informa de que las máquinas seran las incluidas en alguno de esos tres registros.

  • Vale. Pues, ¿qué dicen esos registros?

    # dig +nocmd +noall +answer _netblocks.google.com TXT
    _netblocks.google.com.  2480    IN      TXT     "v=spf1 ip4:35.190.247.0/24 ip4:64.233.160.0/19 ...mas_ips... ~all"
    

Ahí sí están referidos todos los rangos de IP de máquinas autorizadas para enviar mensajes del dominio gmail.com. La IP de la máquina que contactó al servidor smtp.example.net debería estar incluida en uno de esos rangos.

Ver también

Esta misma averiguación podríamos haberla hecho más visualmente desde este enlace.

Hay, no obstante, que hacer dos puntualizaciones respecto a las consultas que permiten acreditar el remitente. Por un lado, no pueden requerirse más de 10 consultas para la obtención de una respuesta. En este caso, han sido un máximo de 5. Por otro lado, el texto de las respuestas no puede contener más de 255 caracteres y esa es la razón por la que los rangos de IP se han dividido en tres registros distintos.

Nota

Observe que esta técnica no previene ninguna suplantación de la dirección del mensaje.

Conocido cómo funciona el protocolo, ¿qué podemos hacer respecto a él con nuestro servidor? Básicamente, dos cosas:

  1. Asegurarnos de incluir en el DNS el registro SPF que acredita nuestro servidor como la máquina emisora de mensajes del dominio. De no existir tal información, podríamos levantar suspicacias en servidores destinatarios y acabar nuestros mensajes en el buzón de spam. Conviene que lea al completo todo el epígrafe siguiente, pero puede saltar directamente a la propuesta de registro.

  2. Incorporar a postfix software que comprueb con SPF el remitente de los mensajes entrantes. Más adelante trataremos cómo hacerlo.

7.3.3.5.1.2. Registro

Los registros de SPF no son un tipo especial de registro DNS, sino un tipo TXT que incluye en la cadena información sobre la aceptación o rechazo:

mail1.org      IN    TXT      "v=spf1 test1 test2 test3 ... testN"

El registro de ejemplo será consultado al recibir mensajes cuyo remitente del sobre sea pepe@mail1.org, usuario@mail1.org o cualquier otra cuenta del dominio mail1.org. La cadena comienza siempre por la definición de la versión del protocolo usada (la versión 1) y una serie de pruebas que se realizan utilizando la IP del remitente como entrada.

Cada prueba consta de:

  • Un cualificador que puede ser:

    Cualificador

    Significado

    +

    PASS, la concordancia devuelve éxito.

    ?

    NEUTRAL, la concordancia no devuelve nada concluyente.

    ~

    SOFTFAIL, la concordancia provoca su marcado como spam.

    -

    FAIL, la concordancia provoca que se rechace el correo.

    Cuando no se especifica cualificador, se sobreentiende «+».

  • Un mecanismo que puede ser:

    Mecanismo

    Significado

    Ejemplo

    all

    Concordancia universal

    -all

    a

    Concordancia con el nombre especificado

    a:smtp.mail1.org

    ip4

    Concordancia con el rango de IPv4 indicado

    ip4:33.34.35.36

    ip6

    Ídem pero para IPv6

    mx

    Concordancia con los servidores de correo

    mx:mail1.org

    include

    Concordancia con las pruebas de otro registro

    include:otromail.org

    Cuando con a o mx no se especifica nombre, se sobreentiende el mismo que el del dominio. En nuestro ejemplo, a equivale a:mail1.org y mx a mx:mail1.org. Además, la última prueba implica siempre el mecanismo all, para que siempre haya una prueba que devuelva concordancia.

    Nota

    También existe, aunque obsoleto, el mecanismo ptr que concuerda si el nombre asociado a la IP del cliente (resolución inversa) está en el dominio proporcionado y tal nombre resuelve a la IP del cliente.

Además de lo anterior podemos usar el modificador redirect (véase el ejemplo ilustrativo del epígrafe anterior) que remite a que se use la política de otro registro.

Por ejemplo, si el registro es:

mail1.org      IN    TXT      "v=spf1 ip4:123.12.0.0/16 mx include:_spf.google.com ~all"

Se obtendría PASS (éxito en la comprobación) si la IP del remitente es de la red 126.12.0.0/16, si coincide con la de alguno de los servidores de correo definidos para el dominio mail1.org o si es una de las máquinas que remite correo de Google. Si no es el caso, la última prueba supone que devolvemos SOFTFAIL y el mensaje debería identificarse como posible spam. Nótese que la segunda y la tercera prueba requieren consultas DNS ulteriores para llegar a obtener una dirección IP numérica.

Para el caso de un servidor modesto como el nuestro, que envía y recibe mensajes, es más que suficiente:

mail1.org      IN       TXT      "v=spf1 mx ~all"

y si tuviéramos algún otro dominio asociado a este servidor:

mail3.org      IN       TXT      "v=spf1 redirect=mail1.org"
ml.mail1.org   IN       TXT      "v=spf1 redirect=mail1.org"

Ver también

En kitterman.com, podemos hacer comprobaciones de registros SPF.

7.3.3.5.1.3. Verificación

Nota

Como alternativa al método explicado aquí, podemos habilitar la verificación SPF del remitente tanto con spamassassin como con rspamd.

Nuestra intención es incluir en la política de aceptación de mensajes de postfix el mecanismo SPF, para lo cual debemos instalar:

# apt install postfix-policyd-spf-python

Advertencia

La comprobación SPF requiere la realización de una ingente cantidad de consultas DNS, de modo que sería conveniente la instalación de un DNS en el propio servidor, si no hay ya uno instalado en la red local.

Hecho esto, debemos añadir a /etc/postfix/master.cf:

policyd-spf  unix  -       n       n       -       0       spawn
    user=policyd-spf argv=/usr/bin/policyd-spf

y añadir a /etc/postfix/main.cf una línea para aumentar la temporización del agente SPF:

policyd-spf_time_limit = 3600

y dejar en las políticas de acceso para el puerto 25 lo siguiente:

port25_recipient_restrictions = permit_mynetworks,
                                reject_unauth_destination,
                                check_policy_service unix:private/policyd-spf,
                                reject_rbl_client zen.spamhaus.org

El agente genera para todos los mensajes procesados un campo de cabecera Received-SPF: con el resultado de la verificación.

Nota

Si preferimos no rechazar los mensajes, aun cuando la verificación genera FAIL, podemos editar /etc/postfix-policyd-spf-python/policyd-spf.conf y dejar:

HELO_reject = False
Mail_From_reject = False

Para comprobar la configuración, podemos utilizar msmtp desde un cliente local que se conecte al puerto 25, para lo cual podemos reaprovechar la configuración anteriomente propuesta para este cliente y añadir una línea para falsear la dirección del sobre:

[...]

account vm25
   auth off
   tls_starttls on
   from spammer@gmail.com

El mensaje puede enviarse ahora:

$ msmtp -a vm25 -t
From: spammer@gmail.com
To: usuario@mail1.org
Subject: Mensaje fraudulento...

Nos hacemos pasar por alguien con cuenta en Gmail

7.3.3.5.2. DKIM

7.3.3.5.2.1. Concepto

El mecanismo de DKIM, descrito en el RFC 6376, permite saber al servidor destinatario que el mensaje proviniente de la dirección del mensaje fue autorizado por el dueño del dominio al que pertenece dicha dirección. Para ello el servidor SMTP remitente aplica firma digital a los mensajes que envía, la cual será verificada en el servidor de destino.

Ver también

Si no tiene claro el concepto, consulte la sección dedicada a la firma digital. Ahora bien, en este caso la firma es absolutamente transparente para los usuarios finales y es sólo un mecanismo que aplican los servidores para juzgar la fiabilidad de los mensajes.

De manera muy resumida el proceso es el siguiente:

  • Con anterioridad, el dueño del dominio debe publicar través de un registro DNS de tipo TXT la clave pública asociada a la clave privada con la que se firman los mensajes.

  • El remitente añade un campo DKIM-Signature: con la firma digital. Para la creación de la firma se usan claves asociadas al dominio de la dirección del mensaje. El campo tiene el siguiente aspecto:

    DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=mail1.org; s=mail;
            t=1545467652; bh=s8zLfuQdHGkvCXnndlQQO/EjIoJDdA+FodZEaFvU2X4=;
            h=From:To:Subject:Date:From;
            b=NIpT52OFx8ty/0/krkt9MtJIN83TVNcoxWkcLtTWEBD1VOzlgHuTtcoJVOsKkBqbU
             YPC9sI4zwQ9mcL4Mr0yNXskXmeAJ6bVMJzgWkKgfkCO6V20Z5pjZ/OPFHV+T3x43US
             cpTYzpwRVtLepxpQ2SJv19KYXnXIGKqIA157GGBC16qc2lwhCGSUY/g6bkmc0b+WpI
             vh8daZPnmKSQqEIEkv3jBADsJ3KlSe/dz3vx1fCbK0azOu2AWNeEZ/mVjSgMLIGaoZ
             BvXY09OqM/v94A8hseGi5HUB0Bxz90bh0Y3U9W9TMk1/wORWmgY5NIAnu3H0PdZtnu
             Qy07Eat+80AeQ==
    
  • El servidor receptor toma el campo anterior, obtiene a través de una consulta DNS la clave pública necesaria, y realiza la comprobación de la firma. El resultado se añade a un campo Authentication-Results con este aspecto:

    Authentication-Results: smtp.mail2.org;
            dkim=pass (2048-bit key; unprotected) header.d=mail1.org header.i=@mail1.org header.b="NIpT52OF";
            dkim-atps=neutral
    

Nota

Observe que en este caso la verificación obra sobre la dirección del mensaje y no sobre la dirección del remitente del sobre.

7.3.3.5.2.2. Implementación

Para implementar DKIM en el correo saliente con postfix, podemos usar el milter OpenDKIM:

# apt install opendkim{,-tools}

La configuración en /etc/opendkim.conf debe quedar del siguiente modo:

Syslog               yes
UMask                007

Canonicalization     relaxed/simple

# Socket dentro de la jaula de postfix.
Socket               local:/var/spool/postfix/var/run/opendkim.sock
PidFile              /var/run/opendkim/opendkim.pid

OversignHeaders      From

# Para habilitar DNSSEC
#TrustAnchorFile       /usr/share/dns/root.key

UserID               opendkim

KeyTable             /etc/opendkim/keytable
SigningTable         /etc/opendkim/signingtable

# El software no respeta lo indicado en /etc/resolv.conf,
# por lo que no usará un servidor local para las resoluciones.
# Si hacemos pruebas internas con dominios inventados
# es indispensable declarar el servidor DNS local.
NameServers          127.0.0.1

Ver también

Puedo consultar que significa la normalización DKIM (Canonicalizaion) en este artículo.

Dado que necesitamos poder escribir dentro de la jaula de postfix, debemos preparar en ella un subdirectorio var/run/ según lo mostrado aquí.

Dado que opendkim necesita firmar, debemos generar las claves:

# opendkim-genkey -D /etc/dkimkeys -r -s mail -d mail1.org
# chown opendkim:opendkim /etc/dkimkeys/mail.*

Esta orden genera las claves para el dominio mail1.org, aunque dentro de la propia clave no está expresado el propio dominio, con lo que podremos reusar la misma clave en otros dominios que gestionemos. Además, está asociada al selector mail, que es un nombre arbitraro. La existencia de selectores permite definir varias claves asociadas a un mismo dominio. Por última, con la opción -r hemos restringido el uso de la clave a la firma del servicio de correo, y no otros servicios.

Para terminar la configuración del servicio debemos crear los ficheros /etc/opendkim/signingtable y /etc/opendkim/keytable. El primero relaciona las direcciones de correo con el identificador de su clave correspondiente:

# mkdir /etc/opendkim
# cat > /etc/opendkim/signingtable
mail1.org          mail._domainkey.mail1.org

y el segundo al identificador con la clave en sí:

# cat > /etc/opendkim/keytable
mail._domainkey.mail1.org     mail1.org:mail:/etc/dkimkeys/mail.private

donde la parte derecha es «dominio:selector:ruta». Hecho esto, reiniciamos el servicio:

# invoke-rc.d opendkim restart

Ahora debemos añadir el registro DNS que publica la clave pública. Su expresión se encuentra dentro de /etc/dkimkeys/mail.txt:

mail._domainkey IN      TXT     ( "v=DKIM1; h=sha256; k=rsa; s=email; "
          "p=MIIBI ... a+"
                    "g2B8aHwc3 ... DAQAB")  ; ----- DKIM key mail for mail1.org

Nota

La adición dependerá de dónde la hagamos. En dnsmasq bastaría con añadir una línea como esta:

txt-record=mail._domainkey.mail1.org,"v=DKIM1; h=sha256; k=rsa; s=email; p=MIIBI ... ag2B8aHwc3 ... DAQAB+"

Convendría probar si somos capaces de resolver el registro y, por último, comprobar si funciona la clave:

# host -t txt mail._domainkey.mail1.org
# opendkim-testkey -d mail1.org -s mail -vvv
opendkim-testkey: using default configfile /etc/opendkim.conf
opendkim-testkey: checking key 'mail._domainkey.mail1.org'
opendkim-testkey: key not secure
opendkim-testkey: key OK

Advertencia

Tenga presente que la comprobación de la clave no funcionará si opendkim no es capaz de resolver el registro con la clave.

Nota

Se indica que la clave no es segura porque no hay forma de verificarla con DNSSEC.

Completada la configuración de opendkim, resta hacer que postfix haga uso de él, para lo cual habrá que añadir a /etc/postfix/main.cf unas líneas:

# DKIM
milter_default_action = accept
smtpd_milters = unix:var/run/opendkim.sock
non_smtpd_milters = unix:var/run/opendkim.sock

e incluir el usuario postfix dentro del grupo opendkim para que pueda leer en el socket:

# adduser postfix opendkim

Con esta configuración, el servidor de correo se encargará de firmar los mensajes que envíe, añadiendo un campo DKIM-Signature: a la cabecera del correo; y verificará los mensajes entrantes que hayan sido firmados por servidores de otros dominios, añadiendo un campo Authentication-Results que incorpore el resultado.

7.3.3.5.3. DMARC

7.3.3.5.3.1. Concepto

SPF incide en la verificación del remitente del sobre y DKIM en la dirección del mensaje. Ambas verificaciones son independientes y provocan resultados independientes. DMARC es un mecanismo que analiza los resultados de ambos métodos y se encarga de dos tareas:

  1. En función del resultado, tomar la decisión de aceptar, poner en cuarentena y rechazar el mensaje.

  2. Enviar informes a los responsables de los dominios que han implementado DMARC de las falsificaciones que hayan llegado al servidor procedentes de sus dominios.

Ver también

La página oficial de DMARC tiene una introducción sobre DMARC bastante elocuente.

7.3.3.5.3.2. Registro

DMARC también exige la publicación de un registro DNS que informa al servidor destinatario de:

  • Qué debe hacer con los mensajes que fallan la verificación. Obviamente, el hecho de que el dueño del dominio indique a se acepten mensajes, no implica que los servidores destinatarios deban aceptarlo sin más. Lo más probable es que implementen ulteriores filtros de spam que puntúen negatiamente el resultado fallido de la comprobación y que en consecuencia, enviando los mensajes a los buzones de spam de los usuarios.

  • Cuál es la dirección a la que deben remitirse los informes.

Los registros tienes este aspecto:

_dmarc.mail1.org     IN    TXT   "v=DMARC1; campo1=valor1; ...; campoN=valorN"

El primer campo v identifica la versión y junto a p es el único obligatorio. Alguno de los campos restantes son:

Campo

Significado

Ejemplo

p

Política a seguir (none, quarantine, reject).

p=none

rua

URI a la que remitir los informes agregados.

rua=mailto:dmarc\@mail1.org

ruf

URI a la que remitir informes individualizados

ruf=mailto:forense\@mail1.org

pct

Porcentaje de mensajes al que aplicar DMARC.2

pct=50

aspf

Alineamiento SPF. Por defecto, r.

aspf=s

adkim

Alineamiento DKIM. Por defecto, r.

adkim=s

Los alineamientos que refiere la tabla relacionan la dirección que autentica el mecanismo con la dirección que no autentica (recordemos que hay dos direcciones que definen el origen del mensaje). El alineamiento SPF obliga a que el dominio de la dirección del mensaje coincida del la del remitente del sobre, si es estricto (s), o a que sea al menos un subdominio, si es relajado (r). Por su parte el alineamiento DKIM obliga a que el dominio de la dirección del remitente del sobre coincida con el de la dirección del mensaje, si es estricto (s); o a que al menos sea un subdominio, si es relajado (r).

Ver también

Para una descripción detallada del registro visite la descripción de zytrax.com.

Un posible registro podría ser el siguiente:

_dmarc.mail1.org        IN    TXT      "v=DMARC1; p=none; rua=mailto:dmarc@mail1.org"

aunque deberíamos hacer que los mensajes dirigidos a la cuenta acabaran en el buzón de algún usuario real.

7.3.3.5.3.3. Implementación

Es obvio que la implementación exige necesariamente que se hayan implementdo previamente SPF y DKIM. Una vez completado lo anterior podemos:

# apt install opendmarc

En el fichero de configuración podemos modificar algunas líneas:

AuthservID smtp.mail1.org
#RejectFailures true
Socket local:/var/spool/postfix/var/run/opendmarc.sock

La directiva RejectFailures, puesta a true, tiene el efecto de rechazar los mensajes cuya comprobación falla y cuya política DMARC del dominio prescribe que se rechacen (p=reject). Si está comentada o puesta a false, los mensajes jamás se rechazarán, aunque la política lo prescriba.

Por último, toca configurar postfix para que lo ejecute como milter, tras opendkim:

milter_default_action = accept
smtpd_milters = unix:var/run/opendkim.sock, unix:var/run/opendmarc.sock
non_smtpd_milters = unix:var/run/opendkim.sock, unix:var/run/opendmarc.sock

Además, deberemos añadir el usuario postfix al grupo opendmarc para poder leer y escribir en el socket:

# adduser postfix opendmarc

Comprobación

Podemos hacer una prueba configurando en un servidor de correo (mail1.org) SPF, DKIM y DMARC por entero; y para otro (mail2.org) definiendo únicamente los registros SPF y DMARC en el DNS. Hecho esto, podemos probar a enviar desde una tercera máquina un correo en que el remitente sea aparentemente un usuario del servidor mail2.org. La comprobación SPF debería fallar y, en consecuencia, DMARC también. Si configuramos que la politica para mail2.org fuera de rechazo y RejectFailures a true, el servidor debería rechazar el mensaje.

Notas al pie

1

Obsérvese que los registros MX definen los servidores encargados de recibir mensajes para ese dominio.

2

Por defecto, se aplica a todos.