Mediante DKIM podemos firmar los correos que mandamos mediante un determinado dominio. Se usa el header DKIM-Signature. Vamos a ver como funciona y como configurar qmail para que firme los correos salientes:

DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed;
        d=gmail.com; s=gamma;
        h=date:from:to:subject:message-id:in-reply-to:references:x-mailer
         :mime-version:content-type:content-transfer-encoding;
        bh=h94cOorFnF7zrqXewhm6jiXkvCwtLdWYcECXDq7i+w0=;
        b=vpq1zBvkGwfaVOCsHRCGrb9UulHTxD/G38gF0CZ3I/YRvOUqpk/kS1W1fc1xdT/T72
         xo+cf1feYMPVKw0xeRU83OGHDIMzA2zYc7pqRB8yO/dVA7PsCg+r2QmI1hwVne4dqNQk
         d60abjGiZJG48ZzVHQUehODLMqJkoZI4VFqKo=

El que reciba el mail puede obtener la clave pública a partir del selector (valor s) en este caso gamma combinado con el dominio firmante (valor d). En el caso anterior sería:

# dig gamma._domainkey.gmail.com txt +short
"k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQDIhyR3oItOy22ZOaBrIVe9m/iME3RqOJeasANSpg2YTHTYV+Xtp4xwf5gTjCmHQEMOs0qYu0FYiNQPQogJ2t0Mfx9zNu06rfRBDjiIU9tpx2T+NGlWZ8qhbiLo5By8apJavLyqTLavyPSrvsx0B3YzC63T4Age2CDqZYA+OwSMWQIDAQAB"

A continuación se usan los headers que se indican con el valor h, se tratan según el algoritmo especificado en el valor c y se firma con un hash de los datos tratados.

Para el caso de relaxed podemos consultar la sección 3.4.2 del RFC4871 donde se indica que cómo se deberán tratar los headers para asegurarnos que se podrá verificar el firmado aunque MTAs intermedias modifiquen los headers.

Para empezar a firmar los mails salientes con qmail, primero deberemos instalar el modulo de perl Mail::DKIM

cpan> install Mail::DKIM

A continuación deberemos conservar el script que viene con el paquete llamado dkimsign.pl:

cp /root/.cpan/build/Mail-DKIM-0.39/scripts/dkimsign.pl /usr/local/bin/

Deberemos modificarlo para que acepte como parámetro nuestra clave privada:

cat <<EOF > /usr/local/src/dkimsign.patch
--- dkimsign.pl.old     2012-01-30 22:06:50.959015108 +0100
+++ dkimsign.pl 2012-01-30 22:08:19.839015533 +0100
@@ -26,8 +26,10 @@
 my $debug_canonicalization;
 my $binary;
 my $help;
+my $key="rsa.private";
 GetOptions(
                "type=s" => \$type,
+               "key=s" => \$key,
                "algorithm=s" => \$algorithm,
                "method=s" => \$method,
                "selector=s" => \$selector,
@@ -61,7 +63,7 @@
                Algorithm => $algorithm,
                Method => $method,
                Selector => $selector,
-               KeyFile => "private.key",
+               KeyFile => $key,
                Debug_Canonicalization => $debugfh,
                );
EOF
patch /usr/local/bin/dkimsign.pl /usr/local/src/dkimsign.patch

Copiamos el qmail-remote original, ya que lo substituiremos por un script que firme los correos:

cp /var/qmail/bin/qmail-remote /var/qmail/bin/qmail-remote.orig

Podemos encontrar un script como el siguiente que permite tener varias claves privadas para firmar según el dominio del from:

#!/bin/bash

host="$1"
sender="$2"

[ -z "$sender" ] && [ "$DEFAULTDOMAIN" ] && sender="@$DEFAULTDOMAIN"
[ -z "$sender" ] && sender=@`hostname -f`
DOMAIN="${sender##*@}"
[ "$DKREMOTE" ] || DKREMOTE="/var/qmail/bin/qmail-remote.orig"
[ "$DKSIGN" ]   || DKSIGN="/etc/domainkeys/%/default"
if [ "$DOMAIN" ] ; then
       while [ ! -r "${DKSIGN//\%/$DOMAIN}" ] ; do
               # try parent domains, per RFC 4871, section 3.8
               DOMAIN=${DOMAIN#*.}
               DPARTS=( ${DOMAIN//./ } )
               [ ${#DPARTS[*]} -eq 1 ] && DOMAIN="${sender##*@}" && break
       done
fi
DKSIGN="${DKSIGN//\%/$DOMAIN}"
if [ -r "$DKSIGN" ] ; then
       tmp=`/bin/mktemp /tmp/dk.sign.XXXXXXXXXXXXXXXXXXX`
       tmp2=`/bin/mktemp /tmp/dk2.sign.XXXXXXXXXXXXXXXXXXX`
       /bin/cat - >"$tmp"

       # compute the DomainKey signature
       error=`(/usr/local/bin/dkimsign.pl --type=domainkeys --selector=default \
                               --key="$DKSIGN" --method=simple <"$tmp" | \
                       /usr/bin/tr -d '\r' >> "$tmp2") 2>&1`
       [ "$error" ] && echo "DomainKey error: $error" >&2 && exit -2

       # compute the DKIM signature
       error=`(/usr/local/bin/dkimsign.pl --type=dkim --selector=default \
                               --key="$DKSIGN" --method=relaxed <"$tmp" | \
                       /usr/bin/tr -d '\r' >> "$tmp2") 2>&1`
       [ "$error" ] && echo "DKIM error: $error" >&2 && exit -2

       # feed the signatures and the original message to the real qmail-remote
       /bin/cat "$tmp2" "$tmp" | "$DKREMOTE" "$@"
       retval=$?
       /bin/rm "$tmp" "$tmp2"
       exit $retval
else
       echo "No DK signature added" >&2
       exec "$DKREMOTE" "$@"
fi

Pero para el caso de muchos dominios puede ser muy pesado tener que crear tantas claves por lo que podemos firmar usando un único dominio. Podemos simplificar el script para que use únicamente la clave privada que tenemos en /etc/domainkeys/default. Por otro lado, los ficheros temporales los podemos guardar en memoria mediante tmpfs:

tmpfs on /dev/shm type tmpfs (rw)

El script anterior, del que deberemos personalizar el dominio con el que queremos firmar, una vez simplificado quedaría:

#!/bin/bash

DKSIGN="/etc/domainkeys/default"
DKREMOTE="/var/qmail/bin/qmail-remote.orig"
DKDOMAIN="systemadmin.es"

tmp=`/bin/mktemp /dev/shm/dk.sign.XXXXXXXXXXXXXXXXXXX`
tmp2=`/bin/mktemp /dev/shm/dk2.sign.XXXXXXXXXXXXXXXXXXX`

/bin/cat - >"$tmp"

/usr/local/bin/dkimsign.pl --type=dkim --selector=default \
        --key="$DKSIGN" --method=relaxed --domain=$DKDOMAIN <"$tmp" | \
        /usr/bin/tr -d '\r' >> "$tmp2" 2>&1

/bin/cat "$tmp2" "$tmp" | "$DKREMOTE" "$@"
retval=$?

/bin/rm "$tmp" "$tmp2"

exit $retval

Lo podemos llamar qmail-remote.DKIM A continuación deberemos crear una clave privada:

mkdir -p /etc/domainkeys/systemadmin.es
cd /etc/domainkeys/systemadmin.es
openssl genrsa -out rsa.private 768
cp rsa.private default

Y generamos la clave pública:

openssl rsa -in rsa.private -out rsa.public -pubout -outform PEM
rm rsa.private

Lo que nos quedará:

$ ll
total 8
-rw-r--r-- 1 root root 688 Mar 17 19:05 default
-rw-r--r-- 1 root root 223 Mar 17 19:05 rsa.public

A continuación podemos obtener lo que deberemos añadir al registro TXT:

$ grep -v ^- rsa.public | perl -e 'while(<>){chop;$l.=$_;}print "k=rsa; t=y; p=$l;\n";'
k=rsa; t=y; p=MHwwAAAAKoZIhvcNAQEBBAADAwAwAAJhAJ6243dIC0CzzBI9nNY/12347selbvh0GI3phmOcEYAA4M+/nlM+lMXHHIo8rlKtgYA2E412345g40ms2zWeCWMtAAmgHL1QCgvQJ5STzF5wOVz6mtFb6AAKBb9AAvl3wIDAQAB;

Mediante el valor t indicamos si estamos en pruebas, cuando estemos seguros que funciona correctamente lo podemos quitar:

_domainkey.systemadnin.es.         IN  TXT "o=-;"
default._domainkey.systemadmin.es. IN  TXT "k=rsa; t=y; p=MHwwDQYJKoZIhvcNAQEBBQADawAwaAJhAOCKwsbO8avw2253VH6ACFqGfilvDfVboz4LX1TLM3oVV8sT51W7k8j8H2Mg3w3SgpKlYcAyJ8LO7cifRpYPUIJjhmeQtIXtGFm0aK7lvxC+sDzvJdWssbXAb3t6hveJ3QIDAQAB;"

Podemos habilitar el firmado creando un link simbólico del qmail-remote.DKIM al qmail-remote y reinicar qmail-send:

ln -sf /var/qmail/bin/qmail-remote.DKIM /var/qmail/bin/qmail-remote
svc -t /service/qmail-send

Si mandamos un mail de prueba:

# telnet localhost 25
Trying 127.0.0.1...
Connected to localhost.localdomain (127.0.0.1).
Escape character is '^]'.
220 RTFM ESMTP
helo test
mail from: jordi@test.com
250 ok
rcpt to: ejemplo@gmail.com
250 ok
data
354 go ahead
From: Jordi Prats <jprats@test.com>
Subject: test dkim

aaa
.
250 ok 1328476380 qp 16660

Podemos ver la firma en los headers del mail:

DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=systemadmin.es; h=date
    :message-id:from:to:subject; s=default; bh=0PMpbQVFwgW9281z6qXAO
    N7t78U=; b=AGSC7IO9Uro/MKQcoEU4ZFsU4C8RY0O3Wox+wywnr2JblZc40NfCc
    Zgqj+sdTATtcJSvH9lVcLSxbD88qpYbQ1ausjszyzswpVudDi6muJefLP2v9A2qB
    Cc7K1F+ngvp

Si lo comprobamos con un SpamAssassin veremos los siguientes hits de reglas:

X-Spam-Status: No, score=-0.1 required=4.0 tests=DKIM_SIGNED,DKIM_VALID,
    DKIM_VALID_AU,SPF_HELO_PASS,SPF_PASS autolearn=unavailable version=3.3.1

En el caso de gmail, si mandamos un mail firmado con DKIM nos añadirá via y el dominio firmante al lado del from, por ejemplo:

DKIM visto por gmail

DKIM visto por gmail

Tags: <a href="http://systemadmin.es/tag/qmail" title="qmail" rel="tag">qmail</a><br>

<h4>Relacionados</h4>
<ul>
<li><a href="http://systemadmin.es/2009/03/usando-qmail-para-entregar-correo-a-nuestro-relay" title="Usando qmail para entregar correo a nuestro relay (31/March/2009)">Usando qmail para entregar correo a nuestro relay</a></li>
<li><a href="http://systemadmin.es/2009/02/ucspi-tls-sslserver-general-protection-rip32bca95737-rsp7fff288e6988-error0" title="UCSPI-TLS sslserver: general protection rip:32bca95737 rsp:7fff288e6988 error:0 (20/February/2009)">UCSPI-TLS sslserver: general protection rip:32bca95737 rsp:7fff288e6988 error:0</a></li>
<li><a href="http://systemadmin.es/2009/02/spamcheck-para-newsletters-con-qmail-y-spamassassin" title="Spamcheck para newsletters con qmail y spamassassin (27/February/2009)">Spamcheck para newsletters con qmail y spamassassin</a></li>
<li><a href="http://systemadmin.es/2009/07/qmqtool-herramienta-para-ver-y-modificar-la-cola-de-qmail" title="qmqtool: Herramienta para ver y modificar la cola de qmail (14/July/2009)">qmqtool: Herramienta para ver y modificar la cola de qmail</a></li>
<li><a href="http://systemadmin.es/2009/01/qmailanalog-usrbinld-errno-tls-definition-in-lib64libcso6-section-tbss-mismatches-non-tls-reference-in-strerrastrerr_syso" title="qmailanalog: /usr/bin/ld: errno: TLS definition in /lib64/libc.so.6 section .tbss mismatches non-TLS reference in strerr.a(strerr_sys.o) (20/January/2009)">qmailanalog: /usr/bin/ld: errno: TLS definition in /lib64/libc.so.6 section .tbss mismatches non-TLS reference in strerr.a(strerr_sys.o)</a></li>

Via http://systemadmin.es/2012/02/dkim-domainkeys-identified-mail-qmail

Related Posts with Thumbnails
 

Comments are closed.

Weboy