A previous version of this tutorial was written by Justin Ellingwood
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 20.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:
sudo
privileges and a firewall configured with UFW. You can follow our Ubuntu 20.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 example.com
or 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:
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:
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 user1@example.com
.root@
and postmaster@
. Use your primary account for this. In this example case, sammy.0
disables any size restriction.+
will work for this tutorial.To be explicit, these are the settings used in this guide:
example.com
(not mail.example.com
)$myhostname, example.com, mail.example.com, localhost.example.com, localhost
127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128
0
+
Note: If you need to ever return to change these settings, you can do so by typing:
The prompts will be pre-populated with your previous responses.
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.
Set the 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:
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 /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 nano
:
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 contact@example.com
and admin@example.com
and would like to have those emails delivered to the sammy Linux user, you could set up your file like this:
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
, Y
, then ENTER
.
Apply the mapping by typing:
Restart the Postfix process to be sure that all of your changes have been applied:
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:
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 MAIL
environment variable is set correctly. s-nail
will look for this variable to figure out where to find mail for your user.
To ensure that the MAIL
variable is set regardless of how you access your account — whether through ssh
, su
, 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:
To read the variable into your current session, source the /etc/profile.d/mail.sh
file:
With that complete, install the s-nail
email client with APT:
Before running the client, there are a few settings you need to adjust. Open the /etc/s-nail.rc
file in your editor:
At the bottom of the file, add the following options:
. . .
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 inboxset folder=Maildir
: sets the Maildir
directory to the internal folder
variableset record=+sent
creates a sent
mbox file for storing sent mail within whichever directory is set as the folder
variable, in this case Maildir
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 -Snorecord
option.
Send the email by piping a string to the s-nail
command. Adjust the command to mark your Linux user as the recipient:
Note: You may get the following response:
OutputCan'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 ~/Maildir
directory:
You will see the directory structure has been created and that a new message file is in the ~/Maildir/new
directory:
Output/home/sammy/Maildir/:
cur new tmp
/home/sammy/Maildir/cur:
/home/sammy/Maildir/new:
1463177269.Vfd01I40e4dM691221.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 s-nail
command:
In your console, you’ll see a rudimentary inbox with the init
message waiting:
Outputs-nail version v14.9.15. Type `?' for help
"/home/sammy/Maildir": 1 message 1 new
>N 1 sammy@example.com 2020-05-19 15:40 14/392 init
Press ENTER
to display the message:
Output[-- Message 1 -- 14 lines, 369 bytes --]:
From sammy@example.com Tue May 19 15:40:48 2020
Date: Tue, 19 May 2020 15:40:48 +0000
To: sammy@example.com
Subject: init
Message-Id: <20160513220749.A278F228D9@mail.example.com>
From: sammy@example.com
init
You can get back to the message list by typing h
, and then ENTER
:
Output>R 1 sammy@example.com 2020-05-19 15:40 14/392 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 ENTER
:
To get back to the terminal, type q
and then ENTER
:
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:
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 -r
option allows you to override this with a valid address, such as one of those you defined in the /etc/postfix/virtual
file. To illustrate, the following command uses contact@example.com
Also, be sure to change user@email.com
to a valid email address which you have access to:
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: 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:
Output+[/home/sammy/Maildir/]sent: 1 message 1 new
▸N 1 contact@example.com 2020-05-19 15:47 12/297 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 20.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.
Thanks for learning with the DigitalOcean Community. Check out our offerings for compute, storage, networking, and managed databases.
This textbox defaults to using Markdown to format your answer.
You can type !ref in this text area to quickly search our full set of tutorials, documentation & marketplace offerings and insert the link!
Great article for getting started! What kind of steps mail admins would usually take beyond this article? As a developer who wonders whether to invest time to setup my own mail server or go with a third-party solution, I would love to have some grasp on how deep the rabbit hole goes. Some overall view of possible steps to take next would be very helpful. For example, maybe setting up an auto-response would be one of the possible steps?
As many have angrily noted in the comment section of the older 18.04 article, I too failed to send email to my default Gmail address after following this tutorial. Here is an excerpt from my
/var/log/mail.log
, domains and email addresses replaced.The error “Our system has detected an unusual rate of unsolicited mail originating from your IP address” is rather weird because this is the first mail ever sent from my Droplet. Maybe the IP has been previously been a source of spam but I think insufficient configuration is the most probable cause. No one in the older article seemed to be able to provide a sounding fix to this issue. I hope DO can.
Here is my experience:
DigitalOcean doesn’t monitor their inventory of IP addresses for having been added to black lists, even though they should have the responsibility to clean those up after they’ve terminated the spammer’s account.
You can either rebuild the droplet with a new IP and reset your DNS, or try to get that IP removed from any block lists yourself.
It’s easier to just get a new IP, as people get ignored by block list owners when they try to fix the block.
It’s nice to have a tutorial for half of a mail server, but now a tutorial on dovecot is needed, other tutorials I have tried for 20.04 don’t work.
I agree with you that a tutorial is needed for dovecot. Half a tutorial is no tutorial at all.
stuck at step 3 when I type echo ‘init’ | s-nail -s ‘init’ -Snorecord relaxslow and enter it shows nothing and next I type ls -R ~/Maildir it gives error msg ls: cannot access ‘/home/relaxslow/Maildir’: No such file or directory
can you please tell me the reason
I had the same issue. The Maildir wasn’t being created under my home directory. Even when I created the directory structure manually, it did not work correctly as mail was never received. I then looked at the syslog (cat /var/log/syslog) and saw that postfix had a configuration error. In my case I had set the mailbox size to 10GB in bytes like so 10000000000, and postfix did not like that number (fatal: bad numerical configuration: mailbox_size_limit). For now, I set it to “0” (unlimited) under the main.cf, restarted postfix, and sent the message again. It worked! Hope this helps someone.
I’ve done up to this stage: $echo ‘init’ | s-nail -s ‘init’ -Snorecord sammy
But I get the following: ls: cannot access ‘/home/sammy/Maildir’: No such file or directory
Please note that when I created a new user I literally used the same name “Sammy” (as in the tutorial)
Getting s-nail working
Like a lot of other posters, I think the tutorial needs to be amended. This tutorial doesn’t create the Maildir or its subfolders or files or whatever is supposed to be there and other tutorials are similarly unclear.
For me, I ended up finding this post: https://support.nagios.com/forum/viewtopic.php?f=7&t=50454
and modified the instructions from ssax to the following:
Where USERNAME is replaced with the user you want on the system and in the main tutorial for this page is referred to as ‘sammy’
I did create, still I dont see any under the folders. May be because of the “connection timeout” error I’m getting and it never goes past Queue to Sent box.
As others mentioned, cant get test mails to work and nothing appears. Also it was noted that SMTP could be disabled for new accounts.
Step I’m stuck at: ls -R ~/Maildir
mailq shows this connection timed-out error:
-Queue ID- --Size-- ----Arrival Time---- -Sender/Recipient------- 811D513BD4C 373 Mon Jan 4 17:04:12 root@xxx.com (connect to alt2.gmail-smtp-in.l.google.com[74.125.137.26]:25: Connection timed out)
I have opened a ticket asking to enable SMTP, but waiting for more than 2 days without action. Do others know how much time normally these take for these kind of requests ?
Same here…
So it seems that VPS providers block smtp by default? I just spent all evening trying to get postfix to send, before seeing a comment here that made me contact Interserver… steaming right now, they should be required to tell you…
I am on Ubuntu 20.01.1, just booted up a new droplet this morning. Followed the instructions up until this command:
echo ‘init’ | s-nail -s ‘init’ -Snorecord USERNAME
It does not create the Maildir structure. After creating the Maildir structure manually, as other have suggested, I am still unable to send mail to myself. It appears in the “sent” directory but does not show up in the “new” mail. Strangely, I can send mail to an external email address, but I still cannot send mail internally to my own user.
As others have noted in the comments the mail is not being delivered properly locally and the Maildir is never created. This is because an important step is missing in the configuration of Postfix in Step 1. There is a possibly new configuration option in the setup which asks “Use procmail for local delivery?”. This should be changed from the default value of “Yes” to “No”. If procmail is used for local delivery the mail will be routed to /var/mail instead of the specified Maildir directory.
Hi, thanks kindly for helpful tutorial, just one line here not clear if I made mistake, tutorial says: Other destinations to accept mail for:
I deleted ‘myhostname’, and filled the rest according to mydomainname.com.
At moment, Hotmail rejects my emails from server completely (gmail and yahoo OK), and host shown here is the name of my Digital Ocean droplet. Is this correct for the host name? Should host name be the domain name, or ‘digitalocean’…? Hotmail ‘Undelivered Mail’ email reads “…This is the mail system at host dropletnameNew…” where dropletnameNew is the name of my droplet. By the way, I am using mail-tester.com to check free for spam rating of email, this seems very useful site for this.
The $myhostname variable is whatever you set ‘myhostname’ equal to in the main.cf file. If it isn’t defined in main.cf, its value defaults to the name in /etc/hostname. It is OK to not use this variable in your ‘mydestination’ config. This configures domains for which your server will attempt to accept mail.
The the part of this configuration that will make sending emails fail, is where Postfix announces itself to another MTA. When sending the EHLO command Postfix uses the value in ‘myorigin’ to announce your MTA.
Some services will reject mail from your server if your DNS PTR record is not set to the IP address of your server. Digital Ocean creates PTR records for all droplets. You’ll need to set your droplet name to the same domain name that Postfix uses for ‘myorigin’. This will ensure reverse DNS lookups will point to your droplet’s IP address.
The next thing is adding an SPF DNS record, and adding DKIM to your server and DNS records. Adding a DMARC DNS record is also recommended. These three things keep your emails from going to SPAM.
SPF tells a receiving MTA that your sending MTA is allowed to send email for your domain, using your droplet’s IP address.
DKIM is a cryptographic signing mechanism. This tells a receiving MTA that the sender is they say they are.
DMARC is tells a receiving MTA what do to with an email that doesn’t pass checks, and gives a way for MTA’s receiving mail from your server to report back to you.
It’s easy to get Postfix set up, but it’s another story to get your emails accepted by other email services.
This is not working. Not creating Maildir directory.
Same here, it is not creating the Maildir.
Maildir is never created in step 3 and no errors are shown.
I’m installing Postfix on Ubuntu 21.04 and have been having this problem: “Errors were encountered while processing: postfix needrestart is being skipped since dpkg has failed”
The problem was the system hostname was automatically set from the name of my Droplet when it was created. This was breaking Postfix on install as it isn’t in the form of a proper domain name.
Fixed it by first uninstalling and purging Postfix, then changing hostname with: sudo hostnamectl set-hostname yourdomainname.com
(I don’t have a domain name for this server yet so am supplying any name eg. “anything.com” will work for the install)
NOTE: This caused no problems at all on my Ubuntu 20.04 server…
My final result after finishing this tutorial was a message in s-nail saying: “Undelivered Mail Returned to Sender”
it’s not creating Maildir directory.
This comment has been deleted
Hello, If the MailDir mailbox has not been created, try to leave a space at the end before “/”
Same issue
echo 'init' | s-nail -s 'init' -Snorecord sammy
doesn’t create Maildir structureI’ve to create it manually:
mkdir -p ~/Maildir/{cur,new,tmp}
Like a lot of people, I was having issues getting this to work. Maildir/ was not being created, running
$s_nail
was outputtinguser@ip-xx-xx-xx-xx:/$ s-nail s-nail: /home/user/Maildir: Is a directory
I eventually got this to work, by not using
sudo
to restart postfix, instead I usedsystemctl restart Postfix
and authenticated with my user password. This then started postfix under the correct user, which then allowed it to read the config file and initiate the maildir/ under the correct user.I also agree with mattkeaveney in that procmail should be disabled in the initial set up of postfix.
tnX for guide but i get this error
E: Package ‘postfix’ has no installation candidate
i did sudo apt update still same error what now?
1)
It didn’t work for me (postfix 550 5.1.1 “User doesn’t exist”). So I removed this step and remove it in /var/postfix/main.cf
2)
It didn’t work either, so I create the folded by hand:
and I checked the permissions and it worked.
Also
3) While I opened the firewall but I also opened the firewall of my virtual machine (IP port 25)
4) I added the next entries to the DNS:
changing the IP and the domain for the right values.
This comment has been deleted