Postfix is a popular open-source Mail Transfer Agent (MTA) that can be used to route and deliver email on a Linux system. It is estimated that around 25% of public mail servers on the internet run Postfix.
In this guide, you’ll learn how to install and configure Postfix on an Ubuntu 22.04 server. Then, you’ll test that Postfix is able to correctly route mail by installing
s-nail, a Mail User Agent (MUA), also known as an email client.
Note that the goal of this tutorial is to help you get Postfix up and running quickly with only some bare-bones email functionality. You won’t have a full featured email server by the end of this guide, but you will have some of the foundational components of such a setup to help you get started.
Setting up and maintaining your own mail server is complicated and time-consuming. For most users, it’s more practical to instead rely on a paid mail service. If you’re considering running your own mail server, we encourage you to review this article on why you may not want to do so.
If you’re sure you want to follow this guide to install and configure Postfix, then you must first have the following:
sudoprivileges and a firewall configured with UFW. You can follow our Ubuntu 22.04 initial server setup guide to set this up.
Note that this tutorial assumes that you are configuring a host that has the FQDN of
mail.example.com. Wherever necessary, be sure to change
mail.example.com to reflect your own FQDN.
Postfix is included in Ubuntu’s default repositories, so you can install it with APT.
To begin, update your local
apt package cache:
sudo apt update
Then install the
postfix package with the following command. Note that here we pass the
DEBIAN_PRIORITY=low environmental variable into this installation command. This will cause the installation process to prompt you to configure some additional options:
sudo DEBIAN_PRIORITY=low apt install postfix
This installation process will open a series of interactive prompts. For the purposes of this tutorial, use the following information to fill in your prompts:
mail.<^>example.com<^>. You will likely want to set the system mail name to
<^>example.com<^>so that, given the username
user1, Postfix will use the address
postmaster@. Use your primary account for this. In this example case, sammy.
0disables any size restriction.
+will work for this tutorial.
To be explicit, these are the settings used in this guide:
$myhostname, <^>example.com<^>, <^>mail.example.com<^>, <^>localhost.example.com<^>, localhost
127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
<$>[note] Note: If you need to ever return to change these settings, you can do so by typing:
sudo dpkg-reconfigure postfix
The prompts will be pre-populated with your previous responses. <$>
When you are prompted to restart services, accept the defaults and choose
When the installation process finishes, you’re ready to make a few updates to your Postfix configuration.
Now you can adjust some settings that the package installation process didn’t prompt you for. Many of Postfix’s configuration settings are defined in the
/etc/postfix/main.cf file. Rather than editing this file directly, you can use Postfix’s
postconf command to query or set configuration settings.
To begin, set the location for your non-root Ubuntu user’s mailbox. In this guide, we’ll use the Maildir format, which separates messages into individual files that are then moved between directories based on user action. The alternative option that isn’t covered in this guide is the mbox format, which stores all messages within a single file.
home_mailbox variable to
Maildir/. Later, you will create a directory structure under that name within your user’s home directory. Configure
home_mailbox by typing:
sudo postconf -e 'home_mailbox= Maildir/'
Next, set the location of the
virtual_alias_maps table, which maps arbitrary email accounts to Linux system accounts. Run the following command, which maps the table location to a hash database file named
sudo postconf -e 'virtual_alias_maps= hash:/etc/postfix/virtual'
Now that you’ve defined the location of the virtual maps file in your
main.cf file, you can create the file itself and begin mapping email accounts to user accounts on your Linux system. Create the file with your preferred text editor; in this example, we’ll use
sudo nano /etc/postfix/virtual
List any addresses that you wish to accept email for, followed by a whitespace and the Linux user you’d like that mail delivered to.
For example, if you would like to accept email at
admin@<^>example.com<^> and would like to have those emails delivered to the sammy Linux user, you could set up your file like this:
[label /etc/postfix/virtual] contact@<^>example.com<^> sammy admin@<^>example.com<^> sammy
After you’ve mapped all of the addresses to the appropriate server accounts, save and close the file. If you used
nano, do this by pressing
CTRL + X,
Apply the mapping by typing:
sudo postmap /etc/postfix/virtual
Restart the Postfix process to be sure that all of your changes have been applied:
sudo systemctl restart postfix
Assuming you followed the prerequisite Initial Server Setup guide, you will have configured a firewall with UFW. This firewall will block external connections to services on your server by default unless those connections are explicitly allowed, so you’ll have to add a firewall rule to allow an exception for Postfix.
You can allow connections to the service by typing:
sudo ufw allow Postfix
With that, Postfix is configured and ready to accept external connections. However, you aren’t yet ready to test it out with a mail client. Before you can install a client and use it to interact with the mail being delivered to your server, you’ll need to make a few changes to your Ubuntu server’s setup.
In order to interact with the mail being delivered, this step will walk you through the process of installing the
s-nail package. This is a feature-rich variant of the BSD
xmail client which can handle the Maildir format correctly.
Before installing the client, though, it would be prudent to make sure your
s-nail will look for this variable to figure out where to find mail for your user.
To ensure that the
su -, or
sudo, for example — you’ll need to set the variable in the
/etc/bash.bashrc file and add it to a file within
/etc/profile.d to make sure it is set for all users by default.
To add the variable to these files, type:
echo 'export MAIL=~/Maildir' | sudo tee -a /etc/bash.bashrc | sudo tee -a /etc/profile.d/mail.sh
To read the variable into your current session, source the
With that complete, install the
s-nail email client with APT:
sudo apt install s-nail
Before running the client, there are a few settings you need to adjust. Open the
/etc/s-nail.rc file in your editor:
sudo nano /etc/s-nail.rc
At the bottom of the file, add the following options:
[label /etc/s-nail.rc] . . . set emptystart set folder=Maildir set record=+sent
Here’s what these lines do:
set emptystart: allows the client to open even with an empty inbox
set folder=Maildir: sets the
Maildirdirectory to the internal
set record=+sentcreates a
sentmbox file for storing sent mail within whichever directory is set as the
foldervariable, in this case
Save and close the file when you are finished. You’re now ready to initialize your system’s Maildir structure.
A quick way to create the Maildir structure within your home directory is to send yourself an email with the
s-nail command. Because the
sent file will only be available once the Maildir is created, you should disable writing to it for this initial email. Do this by passing the
Send the email by piping a string to the
s-nail command. Adjust the command to mark your Linux user as the recipient:
echo 'init' | s-nail -s 'init' -Snorecord <^>sammy<^>
<$>[note] Note: You may get the following response:
[secondary_label Output] Can't canonicalize "/home/<^>sammy<^>/Maildir"
This is normal and may only appear when sending this first message.
You can can check to make sure the directory was created by looking for your
ls -R ~/Maildir
You will see the directory structure has been created and that a new message file is in the
[secondary_label Output] /home/<^>sammy<^>/Maildir/: cur new tmp /home/<^>sammy<^>/Maildir/cur: /home/<^>sammy<^>/Maildir/new: 1650294586.Vfc01I7e11dM993645.mail.<^>example.com<^> /home/<^>sammy<^>/Maildir/tmp:
Now that the directory structure has been created, you’re ready to test out the
s-nail client by viewing the
init message you sent and sending a message to an external email address.
To open the client, run the
In your console, you’ll see a rudimentary inbox with the
init message waiting:
[secondary_label Output] s-nail version v14.9.15. Type `?' for help "/home/sammy/Maildir": 1 message 1 new >N 1 firstname.lastname@example.org 2022-04-18 15:09 14/452 init
ENTER to display the message:
[secondary_label Output] [-- Message 1 -- 14 lines, 452 bytes --]: Date: Mon, 18 Apr 2022 15:09:46 +0000 To: email@example.com Subject: init Message-Id: <20220418150946.EE6897E11A@@mail.example.com> From: firstname.lastname@example.org init
You can get back to the message list by typing
h, and then
[secondary_label Output] >R 1 email@example.com 2022-04-18 15:09 14/452 init
Notice that the message now has a state of
R, indicating that it’s been read.
Since this message isn’t very useful, you can delete it by pressing
d, and then
To get back to the terminal, type
q and then
As a final test, check whether
s-nail is able to correctly send email messages. To do this, you can pipe the contents of a text file into the
s-nail process, like you did with the
init message you sent in the previous step.
Begin by writing a test message in a text editor:
Inside, enter some text you’d like to send:
[label ~/test_message] Hello, This is a test. Please confirm receipt!
Save and close the file after writing your message.
Then, use the
cat command to pipe the message to the
s-nail process. You can do so with the following example, which uses these options:
-s: This defines the subject line of the email message
-r: An optional change to the “From:” field of the email. By default, the Linux user you are logged in as will be used to populate this field. The
-roption allows you to override this with a valid address, such as one of those you defined in the
/etc/postfix/virtualfile. To illustrate, the following command uses
Also, be sure to change
<^>user<^>@<^>email.com<^> to a valid email address which you have access to:
cat ~/<^>test_message<^> | s-nail -s '<^>Test email subject line<^>' -r <^>firstname.lastname@example.org<^> <^>user<^>@<^>email.com<^>
Then, navigate to the inbox for the email address to which you sent the message. You will see your message waiting there almost immediately.
<$>[note] Note: If the message isn’t in your inbox, it may have been delivered to your Spam folder. <$>
You can view your sent messages within your
s-nail client. Start the interactive client again:
From the email client, view your sent messages by typing:
You’ll see output like this:
[secondary_label Output] +[/home/sammy/Maildir/]sent: 1 message 1 new ▸N 1 To email@example.com 2022-04-18 15:12 10/211 Test email subject line
You can manage sent mail using the same commands you use for incoming mail.
You now have Postfix configured on your Ubuntu 22.04 server. Managing email servers can be a tough task for new system administrators, but with this configuration, you should have enough MTA email functionality to get yourself started.