mira dentro de mí

15 de julio de 2009

Cuando enviamos un correo electrónico de una dirección a otra, toda esta información se envía en formato texto ASCII. Incluso cuando adjuntamos una imagen o un archivo PDF el correo resultante que viaja de un servidor a otro lo hace en formato texto.
Para ello se utilizan conceptos como los tipo MIME y la codificación en Base64. Hoy día es difícil ver correos que no este hechos en formato HTML con imágenes y a todo color.

Cuando enviamos un correo no solo estamos enviado el cuerpo del mensaje con su From/To, sino mucha más información como editor de correo donde se escribió el mensaje, cuales han sido los antivirus que han analizado el correo, por donde ha ido pasando el correo etc.
El analizar las cabeceras de un correo electrónico puede ser una manera de depurar errores y de comprender un poco más el funcionamiento del SMTP.

Aquí tenéis un ejemplo de un correo que utilizaré para explicar cada una de las partes que lo componen: example_mail.txt.
Se trata de un correo de publicidad de masters de la Universidad de La Salle (Barcelona) enviado a mí a través de una lista de distribución tal como veremos. Desde cualquier cliente de correo podéis acceder a las cabeceras de un correo electrónico.

Si abrimos este correo de ejemplo lo primero que miraremos es quien lo escribe y quien lo recibe:

From: "BES La Salle" <infosolicitud@lasalleonline.net>
To: <infosolicitud@lasalleonline.net>

Es curioso ver que el emisor y el receptor son la misma persona. ¿Cómo puede ser?. En este caso se trata de una lista de distribución. Para ello debemos fijarnos en:
Delivered-To: amperisblog@gmail.com
List-Unsubscribe: <http://columba.salleURL.edu/cgi-bin/mailman/options/infoalumnes>,
                <mailto:infoalumnes-request@columba.salleURL.edu?subject=unsubscribe>
X-Mailman-Approved-At: Fri, 10 Jul 2009 10:09:03 +0200

Nos da la posibilidad de borrarnos de la lista de distribución. Este tipo de casos también pude darse cuando se envia un mail con copia oculta. En el campo To: no aparece nuestro nombre. Esto es debido a que nos han puesto como copia oculta.

También tenemos el campo Date que indica la hora a la que se escribió el mensaje. No es la hora en la que se descargó el mensaje. Por este motivo si tenemos algún problema con nuestro servidor de correo y los correos llegan tarde, es normal que nos aparezcan en nuestra bandeja de entrada correos de fechas pasadas. Normalmente la bandeja de entrada está ordena por fecha.

Date: Fri, 10 Jul 2009 10:08:34 +0200

También podemos ver los diferentes servidores MX por los que ha ido pasando el correo y extraer mucha información de como una empresa tiene implementado sus servidores de correo. Para ello nos tenemos que fijar en los campos "Received":
Received: by 10.103.218.8 with SMTP id v8cs318399muq;
        Fri, 10 Jul 2009 01:10:31 -0700 (PDT)
Received: by 10.204.50.195 with SMTP id a3mr1643982bkg.123.1247213430935;
        Fri, 10 Jul 2009 01:10:30 -0700 (PDT)
Received: from relay1.salle.url.edu (relay1.salle.url.edu [84.88.232.246])
        by mx.google.com with ESMTP id 27si1340370fxm.114.2009.07.10.01.10.29;
        Fri, 10 Jul 2009 01:10:30 -0700 (PDT)
Received: from columba.salle.url.edu (columba.salleURL.edu [84.88.232.238])
 by relay1.salle.url.edu (8.14.3/8.14.3/Debian-5) with ESMTP id n6A8A2sH019065
 (version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT);
 Fri, 10 Jul 2009 10:10:03 +0200
Received: from columba.salle.url.edu (localhost [127.0.0.1])
 by columba.salle.url.edu (8.14.3/8.14.3/Debian-5) with ESMTP id n6A894eQ014556;
 Fri, 10 Jul 2009 10:09:59 +0200
Received: from jordiribesi00cc (pcjribes.salle.url.edu [172.16.17.189])
 (authenticated bits=0)
 by columba.salle.url.edu (8.14.3/8.14.3/Debian-5) with ESMTP id
 n6A88ZMC014449; Fri, 10 Jul 2009 10:08:35 +0200

El primer Received que encontramos es directamente nuestro servidor donde está alojado el correo a la espera que nosotros lo leamos por POP/IMAP/Webmail. El último "Received" es el primer servidor SMTP que recibió el correo.
Podemos ver como el correo lo escribió una persona llamada jordiribesi00cc, que su ordenador tenia la IP 172.16.17.189 y que se lo envió a su servidor de correo llamado columba.salle.url.edu" que resulta ser un Sendmail versión 8.14.3 con un Debian v5.
Luego lo volvió a recibir la maquina columba.salle.url.edu en la IP 127.0.0.1. Esto es posible porque se lo pasó al antivirus alojado en su misma maquina. Posteriormente se lo envía a una maquina de relay de correo bajo el nombre de relay1.salle.url.edu a través de una sesión cifrada (cipher=DHE-RSA-AES256-SHA). Finalmente esta maquina sale de la empresa salle.url.edu y contacta con Google para entregarle el correo. La maquina relay1.salle.url.edu con IP pública 84.88.232.246 contacta con el servidor mx.google.com y le entrega el correo a las 01:10:30 hora verano del Pacifico Norte (PDT=UTC-7).
Para finalizar, el correo va pasando por dos máquina más de Google hasta que a las 01:10:31 hora verano del Pacifico Norte se almacena en el servidor con IP 10.103.218.8.

Notar que hay 7 saltos para hacer llegar el correo de un servidor a otro. ¿Son 7 o son más?. Realmente no lo podemos saber. Podría ser el caso que algún servidor interno, por ejemplo Google, no notificara en sus cabeceras por donde va pasando dicho correo.
Otra cosa interesante es saber la versión de Sendmail que está utilizando salle.url.edu. Deberíamos evitar que nuestros servidores dejaran información sobre versiones y sistemas operativos de los servidores de correo. Normalmente por cuestiones de seguridad y bugs que puedan ser explotados.

Se está trabajando en técnicas conocidas como "Reciprocation of SMTP Trace Record" para depurar por donde a ido pasando un correo electrónico. Incluso existe alguna Web que haces un copy-paste del tus Received y te dibuja en un mapa la ruta seguida por el correo al más puro estilo Neotrace.

Los antivirus y otros filtros también dejan su marca cada vez que escanean un correo:
X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on relay1.salle.url.edu
X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on columba.salle.url.edu
X-Virus-Scanned: ClamAV version 0.94.2, clamav-milter version 0.94.2 on columba.salle.url.edu
X-Virus-Status: Clean
X-Scanned-By: MIMEDefang 2.64 on 84.88.232.246
X-Scanned-By: MIMEDefang 2.64 on 84.88.232.238
X-Scanned-By: MIMEDefang 2.64 on 84.88.232.238

Estamos en lo de simpre... evitar que aparezcan versiones y cualquier tipo de información.

Nota: Para evitar que nuestro Postfix/Sendmail anote sus direcciones IP internas o externas en la cabeceras hay que retocar el código fuente y recompilar.

Para debugear este correo cuando llega al primer servidor de correo se añade una marca de idetificación llamada Message-ID. Esta marca la podemos utilizar para tracear el mensaje dentro de nuestros logs de correo.
Message-ID: <000601ca0135$9f2ab0b0$dd801210$@net>

Finalmente llegamos a la parte del cuerpo del mensaje. Dado de que se trata de un correo con imágenes, en HTML y con archivos adjuntos este correo debe ser compuesto en formato MIME (Multipurpose Internet Mail Extension). El MIME son unas extensiones del protocolo SMTP que me permite intercambiar todo tipo de contenido (video, PDF, imágenes, Words, etc) de forma transparente para el usuario.

Lo primero que debemos encontrar son estas dos cabeceras:
MIME-Version: 1.0
Content-Type: multipart/mixed;
 boundary="----=_NextPart_000_0007_01CA0146.62B380B0"
X-Mailer: Microsoft Office Outlook 12.0

Lo primero indica que estamos utilizando MIME v1 y el segundo nos indica que el mail está estructurado en varias partes (cuerpo, adjuntos, cuerpo en HTML, etc). En este caso cada parte podrá contener más objetos de tipo MIME. Para separar cada parte de los objetos MIME se utilizará la marca "----=_NextPart_000_0007_01CA0146.62B380B0". Vemos también que el cliente de correo que ha construido el mail en formato MIME a sido un Outlook 2007.

Dentro del objeto MIME con marca "----=_NextPart_000_0007_01CA0146.62B380B0" veremos que encontramos otros objetos MIME que lógicamente también contienen su marca. Por ejemplo "----=_NextPart_001_0008_01CA0146.62B380B0" o "----=_NextPart_002_0009_01CA0146.62B380B0".

Bajo la marca "----=_NextPart_002_0009_01CA0146.62B380B0" encontramos el cuerpo del mensaje en formato texto o "text/plain". Este tipo de objeto se añade por si el receptor no tiene un cliente de correo que acepte HTML.
Luego encontraremos bajo esta misma marca el mismo correo pero en formato HTML o "text/html". Este tipo de objeto se añade para los clientes que tienen un cliente de correo compatible con HTML.

Finalmente, los ficheros adjuntos también van dentro de su tipo MIME:
------=_NextPart_001_0008_01CA0146.62B380B0
Content-Type: image/jpeg;
 name="image001.jpg"
Content-Transfer-Encoding: base64
Content-ID: 

/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAoHBwgHBgoICAgLCgoLDhgQDg0NDh0VFhEYIx8lJCIf
IiEmKzcvJik0KSEiMEExNDk7Pj4+JS5ESUM8SDc9Pjv/2wBDAQoLCw4NDhwQEBw7KCIoOzs7Ozs7
Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozv/wAARCAB8AoQDASI
...

En este caso, una de las imágenes a sido añadida como un tipo de fichero adjunto. Para ello le decimos que es de tipo MIME "image/jpeg", que la imagen se llama image001.jpg y que está codificada en Base64. La codificación siempre es necesaria ya que al tratarse de un formato binario este debe convertirse en un formato de texto ASCII para poder ser enviado por SMTP.

Hay otras muchas cabeceras que incluso no salen es este mail de ejemplo. Todas ellas esta explicadas en sus RFCs correspondientes: RFC2045 y RFC2821.

Más información:
- http://es.wikipedia.org/wiki/Multipurpose_Internet_Mail_Extensions
- http://es.wikipedia.org/wiki/Base64