DKIM con QMail (con y sin DomainKey)

El método explicado aquí para implementar DKIM con QMail se basa en el uso de un wrapper que sustituye al script qmail-remote original permitiendo firmar el correo saliente antes de enviarlo. Dicho wrapper está diseñado para generar una firma DomainKey y una firma DKIM a partir de la misma clave, útil para quienes no tengan aún implementada ninguna de las dos. En la segunda parte del artículo se explica cómo modificar el wrapper para generar sólo la firma DKIM, por si tu sistema ya tiene implementada la DomainKey. Se ha probado con QMail 1.03 sobre Centos 6.


Instalar wrapper DKIM qmail-remote

Descargamos qmail-remote.sh, renombramos qmail-remote original a qmail-remote.orig (importante, el wrapper busca el script con este nombre), sustituimos el original y le asignamos los permisos correspondientes:

wget http://www.memoryhole.net/qmail/qmail-remote.sh
mv /var/qmail/bin/qmail-remote /var/qmail/bin/qmail-remote.orig
cp qmail-remote.sh /var/qmail/bin/qmail-remote
chmod 755 /var/qmail/bin/qmail-remote
chown root:qmail /var/qmail/bin/qmail-remote

El nuevo qmail-remote necesita dos programas externos para funcionar: dktest, disponible en la librería libdomainkeys, y dkimsing.pl, un script en Perl para firmar el correo. Éste último requiere las librerías Mail::DKIM::Signer, Mail::DKIM::TextWrap, Getopt::Long y Pod::Usage.

wget http://www.memoryhole.net/qmail/dkimsign.pl
cp dkimsign.pl /usr/local/bin
chmod 755 /usr/local/bin/dkimsign.pl
wget http://sourceforge.net/projects/domainkeys/files/libdomainkeys/0.69/libdomainkeys-0.69.tar.gz/download
tar -xzf libdomainkeys-0.69.tar.gz
cd libdomainkeys-0.69

Editamos ahora el Makefile, añadimos -lresolv al final de la línea LIBS, guardamos y make. Ya podemos instalarlos en los directorios donde los busca el wrapper:

install -m 644 libdomainkeys.a /usr/local/lib
install -m 644 domainkeys.h dktrace.h /usr/local/include
install -m 755 dknewkey /usr/bin
install -m 755 dktest /usr/local/bin

Generación de DomainKey para el dominio

Creamos un subdirectorio dentro de /etc/domainkeys/ con el nombre del dominio para el que necesitemos una clave y generamos ésta con la utilidad dknewkey. El fichero default creado es la parte privada y default.pub la pública:

mkdir -p /etc/domainkeys/ejemplo.com
cd /etc/domainkeys/ejemplo.com
dknewkey default 1024 > default.pub
chown -R root:root /etc/domainkeys
chmod 640 /etc/domainkeys/ejemplo.com/default
chown root:qmail /etc/domainkeys/ejemplo.com/default

Abrimos ahora el fichero default.pub y copiamos la parte entre comillas:

default._domainkey        IN      TXT     "v=DKIM; k=rsa; p=MIGfMA0GCSqGSIb390BAQUAA4GNADCBiQKBgQDNmNtzcX6/XzYgalxJqdftSSUyED1+5QuegTSwBZrKm+jrdg55Xm2Dqyt1y2RcVqC0ENw2QjX3uibYKHY8S7Y7t5nxrUH58Yu7COeghV3nFZT5Rqtz6lbW/7YPohqbGntCiKv4PV5CJPcEC5Gr52HtNAD1jYsVY/7ORhtEHYlRMQIDAQAB"

Esta información es la que debemos añadir a un registro TXT de la zona DNS de nuestro dominio cuyo nombre será: default._domainkey.ejemplo.com, también hay que añadir  otro de nombre _adsp._domainkey.ejemplo.com igual a dkim=unknown y listo. Podemos verificar que funciona enviando correos de prueba a las direcciones facilitadas por Port25.

Modificar el wrapper DKIM qmail-remote para usar sólo DKIM

Y usar además claves ya creadas anteriormente con OpenDKIM. Éste es el caso si se ha migrado de una instalación anterior que usaba por ejemplo Postfix con OpenDKIM. En el ejemplo he creado un subdirectorio /dkim dentro de /etc/domainkeys/ejemplo.com para guardar la clave privada pero puede hacerse cambiando simplemente el nombre al fichero.

Modificamos el wrapper: abrimos qmail-remote y cambiamos la linea 19:

[ "$DKSIGN" ]   || DKSIGN="/etc/domainkeys/%/default"
por
[ "$DKSIGN" ]   || DKSIGN="/etc/domainkeys/%/dkim/k_dkim"
y las líneas 40 a 48 (donde se genera la DomainKey) las comentamos:

# compute the DomainKey signature
# error=`(dktest -s "$DKSIGN" -c nofws -h <"$tmp" | \
#  sed 's/; d=.*;/; d='"$DOMAIN"';/' > "$tmp2") 2>&1`
# if [ "$error" ] ; then
#  # Communicate the problem to qmail (that's why the 'Z')
#  echo "ZDomainKey error: $error"
#  rm "$tmp" "$tmp2"
#  exit -1
# fi
Copiamos la clave privada que ya creamos con OpenDKIM, normalmente en /etc/opendkim/keys, a la nueva carpeta /dkim que crearemos en /etc/domainkeys/ejemplo.com:

mkdir /etc/domainkeys/ejemplo.com/dkim
chmod  755 /etc/domainkeys/ejemplo.com/dkim
cp /etc/opendkim/keys/ejemplo.com/default /etc/domainkeys/ejemplo.com/dkim/k_dkim
chmod 649 /etc/domainkeys/ejemplo.com/dkim/k_dkim
chown root:qmail /etc/domainkeys/ejemplo.com/dkim/k_dkim

Y para terminar debemos cambiar el parámetro --selector en la línea 51 del wrapper para indicarle el nombre del fichero clave/registro DNS:

error=`(dkimsign.pl --type=dkim --selector=k_dkim --domain="$DOMAIN" \

Este paso se realiza para evitar colisionar con el registro DNS de DomainKeys, si existe, que seguramente usará como selector a default. Hacemos los cambios pertinentes en la zona DNS y listo.

2 comentarios:

  1. Hola Eduard, muchas gracias por este post. Me está siendo de mucha utilidad para las configuraciones que estoy intentando en un CentOS 6.5 Final con Qmail 1.03. En mi caso he migrado de Postfix a Qmail, por lo que me he centrado en la segunda parte.

    Veo que indicas que hay que copiar la clave privada creada con OpenDkim. En mi caso al generarla se llama "mail.private", "default" es la publica (si no he entendido mal la documentacion que he manejado). Por lo tanto queria confirmar que la que hay que copiar es la clave privada, en lugar de la publica que es "default".

    Por otro lado creo que en la linea donde asignas permisos a "k_dim" en lugar de ser "649" debe ser "644".

    Muchas gracias de nuevo y a ver si lo logro hacer funcionar.

    ResponderEliminar
    Respuestas
    1. Hola compañero, es tal como tu dices. El fichero que debes copiar al directorio donde DKIM las localiza es el que contiene la parte privada de la clave. La parte pública sólo debe aparecer en el registro correspondiente de la zona DNS. En cuanto a los permisos creo que tienes razón, sería lo lógico. Lo verificaré, gracias.

      Eliminar