What is SMTP?
Simple mail transfer protocol is one of the first text based protocols that software engineers play with. You can easily fire up a netcat session,talk to a mail server and deliver email.
The excitement of seeing a mail sent by using low level semantics is not only very gratifying for a smart programmer it also used to serve a useful purpose.
Until the problem of spam came long.
And it is no longer possible to live so simply because we no longer live in a wholly trusted world where we can be believed to be who we claim to be.
E-mail spam filters started putting all sorts of rules and regulations on how emails are to be sent, who can send it, from which IP addresses, how many in a minute and so on.
The long list of rules are worrisome to many but people always find ways to fight them.
Or else by today spam would be a solved problem.
In 1980, Jon Postel proposed the Mail Transfer Protocol as a replacement of the use of FTP for mail.
In November 1981, Postel published RFC 788 “Simple Mail Transfer Protocol”.
The SMTP standard was developed around the same time as Usenet, a one-to-many communication network with some similarities.
The original SMTP protocol supported only unauthenticated unencrypted 7-bit ASCII text communications, susceptible to trivial man-in-the-middle attack, spoofing, and spamming, and requiring any binary data to be encoded to readable text before transmission.
Due to absence of a proper authentication mechanism, by design every SMTP server was an open mail relay. The Internet Mail Consortium reported that 55% of mail servers were open relays in 1998.
Popularity of the Internet meant that SMTP had to include specific rules and methods for relaying mail alongside authenticating users to prevent abuses such as relaying of unsolicited email (spam).
As this protocol started out purely ASCII text-based, it did not deal well with binary files, or characters in many non-English languages. Standards such as Multipurpose Internet Mail Extensions (MIME) were developed to encode binary files for transfer through SMTP. Mail transfer agents (MTAs) developed after Sendmail also tended to be implemented 8-bit-clean, so that the alternate “just send eight” strategy could be used to transmit arbitrary text data (in any 8-bit ASCII-like character encoding) via SMTP.
Today’s SMTP implementations
Email is submitted by a mail client (mail user agent, MUA) to a mail server (mail submission agent, MSA) using SMTP on TCP port 587. Most mailbox providers still allow submission on traditional port 25.
The example of MSAs are webmail, Microsoft Outlook, thunderbird, mutt.
Any e-mail client where you type out mail is an MSA.
Users almost always interact only with MSAs never with mail servers directly.
The MTA uses DNS to look up the MX (mail exchanger) record for the recipient’s domain (the part of the email address on the right of @). The MX record contains the name of the target MTA. Based on the target host and other factors, the sending MTA selects a recipient server and connects to it to complete the mail exchange.
Here is an example of an MX lookup.
$ dig +short gmail.com mx 20 alt2.gmail-smtp-in.l.google.com. 40 alt4.gmail-smtp-in.l.google.com. 10 alt1.gmail-smtp-in.l.google.com. 5 gmail-smtp-in.l.google.com. 30 alt3.gmail-smtp-in.l.google.com.
Message transfer can occur in a single connection between two MTAs, or in a series of hops through intermediary systems. A receiving SMTP server may be the ultimate destination, an intermediate “relay”.
Per RFC 5321 section 2.1, each hop is a formal handoff of responsibility for the message, whereby the receiving server must either deliver the message or optionally report the failure to do so.
Once the final hop accepts the incoming message, it hands it to a mail delivery agent (MDA) for local delivery. An MDA saves messages in the relevant mailbox format.
SMTP defines message transport, not the message content. Thus, it defines the mail envelope and its parameters, such as the envelope sender, but not the header (except trace information) nor the body of the message itself. STD 10 and RFC 5321 define SMTP (the envelope), while STD 11 and RFC 5322 define the message (header and body), formally referred to as the Internet Message Format.
SMTP is a connection-oriented, text-based protocol in which a mail sender communicates with a mail receiver by sending commands and giving necessary data over TCP connection. An SMTP session consists of commands originated by an SMTP client (the initiating agent, sender, or transmitter) and corresponding responses from the SMTP server (the listening agent, or receiver) so that the session is opened, and session parameters are exchanged. A session may include zero or more SMTP transactions. An SMTP transaction consists of three command/reply sequences:
MAIL command, to establish the return address, also called
- bounce address
- mfrom, or
- envelope sender.
RCPT command, to establish a recipient of the message.
This command can be issued multiple times, one for each recipient. These addresses are also part of the envelope.
DATA to signal the beginning of the message text
The content of the message, as opposed to its envelope. It consists of a message header and a message body separated by an empty line. DATA is actually a group of commands, and the server replies twice: once to the DATA command itself, to acknowledge that it is ready to receive the text, and the second time after the end-of-data sequence, to either accept or reject the entire message.
Besides the intermediate reply for DATA, each server’s reply can be either positive (2xx reply codes) or negative. Negative replies can be permanent (5xx codes) or transient (4xx codes). A reject is a permanent failure and the client should send a bounce message to the server it received it from. A drop is a positive response followed by message discard rather than delivery.
In the case of greylisting a transient error code 401 is sent.
The initiating host, the SMTP client, can be either an end-user’s email client, functionally identified as a mail user agent (MUA), or a relay server’s mail transfer agent (MTA), that is an SMTP server acting as an SMTP client, in the relevant session, in order to relay mail. Fully capable SMTP servers maintain queues of messages for retrying message transmissions that resulted in transient failures.
A MUA knows the outgoing mail SMTP server from its configuration. A relay server typically determines which server to connect to by looking up the MX (Mail eXchange) DNS resource record for each recipient’s domain name. If no MX record is found, a conformant relaying server (not all are) instead looks up the A record.
How to test a network protocol with netcat?
What is netcat first?
NC(1) BSD General Commands Manual NC(1) NAME nc — arbitrary TCP and UDP connections and listens SYNOPSIS nc [-46bCDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] [-m minttl] [-O length] [-P proxy_username] [-p source_port] [-q seconds] [-s sourceaddr] [-T keyword] [-V rtable] [-W recvlimit] [-w timeout] [-X proxy_protocol] [-x proxy_address[:port]] [destination] [port] DESCRIPTION The nc (or netcat) utility is used for just about anything under the sun involving TCP, UDP, or UNIX-domain sockets. It can open TCP connections, send UDP packets, listen on arbitrary TCP and UDP ports, do port scanning, and deal with both IPv4 and IPv6. Unlike telnet(1), nc scripts nicely, and separates error messages onto standard error instead of sending them to standard output, as telnet(1) does with some.
Netcat is a very effective tool for debugging network problems or understanding a network protocol like SMTP.
Sample SMTP handshake
Here is an example of SMTP communication from my mail logs.
>>> 220 mail.spamcheetah.com ESMTP OpenSMTPD <<< EHLO sender4-of-o59.zoho.com STATE_CONNECTED -> STATE_HELO >>> 250-mail.spamcheetah.com Hello sender4-of-o59.zoho.com [126.96.36.199], pleased to meet you >>> 250-8BITMIME >>> 250-ENHANCEDSTATUSCODES >>> 250-SIZE 36700160 >>> 250-DSN >>> 250-STARTTLS >>> 250 HELP <<< STARTTLS >>> 220 2.0.0 Ready to start TLS STATE_HELO -> STATE_TLS 7b7a10078eeb6f1f smtp tls ciphers=TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256 7b7a10078eeb6f1f smtp cert-check result="no certificate presented" STATE_TLS -> STATE_HELO <<< EHLO sender4-of-o59.zoho.com STATE_HELO -> STATE_HELO >>> 250-mail.spamcheetah.com Hello sender4-of-o59.zoho.com [188.8.131.52], pleased to meet you >>> 250-8BITMIME >>> 250-ENHANCEDSTATUSCODES >>> 250-SIZE 36700160 >>> 250-DSN >>> 250 HELP <<< MAIL FROM:<email@example.com> >>> 250 2.0.0 Ok <<< RCPT TO:<firstname.lastname@example.org> >>> 250 2.1.5 Destination address valid: Recipient ok <<< DATA >>> 354 Enter mail, end with "." on a line by itself STATE_HELO -> STATE_BODY <<< [MSG] Received: from sender4-of-o59.zoho.com (sender4-of-o59.zoho.com [184.108.40.206]) <<< [MSG] by mail.spamcheetah.com (OpenSMTPD) with ESMTPS id c9435d45 (TLSv1.2:ECDHE-RSA-AES256-GCM-SHA384:256:NO) <<< [MSG] for <email@example.com>; <<< [MSG] Sun, 27 Jun 2021 22:15:55 +0530 (IST) <<< [MSG] ARC-Seal: i=1; a=rsa-sha256; t=1624812344; cv=none; <<< [MSG] d=zohomail.com; s=zohoarc; <<< [MSG] b=TuBHzRARUw+Kejxnj/L7OaCcdGxWJGst4G54DdGldogKmrrGWltBy/X3Qj54hJg6YPOrjesL3t98Tjt+qJfK3NbFvJf0ZG7FW1rqcpjVBcF3YxFU/oTCNEuCk1RQOe8hTyJ2ao36HGjV+KYRrwxuIBrGGtYyoiUT6MVjC4pwDno= <<< [MSG] ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; <<< [MSG] t=1624812344; h=Content-Type:Date:From:MIME-Version:Message-ID:Subject:To; <<< [MSG] bh=stsNObeqRx2lyen5BJCd3LjHtyBjsksdZg4PncbB+78=; <<< [MSG] b=dGMYo2ySVyWueI5HO2SH2PbWeeVFYfzqT8N0uzUZUWAMBd3KpbVDasuzVqM6ewyoeasm+EAWAowPsTrTyjlLUEf8avpvd79Dqmm2EyBYcldI2b86L+QaVUAerT2amZgxXv2EaW//l3A/VP8pdSnzm7trdxrS1Mp+DqNAvdls5kw= <<< [MSG] ARC-Authentication-Results: i=1; mx.zohomail.com; <<< [MSG] dkim=pass header.i=zoho.com; <<< [MSG] spf=pass firstname.lastname@example.org; <<< [MSG] dmarc=pass header.from=<email@example.com> <<< [MSG] DomainKey-Signature: a=rsa-sha1; q=dns; c=nofws; <<< [MSG] s=zapps768; d=zoho.com; <<< [MSG] h=date:from:to:message-id:subject:mime-version:content-type; <<< [MSG] b=fhE85bl7Ce++DzfX0A6rRCFPyitIGsDwUL09CJyey8XFD9Cot2oLZew1DMIs5UCl9opKk83Xf+Wn <<< [MSG] hbhNloaKf72RaqSXdkj3Im/ix294HJHSK3KbliXEO0cVhQeIeSIH <<< [MSG] DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; t=1624812344; <<< [MSG] s=zm2020; d=zoho.com; firstname.lastname@example.org; <<< [MSG] h=Date:From:To:Message-Id:Subject:MIME-Version:Content-Type; <<< [MSG] bh=stsNObeqRx2lyen5BJCd3LjHtyBjsksdZg4PncbB+78=; <<< [MSG] b=GhGza3HE/7IOcdlPj3lR9/wQdG9uJbvpZydDJezQcheBFHSs7z+iQUiDVbNPlEJ2 <<< [MSG] F7OUMakpKKiG4/vSIyMgdQcWDFpJF3l6zZqLCvdBOBnERs2Vrl6TzGUFy662+KWUmOG <<< [MSG] poWqa2c1xZJyUqgGsSerE5TdkxIHBiTANHhxH+1w= <<< [MSG] Received: from mail.zoho.com by mx.zoho.com <<< [MSG] with SMTP id 162481234211673.17682546065134; Sun, 27 Jun 2021 09:45:42 -0700 (PDT) <<< [MSG] Date: Sun, 27 Jun 2021 09:45:42 -0700 <<< [MSG] From: email@example.com <<< [MSG] To: firstname.lastname@example.org <<< [MSG] Message-Id: <email@example.com> <<< [MSG] Subject: Report domain: spamcheetah.com Submitter: zoho.com Report-ID: <<< [MSG] b94fb7e3-d292-4e51-800d-fe9701fcab02 <<< [MSG] MIME-Version: 1.0 <<< [MSG] Content-Type: multipart/mixed; <<< [MSG] boundary="----=_Part_1528706_309504472.1624812342114" <<< [MSG] X-Zoho-Virus-Status: 1 <<< [MSG] <<< [MSG] ------=_Part_1528706_309504472.1624812342114 <<< [MSG] Content-Type: text/html; charset="UTF-8" <<< [MSG] Content-Transfer-Encoding: 7bit <<< [MSG] <<< [MSG] This is an automated DMARC aggregate report from zohomail <<< [MSG] <<< [MSG] <<< [MSG] ------=_Part_1528706_309504472.1624812342114 <<< [MSG] Content-Type: application/octet-stream; <<< [MSG] name=zoho.com!spamcheetah.com!1624604400!1624690800.xml.gz <<< [MSG] Content-Transfer-Encoding: base64 <<< [MSG] Content-Disposition: attachment; <<< [MSG] filename=zoho.com!spamcheetah.com!1624604400!1624690800.xml.gz <<< [MSG] <<< [MSG] H4sIAAAAAAAAAJ1UwZLiIBC9z1dYuSckTtRxCzN72i/YPacIdAw1BCgg48x+/RKJkqhTNbVehNev <<< [MSG] m9evbfHrRy9W72AsV/KQFFmerEBSxbg8HpI/v3+lL8nKOiIZEUrCIZEqea2ecAvAGkLfqqeV/2AD <<< [MSG] WhlX9+AII44E9BxR5lhL0kP1V3Uqo6rH6ApFFvSEi0oqX0d8pqwnhv6MCSE6Y384Q2qqpCPU1Vy2 <<< [MSG] quqc0/YHQqfTKbskojENdSA0IqznvitplQB0Lp9qJTj9zDrXC//CfcX43NQcZ1WzL9tmB88pW+/X <<< [MSG] aQmbIn3Jc5a2sN/lRUtJk68xivxYw7sCtSHyOOv6HGjgyGVVbNflNi/LPMcoIEsWSBY4+/xl5Iz3 <<< [MSG] WBzdVr9qWA4Eh55rPTSC2w4WApV3S1ZWk5524NO64P2ERyJhb7yvDEbhMAtY3Z7x8TvC2o9VAkZ6 <<< [MSG] jlFXFWMf4yHC3nWPXbz30Ydy/TyoMnPtRp1u/LJqMBRqrqvtJlsXWVHusw1GEV7SqRqkV4RROCyD <<< [MSG] kwp4J2LwPrNlOJjHrVaWO79DU7dz5AF/dE4Taz1xYWJswHsYCAs3F748UOQHP/cCcwbS8Zb7/b4p <<< [MSG] 0gFhYOrWqP5+6PPgrPbDapgMrqsN2EG420e+aC6Qp/6mywOTvvmLjJ6BAOqUGTcl3zzvdps8m2V7 <<< [MSG] Ky+EGz/vZeI71/9P0vc6tVRpqPrRbi/yfLlRuFwpdG/5WD1shV+g63/zP8nEzfDeBQAA <<< [MSG] ------=_Part_1528706_309504472.1624812342114-- <<< [MSG] <<< [MSG] . <<< [EOM] >>> 250 2.0.0 c9435d45 Message accepted for delivery 7b7a10078eeb6f1f smtp message msgid=c9435d45 size=3859 nrcpt=1 proto=ESMTP 7b7a10078eeb6f1f smtp envelope evpid=c9435d4534da263c from=<firstname.lastname@example.org> to=<email@example.com> STATE_BODY -> STATE_HELO 7b7a1008869e924a mda delivery evpid=c9435d4534da263c from=<firstname.lastname@example.org> to=<email@example.com> rcpt=<firstname.lastname@example.org> user=girish delay=3s result=Ok stat=Delivered <<< QUIT >>> 221 2.0.0 Bye STATE_HELO -> STATE_QUIT
SMTP is not just a protocol for sending email but also for DMARC reports as you can see. It is also used for cron jobs and other background tasks.
The idea of automation is built into SMTP but unfortunately for us that is what spammers abuse.
What is a session?
A session is nothing but a state machine in which the trust is established and the commands that can be sent after a session state cannot be sent before. Sessions have other formal purposes but from the point of view of SMTP from the mail logs above you can glean that broadly speaking there are 3 states. As the standard SMTP defines.
Practically speaking however, the initial introduction in a simple
HELO itself is pretty significant.
If the RBL check or sender score does not check out we simply ask them to stop bothering with further commands.
SMTP state machine in depth
Here is a block diagram of how SMTP works. If it was not already clear from above.
It is indeed brain dead simple.
That is why perhaps it is so easily for spammers to create a protocol sender.
Can SMTP in today’s Google centric world help?
In today’s email traffic , if you were to look at who handles all the mailing and SMTP protocol wire traffic, you find that a major chunk is handled by Google servers.
This is definitely a cause for worry since the underdogs are in trouble if the big boys take decisions that can hurt us.
It is always desirable to have a democratic technology distribution.
So our thrust is for more and more mail server deployments as the email service from Google is not very good anyway.
You can easily develop your own mail server and spam control and get going in no time.
Why should you run your own mail server?
Setting up one’s own mail server is really easy as we saw in this article that SMTP is no big deal anyway.
Kidding aside the checklist for setting up a mail server on your own is not at all daunting.
If you have been following our blogs then with a fair bit of googling you can come up with a plan to dump dependence on third party mail corporations and instead take things into your own hands.
Are there alternatives to SMTP?
As of 2021, there does not seem to be many. The age old protocol is still being used and with only some SSL or TLS pipes and some slight extensions.
The possibility of a new standard replacing RFC5321 does not seem likely.