El objetivo de SMTP (Simple Mail Transport Protocol) es transferir correo de forma segura y eficiente entre diferentes subsistemas de una red WAN o LAN. Requiere de un transporte que usualmente es TCP pero no está restringido solamente a este protocolo. El único requisito es que sea un transporte seguro y que se haga de forma ordenada. Permite que un correo sea retransmitido por una serie de hosts intermedios de una red. Luego, para la recepción final de los correos, normalmente se utilizan otros protocolos como por ejemplo POP (Post Office Protocol) e IMAP. Uno de los RFC que lo define es el 5321 [1].
El siguiente dibujo esquematiza la arquitectura e interacciones típica de un sistema con SMTP:
+----------+ +----------+
+------+ | | | |
| User |<-->| | SMTP | |
+------+ | Client- |Commands/Replies| Server- |
+------+ | SMTP |<-------------->| SMTP | +------+
| File |<-->| | and Mail | |<-->| File |
|System| | | | | |System|
+------+ +----------+ +----------+ +------+
SMTP client SMTP server
Los servidores pueden tener diferentes características las cuales no todas son definidas como obligatorias en el RFC. Los servidores llamados fully-capable en el RFC, son servidores que entre otras cosas proveen mecanismos de encolamiento y retransmisión. Notar que luego que un servidor recibe un correo, puede tomar el rol de cliente y reenviar el correo hacia otro servidor. Usualmente a estos servidores se les llama "relay servers".
Para realizar pruebas se puede utilizar cualquier servidor de correo, por ejemplo los de Google. Los hostnames se pueden obtener mediante el comando dig
:
dig MX <hostname>
El envío de correos se hace mediante una serie de comandos de forma transaccional. Los comandos pueden tener argumentos, por ejemplo el comando RCPT
lleva el argumento to
. Se pueden diferenciar dos partes en todo el envío de un correo: el envelope y el contenido. El envelope contiene la dirección que origina el correo (y la cual se le reportarán los errores que ocurriesen), uno o mas destinatarios (recipients) y otros datos opcionales. El contenido tiene dos partes: los headers y el cuerpo. Cada header se compone de un nombre, el caracter ":" y el valor. Los caracteres de las líneas de comandos se codifican en ASCII y se finalizan con el caracter CRLF (caracteres de valores hexadecimales 0D y OA respectivamente).
Generalmente cuando un servidor recibe un comando, devuelve una respuesta (reply) positiva o negativa. Normalmente contienen un valor númerico que se utiliza en programas y un texto descriptivo para humanos.
Todo esto sobre el formato de los mensajes, la sintaxis general de los comandos y la terminología de SMTP se explica en las secciones 2.3 2.4.
Lo primero que se debe hacer es iniciar la sesión de cliente. Para probar esto conectar mediante telnet
al hostname de un servidor de correo :
telnet <hostname> 25
El servidor deberá responder con un código de status de éxito :
220 mx.google.com ESMTP e126si4048244qkb.261 - gsmtp
Es similar a un saludo para identificar el cliente en el servidor: "Hola soy ". Para esto se utiliza el comando HELO
(o EHLO
):
Se deben enviar tres comandos (cada uno en una línea):
MAIL FROM:<user@domain>
: Indica al servidor cual es la dirección del usuario que envía el correo.RCPT TO:<user@domain>
: Indica al servidor cual es la dirección del usuario que va a recibir el correo.DATA
: Inicia la parte de contenido del correo.
Aclaraciones (ver sección 4 del RFC):
- La sintaxis de los comandos anteriores muestra una versión simplificada, en algunos casos se pueden agregar mas argumentos.
- Los caracteres "<" y ">" son obligatorios.
- Puede haber mas de un destinatario, esto se logra ingresando mas de un comando
RCPT
.- El contenido del correo (luego del comando
DATA
), se debe finalizar con el caracter "." y un CRLF.
En este ejemplo se muestra la secuencia de comandos completa para enviar un correo. Primero se debe establecer la conección TCP con el servidor y luego ir ingresando los comandos (no se deben ingresar las respuestas del servidor con los códigos de status):
HELO fromtheotherside
250 mx.google.com at your service
MAIL FROM:<[email protected]>
250 2.1.0 OK c7si428870qkj.67 - gsmtp
RCPT TO:<[email protected]>
250 2.1.5 OK c7si428870qkj.67 - gsmtp
DATA
354 Go ahead c7si428870qkj.67 - gsmtp
Mensaje enviado con telnet
.
421-4.7.0 [167.58.7.228 15] Our system has detected that this message is
421-4.7.0 suspicious due to the very low reputation of the sending IP address.
421-4.7.0 To protect our users from spam, mail sent from your IP address has
421-4.7.0 been temporarily rate limited. Please visit
421 4.7.0 https://support.google.com/mail/answer/188131 for more information. c7si428870qkj.67 - gsmtp
Notar que la respuesta final no es de éxito lo que se debe a que el dominio ingresado como argumento del comando HELO
no es válido. Además, para poder enviar correo a través de los servidores de Google se requiere establecer una conección encriptada con SSL [3]. En lugar de usar el comando de AUTH LOGIN
como se menciona en [3], es mejor usar el comando AUTH XOAUTH2
de SMTP generando un código en base 64 [4].
[1]: RFC 5321, https://www.rfc-editor.org/rfc/rfc5321.txt
[2]: General Syntax Principles and Transaction Model, RFC 5321, Section 2.4
[3]: How to send email using simple smtp commands via gmail, https://stackoverflow.com/questions/11046135/how-to-send-email-using-simple-smtp-commands-via-gmail
[4]: SMTP Protocol Exchange, https://developers.google.com/gmail/imap/xoauth2-protocol#smtp_protocol_exchange.