Servidor de Correo – Casillas y usuarios virtuales

DKIM, SPF y DMARC

DKIM, SPF y DMARC

DKIM, SPF y DMARC son estándares que habilitan diferentes aspectos de la autenticación de correo electrónico. Abordan cuestiones complementarias.

  • SPF permite a los remitentes definir qué direcciones IP pueden enviar correo para un dominio determinado.
  • DKIM proporciona una clave de cifrado y una firma digital que verifica que un mensaje de correo electrónico no fue falsificado o alterado.
  • DMARC unifica los mecanismos de autenticación de SPF y DKIM en un marco común y permite a los propietarios de los dominios declarar cómo desean que se maneje el correo electrónico de ese dominio si no pasa una prueba de autorización.

Instalación Básica

# apt install opendkim opendkim-tools postfix-policyd-spf-python postfix-pcre

Agregar el usuario

postfix

al grupo

opendkim

de modo que Postfix pueda acceder al socket de OpenDKIM cuando lo necesite:

adduser postfix opendkim

Configurar SPF

Agregar registros SPF al DNS

midominio.edu.ar.IN TXT "v=spf1 mx a ip4:170.210.45.130 ip6:2800:110:44:6260::130 a:correo.midominio.edu.ar -all"
  • La etiqueta v=spf1 es necesaria y tiene que ser la primera.
  • La última etiqueta, -all, indica que el correo de nuestro dominio solo debería proceder de los servidores identificados en la cadena SPF.
  • mx señala a todos los hosts listados en los registros MX de nuestro dominio.
  • La etiqueta a permite identificar un host específico por nombre o dirección IP, con esto podemos definir que hosts están autorizados.

Agregar el agente de directivas SPF a Postfix

El agente de directivas SPF basado en Python agrega la verificación de directivas SPF a Postfix. El registro SPF para el dominio del remitente del correo entrante será verificado y, si existe, el correo será manejado en consecuencia.

  1. Al usar SpamAssassin, puede que querramos editar/etc/postfix-policyd-spf-python/policyd-spf.confpara cambiar la configuración deHELO_rejectyMail_From_rejectaFalse. Esto hará que el agente de directivas SPF ejecute sus pruebas y agregue un mensaje al encabezado con los resultados y no rechace ningún mensaje. Esto también resulta útil si queremos ver los resultados del procesamiento de no aplicarlos al procesamiento de coreo. De otro modo, basta continuar con la configuración estándar.
  2. Editamos/etc/postfix/master.cfy agregamos lo siguiente al final:
    policyd-spf unix - n n - 0 spawn user=policyd-spf argv=/usr/bin/policyd-spf
  3. Abrir/etc/postfix/main.cfy agregar esta entrada para incrementar el timeout del agente de directivas de Postfix, con lo cual evitaremos que Postfix aborte al agente si las transacciones se enlentecen:
policyd-spf_time_limit = 3600
  1. Editar la entradasmtpd_recipient_restrictionspara agregar check_policy_service:
    smtpd_recipient_restrictions =
     ...
     reject_unauth_destination,
     check_policy_service unix:private/policyd-spf,
     ...

    Debemos asegurarnos de agregar la entrada

    check_policy_service

    después de

    reject_unauth_destination

    para evitar que nuestro sistema se convierta en un relay abierto. Si

    reject_unauth_destination

    es la última entrada en nuestra lista de restricciones, es necesario agregar una coma a continuación de ella y omitir la coma al final de

    check_policy_service

    .

  2. Reiniciar Postfix
    systemctl restart postfix

Podemos verificar el funcionamiento del agente de directivas buscando en los encabezados originales en del correo entrante el encabezado de resultados SPF. El encabezado que el agente de directivas agrega a los mensajes debería ser similar a este:

Received-SPF: Pass (sender SPF authorized) identity=mailfrom; client-ip=127.0.0.1; helo=mail.midominio.edu.ar; envelope-from=text@midominio.edu.ar; receiver=tknarr@silverglass.org

Esto indica una verificación exitosa contra las directivas SPF del dominio remitente. Si cambiamos las directivas definidas en el paso 1 para que no rechace el correo que no pasa la validación SPF, podriamos ver resultados fallidos en este encabezado. Este encabezado no aparecerá en correo saliente o local.

El agente de directivas SPF también registra su actividad en

/var/log/mail.log

. Allí veremos mensajes como este:

Jan 7 06:24:44 arachnae policyd-spf[21065]: None; identity=helo; client-ip=127.0.0.1; helo=mail.midominio.edu.ar; envelope-from=test@midominio.edu.ar; receiver=tknarr@silverglass.org
Jan 7 06:24:44 arachnae policyd-spf[21065]: Pass; identity=mailfrom; client-ip=127.0.0.1; helo=mail.midominio.edu.ar; envelope-from=test@midominio.edu.ar; receiver=tknarr@silverglass.org

El primer mensaje es una verificación del comando HELO, en este caso indicando que no existe información SPF alguna que coincida con el HELO (lo cual está perfectamente bien). El segundo mensaje es una verificación contra la dirección From, e indica que pasó la verificación y procede de uno de los servidores de envío que el servidor del dominio remitente ha informado que se encuentra habilitado a enviar correo para ese dominio.

Consideraciones:

Existe un bug en las versiones de Bind9 incluidas en Debian por el cual es posible que tengamos mensajes como este en el log:

found SPF/TXT record but no SPF/SPF record found, add matching type SPF record

A partir de 2014 los registros SPF fueron ‘deprecados’ y fueron reemplazados por registros TXT con la información inherente a SPF.

No obstante, habiendo seguido los pasos para configurar el registro SPF en nuestro DNS, el servidor de correo pasará las validaciones.

Configurar OpenDkim

Esto implica configurar el paquete OpenDKIM, anexarlo a Postfix, y agregar un registro al DNS.

El archivo principal de configuración de OpenDKIM

/etc/opendkim.conf

debe verse así:

# Log to syslog
Syslogyes
# Required to use local socket with MTAs that access the socket as a non-
# privileged user (e.g. Postfix)
UMask002
# OpenDKIM user
# Remember to add user postfix to group opendkim
UserIDopendkim
# Socket smtp://localhost
Socketinet:12301@localhost
# Map domains in From addresses to keys used to sign messages
KeyTable/etc/opendkim/keytable
SigningTablerefile:/etc/opendkim/signingtable
# Hosts to ignore when verifying signatures
ExternalIgnoreListrefile:/etc/opendkim/trustedhosts
InternalHostsrefile:/etc/opendkim/trustedhosts
Selectorcorreo
Canonicalizationrelaxed/simple
Modesv
SubDomainsno
AutoRestartyes
AutoRestartRate10/1M
Backgroundyes
DNSTimeout5
SignatureAlgorithmrsa-sha256
OversignHeadersFrom

Aquí el dato clave es el valor que asignemos al

Selector

Debemos asegurarnos que los permisos del archivo se definieron correctamente:

chmod u=rw,go=r /etc/opendkim.conf

Creamos los directorios donde se alojarán los archivos de datos de OpenDKIM, asignamos la propiedad al usuario opendkim, y restringimos los permisos de archivo:

mkdir /etc/opendkim
mkdir /etc/opendkim/keys
chown -R opendkim:opendkim /etc/opendkim
chmod go-rw /etc/opendkim/keys

Creamos la tabla de firmas

/etc/opendkim/signingtable

. Debe contener una línea por cada dominio para el cual gestionamos correo. Y cada una de ellas debería verse así:

*@midominio.edu.ar correo._domainkey.midominio.edu.ar

El archivo signingtable le indica a OpenDKIM como usar tus llaves, que remitentes deberían usar cuales selectores para sus firmas. En el ejemplo anterior, estamos señalando que todos (*) quienes envían correo desde “midominio.edu.ar” deberían usar el selector llamado “correo.” Es importante notar que el comodín * solamente funcionará si la opción SigningTable usa el prefijo refile: antes del nombre de archivo.

Creamos la tabla de llaves

/etc/opendkim/keytable

. Debe tener una línea por cada dominio en la tabla de firmas. Cada linea debería verse así:

correo._domainkey.midominio.edu.ar midominio.edu.ar:correo:/etc/opendkim/keys/correo.private

El primer campo conecta las tablas signing y key. Vale aclarar que tanto la tabla signing como la tabla key pueden estar tranquilamente en el /etc/opendkim, solo es cuestión de preferencias.

El segundo campo está dividido en 3 secciones separadas por ‘:’.

    • La primera sección es el nombre de dominio para el cual la llave es usada.
    • La segunda sección es el selector usado al buscar registros en el DNS. Fue definido en/etc/opendkim.conf
    • La tercera sección identifica al archivo que contiene la llave para el dominio.

Creamos el archivo de hosts de confianza

/etc/opendkim/trustedhosts

. Al igual que las tablas, también podría estar en

/etc/opendkim

. Su contenido debe ser:

127.0.0.1
localhost
170.210.45.130
2800:110:44:6260::130
*.midominio.edu.ar

Generamos las llaves para cada dominio:

opendkim-genkey -b 2048 -h sha256 -r -s correo -d midominio.edu.ar -v

Esto generará dos archivos, correo.private con la llave y correo.txt con el registro TXT que tendremos que agregar al DNS

Debemos asegurarnos que el directorio

/etc/opendkim/keys

solamente sea accesible por el propietario:

chown -R opendkim:opendkim /etc/opendkim
chmod -R go-rwx /etc/opendkim/keys

Conectamos el milter a Postfix:

nano /etc/default/opendkim

Añadimos la siguiente línea, editamos el número de puerto sólo si se utiliza uno personalizado:

SOCKET="inet:12301@localhost"

Verificamos que OpenDKIM se inicia correctamente:

systemctl restart opendkim

No debería haber mensajes de error, pero si los hay, así comienza la diversión:

systemctl status -l opendkim

Configurar el DNS

Al igual que SPF, DKIM emplea registros TXT para mantener la información acerca de la llave para cada dominio. Es necesario crear un registro TXT para el host correo._domainkey para cada dominio por el que gestione correo. Su valor puede ser encontrado en el archivo correo.txt para cada dominio. Estos archivos se ven así:

correo._domainkey IN TXT ( "v=DKIM1; k=rsa; "
 "p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDWZK7F4thFxpZa2or6jBEX3cSL6b2TJdPkO5iNn9vHNXhNX31nOefN8FksX94YbLJ8NHcFPbaZTW8R2HthYxRaCyqodxlLHibg8aHdfa+bxKeiI/xABRuAM0WG0JEDSyakMFqIO40ghj/h7DUc/4OXNdeQhrKDTlgf2bd+FjpJ3bNAFcMYa3Oeju33b2Tp+PdtqIwXRZksfuXh7m30kuyavp3Uaso145DRBaJZA55lNxmHWMgMjO+YjNeuR6j4oQqyGwz"
 "PaVcSdOG8Js2mXt+J3Hr+nNmJGxZUUW4Uw5ws08wT9opRgSpn+ThX2d1AgQePpGrWOamC3PdcwIDAQAB" ) ; ----- DKIM key correo for midominio.edu.ar

Copiamos todo y pegamos ese valor en nuestro archivo de zona de Bind. Luego de algunos retoques, debería verse así:

correo._domainkey.midominio.edu.ar. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAu5oIUrFDWZK7F4thFxpZa2or6jBEX3cSL6b2TJdPkO5iNn9vHNXhNX31nOefN8FksX94YbLJ8NHcFPbaZTW8R2HthYxRaCyqodxlLHibg8aHdfa+bxKeiI/xABRuAM0WG0JEDSyakMFqIO40ghj/h7DUc/4OXNdeQhrKDTlgf2bd+FjpJ3bNAFcMYa3Oeju33b2Tp+PdtqIwXRZksfuXh7m30kuyavp3Uaso145DRBaJZA55lNxmHWMgMjO+YjNeuR6j4oQqyGwzPaVcSdOG8Js2mXt+J3Hr+nNmJGxZUUW4Uw5ws08wT9opRgSpn+ThX2d1AgQePpGrWOamC3PdcwIDAQAB"

Es necesario repetir esto para cada dominio para el cual gestionemos correo, usando la información del archivo .txt para ese dominio.

Probamos la configuración

Para probar las el correcto firmado y verificación de las llaves usamos:

opendkim-testkey -d midominio.edu.ar -s correo

Si todo está bien no deberíamos ver ninguna salida. Para tener más información, agregamos

-vvv

al final del comando. Eso produce una salida detallada. El último mensaje debería ser “key OK”. Justo antes de eso podríamos ver un mensaje “key not secure”. Eso es normal y no es señal de error, se debe a que la DNSSEC no está habilitada en su nombre de dominio. Se trata de un estándar de seguridad para la consulta segura del DNS. La mayoría de los nombres de dominio no tienen habilitada la DNSSEC.

Vinculamos OpenDKIM a Postfix

Definimos el socket correcto para Postfix en

/etc/default/opendkim

# Command-line options specified here will override the contents of
# /etc/opendkim.conf. See opendkim(8) for a complete list of options.#DAEMON_OPTS=""
#
# Uncomment to specify an alternate socket
# Note that setting this will override any Socket value in opendkim.conf
#SOCKET="local:/var/run/opendkim/opendkim.sock" # default
#SOCKET="inet:54321" # listen on all interfaces on port 54321
#SOCKET="inet:12345@localhost" # listen on loopback on port 12345
#SOCKET="inet:12345@192.0.2.1" # listen on 192.0.2.1 on port 12345
SOCKET="inet:8891@localhost"

Editamos

/etc/postfix/main.cf

y agregamos una sección para activar el procesamiento de correo a través del demonio OpenDKIM:

# OpenDKIM
milter_default_action = accept
milter_protocol = 6
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters

Consideraciones:

El formato del smtpd:milter (inet:localhost:8891) difiere de la configuración de OpenDKIM (inet:8891@localhost). Invertir el orden host / puerto en uno u otro puede acarrear varias horas de diversión.

La línea lógica que define la configuración de OpenDKIM en Postfix no puede estar identada, es decir que cada línea de configuración debe comenzar en la columna cero.

Si bien podemos colocar la configuración relativa a postfix en cualquier lugar del archivo. Lo usual es hacerlo a continuación de la entrada

smtpd_recipient_restrictions

.

Reiniciamos el demonio OpenDKIM de modo que defina el socket correcto para Postfix:

systemctl restart opendkim

Reiniciamos Postfix para que comience a utilizar OpenDKIM al procesar correo:

systemctl restart postfix