The Inner Workings of SMTP
You may already know that SMTP, the Simple Mail Transfer Protocol, is the main protocol used to submit messages from your email client to an email server and transfer them between servers. But as an eager student, a tech-savvy email marketer, or a beginner software developer, you may wonder: how does SMTP actually work? What happens under the hood of an SMTP server, and what may go wrong, resulting in delivery errors?
This article aims to answer this question in the most practical way. You’ll set up an SMTP server on your Windows computer and send an email to a local mailbox using nothing except your bare hands (and a bit of knowledge). At the end, you’ll also have a working setup you may use to test your email sending scripts.
To complete this tutorial, you’ll need a Windows or Linux computer with at least 4 gigabytes of RAM and 20 gigabytes of free disk space. The whole process should take one to two hours, though your mileage may vary.
Real or Fake SMTP Server: An Unexpected Question
Wait, what? Are there different kinds of SMTP servers, and one should take care to avoid “fake”, improper ones? Well, not quite. The term “fake SMTP” refers to software which implements the SMTP protocol but is only able to receive mail and store it locally. Such software may be useful for testing purposes, for example, if you need to evaluate the speed of your outbound mail flow that could be achieved with an ideal broadband connection. It is also a viable option to study the particulars of SMTP in a practical way.
However, we recommend using a widely adopted, production grade MTA (Mail Transfer Agent) even for testing and educational purposes. This way, your setup can closely match real life scenarios, and any problems you may encounter are also likely to show up in regular SMTP sessions. Besides, fake SMTPs cannot be used to test complex setups involving message relays. And finally, familiarizing yourself with popular SMTP server software will pay off if you ever need to set up one for your own needs.
For this tutorial, we’ve opted for Postfix, one of the most widely used MTAs which is relatively easy to install and configure. This software is free and open source, so you may use it for your business needs as well.
Installing Postfix on Windows
To install and configure Postfix on a Windows machine, you’ll need to take some preliminary steps. Postfix is designed for UNIX-like systems (Linux, BSD, etc.), and isn't natively supported on Windows. Fortunately, you can still launch it on Windows using virtualization software which will allow you to set up a virtual Linux environment (a so-called Virtual Machine, or VM) on your Windows system.
For this tutorial, we’ll be using Oracle VirtualBox, a popular open source virtualizer. You may use any other method of creating a Linux VM on Windows, or just set aside an older laptop you may own for the purposes of testing. However, I recommend using VirtualBox or similar software instead of a dedicated Linux computer for some added versatility. A virtualizer even allows you to run several Linux machines on a single Windows host to simulate a network for more complex scenarios. And if something goes wrong with your experiment, it’s often easier to delete a problematic VM and start from scratch, instead of painfully looking for a remedy.
If you are already familiar with virtualization software or have a spare Linux machine at your disposal, you may skip Steps 1 and 2 and proceed with actual Postfix installation.
Step 1. Install VirtualBox and Linux
For this step, you may use any Debian or Ubuntu based Linux distro to create a VM, or even try a few different flavors to see which one you like most. I personally prefer Linux Mint for its aesthetically pleasing greenish interface, so let’s use it as an example.
- Download and install VirtualBox:
- Go to the VirtualBox website and download the installer for Windows.
- Run the installer and follow the prompts to install. The process is pretty straightforward.
- Download Linux Mint (Cinnamon) ISO:
- Go to the Linux Mint download page and select the Cinnamon version.
- Download the ISO file for installation. This is a disk image you can use to install your copy of Linux using VirtualBox, or even burn a physical DVD disk if you love antique technologies.
- Set Up a Virtual Machine in VirtualBox:
- Open VirtualBox and click New.
- Name the VM (e.g., "Mint Test"), set Type to Linux, Version to Ubuntu (64-bit), and check the Skip Unattended Installation option. For ISO Image, specify the full filename of the Linux ISO file you’ve downloaded.
- On Hardware and Hard Disk tabs below, allocate memory (at least 2GB recommended) and create a virtual hard disk (20GB or more). This is just the upper limit for your VM and will not be claimed immediately, but you still need a few gigabytes of free space to accommodate your Linux installation.
- Install Linux Mint:
- Start the VM. In the Welcome menu, select “Start Linux Mint”. Wait until it fully loads, then click the Install Linux Mint icon on your virtual desktop and follow on-screen instructions. The process will take a few minutes. When prompted for your computer’s name, username and password, be sure to remember the values you enter. Although you may opt to log in automatically, in which case you do not need to enter your credentials when the VM starts, you’ll need these values later.
- After installation, reboot the VM, remove the ISO from storage, and start the machine again.
Step 2. Update and tweak Linux Mint
Open the desktop menu by pressing the Mint logo in the bottom left corner and type “terminal” in the search field, then press Enter. A command shell will open where you enter various commands to install apps and manage your system. While most such tasks may be performed using interactive tools, we will stick to Terminal here as we are going to need it later anyway.
Enter the following commands to apply the latest updates and security fixes. This process usually takes another few minutes, so you’ll have time to intake an extra dose of caffeine (consult your doctor if in doubt).
sudo apt update
sudo apt upgrade -y
When entering a command starting with sudo (which means it is run with admin privileges), the system may ask you to retype your password. Do not worry, this is normal.
Many people find the default Linux font size being too small for comfortable use, so be sure to adjust it according to your preferences. The easiest way is to turn on Large text in System Settings -> Accessibility. If the result is still inappropriate, install the interactive Gnome Tweak Tool by typing
sudo apt-get install gnome-tweak-tool
and choose the scaling factor you prefer (it is located on the Fonts tab, at the very bottom).
Step 3. Install Postfix
It’s finally time to install the Postfix software. In your Terminal window, run the following command:
sudo apt install postfix
This will install the latest version of Postfix on your VM. During installation, select Local only when asked for configuration type. Set the System mail name to localhost.
Check Postfix status:
sudo systemctl status postfix
This command will temporarily start the Postfix service on your machine. If you see no error messages, you’re ok to proceed with configuration.
Step 4. Configure Postfix for Localhost
To edit Postfix configuration, enter this command:
sudo nano /etc/postfix/main.cf
It invokes a very simple text editor, with your Postfix settings file already loaded. Ensure the following settings are in place:
myhostname = localhost
mydomain = localhost
myorigin = $mydomain
inet_interfaces = loopback-only
mydestination = $myhostname, localhost.$mydomain, localhost
relayhost =
home_mailbox = Maildir/
The last line will probably be missing, so you’ll have to add it manually. When done, save changes and exit (press Ctrl + X, then Y to confirm changes).
Restart Postfix with the following command for the changes to take effect:
sudo systemctl restart postfix
Performing a Basic SMTP Session
Step 5. Connect to Postfix Using Telnet
While still in Terminal, run Telnet to connect to Postfix:
telnet 127.0.0.1 25
Telnet is a program that allows you to connect to a given IP address (first parameter on the command line) in text mode, using a particular port number (second parameter). 127.0.0.1 is a special IP address which refers to the machine you’re at, and the name “localhost” you’ve seen earlier is an alias for this IP. So, by entering this command you are trying to connect to whatever program on your Linux VM is waiting for incoming data on port 25, the standard SMTP port.
You should see a message like:
Bingo! Believe it or not, you’ve just started an SMTP session, and the Postfix server tells you it’s there, waiting for meaningful commands. The number at the beginning of each server response is the numeric SMTP result code. Numbers from 200 to 299 tell us everything is ok, 300 to 399 prompt for more data, and 400 to 599 signify a temporary or permanent error.
Step 6. Submit an Email
Now you are ready to send an email manually, just by entering a few SMTP commands. First, you need to greet the server and introduce yourself:
HELO localhost
This way, you are providing the name of the domain you are “calling” from. Postfix responds with its own hostname (in our case, it’s the same):
But what if you make a typo and things go wrong? Do not worry, you won’t break anything. The worst thing possible is that your Telnet session unexpectedly terminates, and you have to restart it. In most cases you’ll just see an error message saying the command is not recognized.
Next, set the email sender:
MAIL FROM:<yourname@localhost>
Replace yourname with your current Linux username and be sure to keep the angle brackets in place. Postfix responds with a 250 Ok code.
Set the recipient:
RCPT TO:<yourname@localhost>
Use the same address you’ve entered in MAIL FROM. Yes, you are sending a message to yourself.
Finally, submit the email:
DATA
Postfix prompts you for the actual message:
An email consists of two parts, the envelope and the body. The envelope is a number of lines, called headers, containing technical information on your letter, such as subject, send date and time, sender and target addresses, and so on. Any SMTP server the message will pass through will also add its own headers to this section. In this example, the only header initially present will be Subject. The header part must be separated from the body with a blank line (by pressing Enter twice), otherwise an error will occur.
The body part is the email itself, and it may also consist of multiple parts: text version, HTML version, images, attachments, etc. In this example, however, it is just a single line of plain text. If you want to enter a longer text or use national characters, bear in mind that lines should not exceed 78 characters (not including end-of-line sequence), and any non-latin characters must be encoded. These matters are a bit too complex to discuss in this beginner tutorial, so for now please stick to shorter lines and look out for any error messages.
To end your email, press Enter to start a new line, input a single dot and press Enter again. This sequence tells the receiving party your message is over.
Close the session:
QUIT
This ends your SMTP session, and you are back in Terminal.
Step 7. Verify Email Delivery
So, if everything was ok, the email is now somewhere on your system, but where exactly? Let’s check our home directory:
ls ~
This command lists the contents of your home directory:
See a subdirectory named Maildir? We’ve used this name earlier when configuring Postfix, and this very directory is used to store your incoming email. Each message resides in a separate file, with a long and rather cryptic name. Let’s take a closer look:
ls ~/Maildir/new
Here it is! Let’s take a look inside:
cat ~/Maildir/new/<any filename you see in this dir>
While kittens are nice, this command has nothing to do with them. It just conCATenates your file(s) to the standard output (your Terminal window). Sounds a bit cryptic too, I know, but better get used to such things if you want to be on the good side of Linux.
As you can clearly see, Postfix has added quite a number of headers to our test email, besides the original Subject. Each header has its own meaning and purpose. By analyzing them, you can determine the exact route the email has followed, the results of authenticity checks, and so on. However, all of this deserves a few dedicated discussions.
In addition, you can also look up Postfix logs for delivery info:
sudo ls -la /var/log/mail*
You’ll see one or more files with names starting with mail.log. Check the most recent one, its name will be /var/log/mail.log. As more entries are added to the log, it is separated into several files named mail.log.1, mail.log.2 and so on, and older parts are compressed; this is called “log rotation”. You should see a few lines related to your recent SMTP session:
sudo cat /var/log/mail.log |less
Studying the SMTP log helps you locate and troubleshoot any issues you may encounter in the course of your work.
Conclusion
By now, you’ve hopefully got the feeling of what the inner workings of the SMTP protocol are like. You should be able to understand the basic SMTP commands and diagnose (or at least make a more educated guess on) the most basic issues like a misconfigured connection or malformed email. For a detailed description of SMTP, you may refer to the protocol’s most recent specification (RFC 5321).
And if you are in need of a fast and reliable way to send marketing and transactional emails in large volumes, be sure to check the email services offered by UniOne!