Escrito por coder el 27 de marzo de 2007 en Informática | Hits: 180305
Ahora que, con hoy, son cuatro los días que llevo en la cama debido a un constipado bastante agresivo (con fiebre incluída) que me ha impedido dedicarme a mis labores profesionales y personales, aprovecho para hacer un mini howto de algo que viene siendo necesario ya desde hace algún tiempo: DomainKeys (o dkim -domainkeys identified mail en su versión mejorada-) + Postfix en castellano.
Y es que los tutoriales que he encontrado no me han convencido en absoluto, ya que, a mi juicio, obviaban dos temas fundamentales: 1) no perder otras funcionalidades -vease spamd o clamav- y 2) hablar del servicio submission.
Al asunto:
¿Qué es DomainKeys? Es una tecnología que está siendo desarrollada por Yahoo que utiliza criptografía pública para dar validez al correo saliente y verificar el correo entrante. El draft, si no he leído mal, está ahora mismo en pleno debate por parte de bastantes empresas, entre ellas AOL, Cisco y demás pesos pesados.
Configuración en Postfix: Es bastante simple. Tan sólo hay que instalar serie de módulos para Perl que permitan al proxy-SMTP dkfilter funcionar, dejándole a este la tarea de realizar el verificado y firmado de los emails. Vamos a ello:
En Gentoo los módulos se pueden instalar usando cualquier sistema de paquetes, ya sea Portage o Paludis:
# paludis crypt-rsa Email-Address MIME-Base64 Net-DNS\
List-MoreUtils Mail-DomainKeys -i
# emerge crypt-rsa Email-Address \
MIME-Base64 Net-DNS List-MoreUtils Mail-DomainKeys
En otras distros habrá que usar otros comandos (ya sea apt-get en Debian, urpmi en Mandriva, yum/rpm en RedHat o yast2 en SuSE). Para el que use Slackware o quiera hacerlo a manopla, un clásico bastará:
perl -MCPAN -e'CPAN::Shell->install("Crypt::OpenSSL::RSA")'
perl -MCPAN -e'CPAN::Shell->install("Mail::Address")'
perl -MCPAN -e'CPAN::Shell->install("MIME::Base64")'
perl -MCPAN -e'CPAN::Shell->install("Net::DNS")'
perl -MCPAN -e'CPAN::Shell->install("Test::More")'
perl -MCPAN -e'CPAN::Shell->install("Text::Wrap")'
perl -MCPAN -e'CPAN::Shell->install("Email::Address")'
perl -MCPAN -e'CPAN::Shell->install("Mail::DomainKeys")'
Después nos bajamos y compilamos el proxy-SMTP de la web de Jason (la última versión estable es la 0.11, y parece que será la última, al estar en desarrollo paralelo dkimproxy):
$ wget http://jason.long.name/dkfilter/dkfilter-0.11.tar.gz
$ tar xvf dkfilter-0.11.tar.gz
$ cd dkfilter-0.11
$ ./configure --prefix=/usr/local/dkfilter && make install
$ useradd dkfilter
Una vez compilado e instalado en /usr/local/dkfilter, tenemos que configurar Postfix para que utilice el proxy, ya sea para los emails de entrada o los de salida. En los howtos que yo he visto suelen utilizar el puerto 10025 para entrada al proxy y el 10026 para la salida del mismo. Esto yo lo veo bien, siempre y cuando no estés ya usando esos puertos. Pero, ¿qué pasa? que casualmente tengo el amavisd-new funcionando también como proxy en esos puertos para filtrar el correo basura -spam y virus-. Y, de momento y hasta que tanto DKIM como SPF sean una realidad obligatoria, no puedo prescindir del servicio amavisd-new. Por tanto yo lo cambié a otros puertos no privilegiados, 10055 y 10056 para verificar y 10057 y 10058 para firmar. Sabiendo eso, editamos el fichero /etc/postfix/master.cf y añadimos la nueva configuración:
# vim /etc/postfix/master.cf
# DKFILTER.IN
# Nada mas llegar un email al sistema, este ha de ser verificado por el proxy
smtp inet n - n - - smtpd
-o smtpd_proxy_filter=127.0.0.1:10055
-o smtpd_client_connection_count_limit=10
# Y se devuelve verificado en el puerto 10056<
127.0.0.1:10056 inet n - n - - smtpd
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
-o smtpd_client_restrictions=
-o smtpd_helo_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o smtpd_data_restrictions=
-o mynetworks=127.0.0.0/8
-o receive_override_options=no_unknown_recipient_checks
# DKFILTER.OUT
# modificamos el servicio submission para que sólo los lusers locales y
# los autentificados mediante SASL (en mi caso Dovecot-SASL) puedan
# firmar los emails salientes
submission inet n - n - - smtpd
-o smtpd_etrn_restrictions=reject
-o smtpd_sasl_auth_enable=yes
-o content_filter=dksign:[127.0.0.1]:10057
-o receive_override_options=no_address_mappings
-o smtpd_recipient_restrictions=permit_mynetworks
,permit_sasl_authenticated,reject
#
# creamos el servicio con el nombre dksign y le asignamos un tope de 10
procesos
#
dksign unix - - n - 10 smtp
-o smtp_send_xforward_command=yes
-o smtp_discard_ehlo_keywords=8bitmime
#
# emails de vuelta a Postfix ya firmados
#
127.0.0.1:10058 inet n - n - 10 smtpd
-o content_filter=
-o receive_override_options=no_unknown_recipient_checks,
no_header_body_checks
-o smtpd_helo_restrictions=
-o smtpd_client_restrictions=
-o smtpd_sender_restrictions=
-o smtpd_recipient_restrictions=permit_mynetworks,reject
-o mynetworks=127.0.0.0/8
-o smtpd_authorized_xforward_hosts=127.0.0.0/8
Una vez hecho esto, guardamos el fichero y salimos, pero NO reiniciamos Postfix todavía, ya que no hemos ni arrancado el dkfilter ni generado la clave.
Generar la clave es muy fácil:
# cd /usr/local/dkfilter
# openssl genrsa -out private.key 1024
# openssl rsa -in private.key -pubout -out public.key
Ahora, para tenerlo todo listo, sólo nos falta publicar la clave pública (valga la rebuznancia) en la zona TXT de nuestro DNS (sí, ya sé, la zona TXT se está llenando de broza cada día más, no era bastante con el SPF ni los srv de w2k3, ahora también esto...):
Nos inventamos un selector (dk por ejemplo) y sacamos la clave pública del fichero y la pegamos en la zona TXT:
_domainkey.fluzo.org IN TXT “t=y; o=-;”
dk._domainkey.fluzo.org IN TXT "g=; k=rsa; p=clave_pública;"
Y a la marcha. Ya está listo. Podemos comprobarlo usando esta URL de test
Arrancamos el servicio utilizando este script que encontré en la web de enterux (ahora mismo caída):
#!/bin/sh
#
# Copyright (c) 2005 Messiah College.
DKFILTERUSER=dkfilter
DKFILTERGROUP=dkfilter
DKFILTERDIR=/usr/local/dkfilter
HOSTNAME=`hostname -f`
DOMAIN="fluzo.org" #`hostname -d`
DKFILTER_IN_ARGS="--hostname=$HOSTNAME 127.0.0.1:10055 127.0.0.1:10056"
DKFILTER_OUT_ARGS="--keyfile=$DKFILTERDIR/private.key --selector=dk
--domain=$DOMAIN --method=nofws --headers 127.0.0.1:10057
127.0.0.1:10058"
DKFILTER_IN_BIN="$DKFILTERDIR/bin/dkfilter.in"
DKFILTER_OUT_BIN="$DKFILTERDIR/bin/dkfilter.out"
PIDDKFILTER_IN="/var/run/dkfilter.in"
PIDDKFILTER_OUT="/var/run/dkfilter.out"
case "$1" in
start)
echo -n "Starting inbound DomainKeys-filter (dkfilter.in)..."
start-stop-daemon --start -q -p$PIDDKFILTER_IN -u
$DKFILTERUSER -g $DKFILTERGROUP -x `$DKFILTER_IN_BIN $DKFI
LTER_IN_ARGS` &
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo done.
else
echo failed.
exit $RETVAL
fi
echo -n "Starting outbound DomainKeys-filter (dkfilter.out)..."
start-stop-daemon --start -q -p $PIDDKFILTER_OUT -u
$DKFILTERUSER -g $DKFILTERGROUP -x `$DKFILTER_OUT_BIN $D
KFILTER_OUT_ARGS` &
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo done.
else
echo failed.
exit $RETVAL
fi
;;
stop)
echo -n "Shutting down inbound DomainKeys-filter (dkfilter.in)..."
start-stop-daemon --stop -p $PIDDKFILTER_IN
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo done.
else
echo failed.
fi
echo -n "Shutting down outbound DomainKeys-filter (dkfilter.out)..."
start-stop-daemon --stop -p $PIDDKFILTER_OUT
RETVAL=$?
if [ $RETVAL -eq 0 ]; then
echo done.
else
echo failed.
exit $RETVAL
fi
;;
restart)
$0 stop
$0 start
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
;;
esac
Y una vez arrancado, ya podemos reiniciar Postfix:
# /etc/init.d/dkfilter start
# postfix reload
El sistema está funcionando. (En Gentoo podemos añadir dkfilter al runlevel default con rc-update, en otras distros o bien con sus utilidades o como toda la vida con un ln al rc.d correspondiente y au). Ahora sólo falta comprobar las cabeceras de los emails que llegan por si algún emisor que no seamos nosotros también está implementando DomainKeys:
Authentication-Results: fraga from=bugzilla-daemon@gentoo.org;
domainkey=neutral (no signature; no policy for gentoo.org)
Y para el envío, configuramos el cliente de correo para usar el puerto submission (587 -grep submission /etc/services-) y firmaremos:
DomainKey-Signature: a=rsa-sha1; h=Received:Date:From:To:Subject:Message-ID:
Organization:X-Vader:X-Mailer:Mime-Version:Content-Type:
Content-Transfer-Encoding; b=wCSIKygHWje8oa5lSRW7L1Rzwk...S8y9xkFfM+Q=;
c=nofws; d=fluzo.org; q=dns; s=m1
Working!
« Micro chulla SVN
Romario, a un gol de los 1000 »