Saturday, March 24, 2012

Sending emails with SMTP

In this post, I'm going to show you how to send an email from the command-line without needing any sort of email client. We're going to be using a protocol called SMTP, which stands for Simple Mail Transport Protocol. This is the protocol that millions of email servers all over the world use to send emails to one another. The protocol is made up of a number of text-based commands and it actually is pretty simple. :-P

For this demonstration, let's send an email to ourselves. That way, once we've sent the email, we can open our inbox and confirm that it was successfully sent. I'll be using my own email address, mike.angstadt@gmail.com, in this blog post, but you should use your own instead obviously.

Finding the SMTP server address

Before we can start sending our email, we need to know where to send it to! In other words, we need to get the address of the SMTP server that our email address belongs to. To do this, we need to perform an MX record lookup against the "host" part of our email address, which is located to the right of the "@" symbol (the part to the left is called the "user" or "mailbox"). In my case, the host is "gmail.com".

To perform an MX record lookup on Linux, type the command dig mx HOST where HOST is the host address.

To perform an MX record lookup on Windows, type the command nslookup. Then, type set type=MX followed by the host name.

Performing an MX record lookup will most likely return a list of SMTP servers. So, which one should you pick? Well, any one will work, but the one with the lowest MX preference indicator should be used. On Linux, this is the number directly to the left of the SMTP address. On Windows, this is the number labeled "MX preference". If you were writing an SMTP server yourself, you would sort this list of addresses by preference indicator and then send the email to the one with the lowest value. If that server happens to be down, then you would keep going down the list until you found a server that worked. If all servers have the same preference indicator, then you should choose one randomly. This helps to evenly spread the load amongst all servers and thus make the server admins happy.

If the MX record lookup does not return any SMTP servers, that means you can use the host part of the email address itself as the SMTP server address.

Sending the email

Now that we have the address of the SMTP server, we can go ahead and send the email. The standard SMTP port is 25, so let's open a telnet connection on that port. To do this, run the command telnet ADDRESS 25, where ADDRESS is the SMTP server address.

Warning: In my experience, some SMTP servers are not very friendly toward "human" SMTP connections--they will terminate the connection if it's idle for only a few seconds. Yahoo is one such example.

The first command that is sent is the EHLO command. This allows the SMTP client (us) to introduce itself to the server. It contains the email host address of the SMTP client. For example, if I was a Hotmail server, I might enter EHLO hotmail.com. This is optional though, so you can just enter EHLO if you want.

Next, we'll specify who the email is from. This is done using the MAIL command. The syntax for this command is MAIL FROM:<address@website.com>. The syntax is very specific--there must be NO space after the colon and the email address MUST be surrounded by < and > characters.

Then, we specify who the email should be sent to using the RCPT command. The snytax for this command is RCPT TO:<mike.angstadt@gmail.com>. If the email has multiple recipients, then this command can be entered multiple times. Just as with the MAIL command, there must be NO space after the colon and the email address MUST be surrounded by < and > characters.

Now, we're ready to send the actual body of the email. Send the DATA command to let the server know that we're ready send the acutal message.

Next, enter the email data. The email data consists of a series of headers, followed by a blank line, followed by the email text, followed by a line consisting of just a single dot (.). Each header goes on its own line and has the syntax HeaderName: HeaderValue. At the very least, you should have the headers "From", "To", and "Subject" because this is what email clients use to display the sender, recipients, and subject of an email. For example, I'm going to type the following:

From: <address@website.com>
To: <mike.angstadt@gmail.com>
Subject: My first SMTP email!

Dear Mike,
This is my first SMTP email.
.

Then, the SMTP server sends the email! You can enter more emails if you like or you can terminate the connection by sending the QUIT command.

The entire SMTP conversation.

Now, open up your email account and you should see a new email! However, it will likely be considered spam because the host in the "from" address does not match who it was really sent from. For example, nothing's stopping me from entering "barack.obama@whitehouse.gov" as the sender. But, obviously, it's not really from the President of the United States, so it would likely be marked as spam. So check your spam folder if you don't see it in your inbox.

2 comments:

Jeho Kim said...

Good post.
I also would like to know how do I attach some files to my mail. Could you explain this? Command line explanation was very helpful.

Michael Angstadt said...

Thanks for the comment. Unfortunately, I haven't gotten that far in my studies! I do know, however, that the attachments are included in the DATA portion of the email, alongside the actual email body, and that the attachments are base64-encoded.