Raspberry Pi Email Server Part 1: Postfix

Postfix Logo

This is the first part of a five part tutorial that will show you how to install a full featured email server on your Raspberry Pi. This tutorial covers Postfix, the Mail Transfer Agent.

The parts are:
The Introduction & Contents Page (read first)
Raspberry Pi Email Server Part 1: Postfix
Raspberry Pi Email Server Part 2: Dovecot
Raspberry Pi Email Server Part 3: Squirrelmail
Raspberry Pi Email Server Part 4: Spam Detection with Spamassassin
Raspberry Pi Email Server Part 5: Spam Sorting with LMTP & Sieve

Installing Postfix

Note: While you are setting up the mail server on the Pi, it’s a good idea to turn off port forwarding rules for email to the Pi in your router’s firewall. If you don’t have any port forwarding rules now, that’s great, don’t worry – I’ll prompt you to set them up later.

First, log into your Pi with a SSH session and install postfix:

sudo apt-get update
sudo apt-get install postfix

You will see a menu with some choices. Select “Internet Site” and then set the mail name to your domain name, not including www. (e.g. samhobbs.co.uk).

The setup script will then do some automatic configuration for you. The output will look something like this:

Selecting previously unselected package postfix.                                              
(Reading database ... 67653 files and directories currently installed.)                       
Unpacking postfix (from .../postfix_2.9.6-2_armhf.deb) ...                                    
Processing triggers for man-db ...
Setting up postfix (2.9.6-2) ...
Adding group `postfix' (GID XXX) ...
Adding system user `postfix' (UID XXX) ...
Adding new user `postfix' (UID XXX) with group `postfix' ...
Not creating home directory `/var/spool/postfix'.
Creating /etc/postfix/dynamicmaps.cf
Adding tcp map entry to /etc/postfix/dynamicmaps.cf
Adding sqlite map entry to /etc/postfix/dynamicmaps.cf
Adding group `postdrop' (GID XXX) ...
setting myhostname: samhobbs
setting alias maps
setting alias database
changing /etc/mailname to samhobbs.co.uk
setting myorigin
setting destinations: samhobbs.co.uk, samhobbs, localhost.localdomain, localhost
setting relayhost: 
setting mynetworks: [::ffff:]/104 [::1]/128
setting mailbox_size_limit: 0
setting recipient_delimiter: +
setting inet_interfaces: all
/etc/aliases does not exist, creating it.
WARNING: /etc/aliases exists, but does not have a root alias.

You can edit all of this later.

You may also get some warnings like this:

postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol

IPv6 is a new type of IP address that was introduced because we’re running out of the “old” IPv4 addresses. Not many ISPs support IPv6 yet, so you probably don’t need it. Unless you fix the warning, you’ll see it every time.

Change directory into the postfix configuration folder:

cd /etc/postfix/

Edit /etc/postfix/main.cf with your favourite command line text editor (e.g. sudo nano main.cf) and add inet_protocols = ipv4 to the end of the file.

Now is also a good time to check that your hostname is specified properly in /etc/postfix/main.cf. The setup script takes the hostname of the server and uses that, but it may not be in the right format, i.e. “samhobbs” instead of “samhobbs.co.uk”. Find the line that begins myhostname = and make sure it is your fully qualified domain name. This is important because your server will use this to talk to other mail servers, and some will reject your emails if you don’t use a fully qualified domain name to say hi! This is covered in more detail in the helo access restrictions later.

Restart postfix and you shouldn’t see the warnings any more:

sudo service postfix restart

Testing and Configuration

Before you start, it’s probably worth backing up the configuration files in their current state. This way, you’ll have something to compare to if you’re ever trying to work out which bits were defaults and which bits you changed yourself:

cd /etc/postfix
sudo cp main.cf main.cf.BAK
sudo cp master.cf master.cf.BAK

Mailbox Setup

There are a couple of different types of mailbox you can use, I’ve chosen to use a “Maildir” rather than “mbox” configuration. For users with “real” UNIX accounts on the system (like the one you’re using to log in), Maildir creates a folder in the user’s home directory and places emails inside it, one file for each email.

I prefer this to the alternatives, because it’s easier to see and understand: you can rummage around in your home folder and see all your emails as individual files.

To tell Postfix to use the Maildir format, add the following lines to /etc/postfix/main.cf:

home_mailbox = Maildir/
mailbox_command =

If there's already a line with mailbox_command, comment it out by adding a # at the start of the line.

We also need to create the mail directory and its subfolders for existing users, and add some things to /etc/skel (the template for new users) so that if you create a new account this will be done automatically.

These commands are part of Dovecot, so first we need to install it:

sudo apt-get update
sudo apt-get install dovecot-common dovecot-imapd

You will get a lot of output: some other dovecot packages will automatically be installed and the config files will be created. You will also see some errors – don’t worry about those for now, I’ll explain how to deal with them in part 2, later.

Now we can create those mail folders. Run the following commands to create the template files:

sudo maildirmake.dovecot /etc/skel/Maildir
sudo maildirmake.dovecot /etc/skel/Maildir/.Drafts
sudo maildirmake.dovecot /etc/skel/Maildir/.Sent
sudo maildirmake.dovecot /etc/skel/Maildir/.Spam
sudo maildirmake.dovecot /etc/skel/Maildir/.Trash
sudo maildirmake.dovecot /etc/skel/Maildir/.Templates

Next, copy the files over to existing users’ home directories, and change the ownership and permissions for privacy (replace USER with the username you are doing this for, and repeat for all existing usernames):

sudo cp -r /etc/skel/Maildir /home/USER/
sudo chown -R USER:USER /home/USER/Maildir
sudo chmod -R 700 /home/USER/Maildir

Initial Testing

Now, the best way to test Postfix during configuration is to use Telnet, because it is such a simple way of communicating between programs and there’s less to go wrong and get confused about.

First, install telnet:

sudo apt-get install telnet

Now, still inside the SSH session to your pi, type this command. It will connect you to port 25 on the Pi:

telnet localhost 25

You can now test sending an email using SMTP. Here are the steps:

  1. send an ehlo command to tell the server who you are, and it will tell you its capabilities
  2. use the mail from command to say who the email is from. If you are sending it from an address that exists on the server, you needn’t include the domain name (i.e. user instead of user@yourdomain.com)
  3. use the rcpt to command to tell the server where to send the email
  4. Use the data command to tell the server that you’re about to start giving it the message you want to send
  5. Type Subject: YOUR SUBJECT then enter to set a subject
  6. Type the body of your email. Once you’re done, press ENTER, then ., then ENTER again.
  7. Type quit to exit

Here’s an example:

telnet localhost 25
Connected to localhost.
Escape character is '^]'.
220 samhobbs.co.uk ESMTP Postfix (Debian/GNU)
ehlo foobar
250-SIZE 10240000
250 DSN
mail from: me        
250 2.1.0 Ok
rcpt to: me@outsideemail.com
250 2.1.5 Ok
354 End data with <CR><LF>.<CR><LF>
Subject: test
This is a test email
250 2.0.0 Ok: queued as A639C3EE6D
221 2.0.0 Bye

Some Access Restrictions

Add the following to /etc/postfix/main.cf to restrict who can send emails to external mail servers:

smtpd_recipient_restrictions =

Reload postfix:

sudo service postfix reload
  • Line 1 begins the list of restrictions.
  • Line 2 permits users who have authenticated with Simple Authentication and Security Layer (SASL) to send email to any destination (this is part of the Dovecot config in Part 2, later).
  • Line 3 will let users send emails to any destination if they have connected from an IP address defined in mynetworks.
  • Line 4 will reject the email if none of the above conditions have been met unless the “rcpt to” address is one of the addresses that your server is accepting email to (as defined in main.cf with the mydestination parameter).

In its present state, the email server will allow you to send external emails because the connection is originating from the Pi itself (you are logged in via SSH) and not an unknown computer. Addresses of “trusted” computers are listed under the mynetworks setting in main.cf, e.g.

mynetworks = [::ffff:]/104 [::1]/128

Try sending an external email again, using telnet as before. You should be able to do so without any issues.

Now we want to see what kind of response someone would get if they were connecting from outside of the IP range defined in mynetworks, to make sure Pi won’t allow everyone to send outgoing emails from your server. To simulate this we can comment out permit_mynetworks under smtpd_recipient_restrictions:

smtpd_recipient_restrictions =
#       permit_mynetworks,

Now reload the postfix configuration:

sudo service postfix reload

This will let you see what kind of response you would get if you weren’t sending the email from mynetworks. Try sending again, and you should receive an error “554: Relay access denied“:

admin@samhobbs /etc/postfix $ telnet localhost 25
Connected to localhost.
Escape character is '^]'.
220 samhobbs.co.uk ESMTP Postfix (Debian/GNU)
ehlo samhobbs.co.uk
250-SIZE 10240000
250 DSN
mail from: USER
250 2.1.0 Ok
rcpt to: me@externalemail.com
554 5.7.1 <me@externalemail.com>: Relay access denied
221 2.0.0 Bye
Connection closed by foreign host.

Perfect. Leave permit_mynetworks commented out in your smtpd_recipient_restrictions (you'll see why in part 2).

Helo access restrictions

Helo access restrictions can be a very useful way of blocking spam.

Note that we’re not talking about unauthorised people being able to send email outside your network any more (that’s taken care of with the smtpd_recipient_restrictions); we’re now talking about stopping spammers from sending incoming mail to your email address.

Spammers try to conceal their identity so that they don’t end up on block lists, so they rarely use helo hostnames that could identify them – these hostnames are written to the mail log files. As a result, they often make up a random string or use an IP address instead of a domain name.

Luckily, these are easily taken care of.

Add the following to /etc/postfix/main.cf:

smtpd_helo_required = yes
smtpd_helo_restrictions =
  • Line 1 requires people and programs to identify themselves when they send email, using the helo or ehlo commands I mentioned earlier.
  • Line 2 starts the list of restrictions.
  • Line 3 accepts any old rubbish in the ehlo if it comes from an IP address defined in mynetworks. If the connection isn’t connecting from an IP address in mynetworks, then the helo hostname is checked against the rest of the list.
  • Line 4 accepts any helo hostname if the client is authenticated with SASL (I added this to the tutorial recently after troubleshooting problems some people had in the comments – it allows you to connect from any network and still send messages through your Pi. Mobiles will usually work without this because most providers pass mail through their own proxies, so your Pi receives a connection from the proxy – which has a valid hostname – and not from the mobile, which may be called something like “android-b627cfe2efea7e67″).
  • Line 5 rejects connection attempts when the HELO hostname syntax is invalid.
  • Line 6 rejects non-fully qualified domain names (for example, foobar instead of foobar.com). This will also block those random strings, e.g. “kjhrsbvks”.
  • Line 7 rejects the helo hostname if it that domain doesn’t have a valid DNS A or MX record. For example, someone spamming you could make up a domain like theflyingspaghettimonster.com. If that domain doesn’t actually exist and have the right records, then your server won’t accept it as a hostname, and the email will be rejected.

If the helo hostname gets past line 7 and hasn’t been denied, it is accepted. You’d be surprised how much spam these helo access restrictions will block on their own (looking through my log files, I can see numerous spam scripts that have attempted to ehlo with my IP address), but there’s an extra step we can add in here to help:

Blocking people claiming to be your domain name

Many spammers try to send email to you after helo’ing with your own domain name. Since postfix doesn’t check whether or not they’re lying about their helo hostname, this will usually work.

But, since we’ve put permit_mynetworks at the top of the list, anyone actually sending an email from your domain will be accepted already. Anyone using your hostname who isn’t in mynetworks is an imposter.

So, add one more line to the end of the restrictions list:

smtpd_helo_restrictions =
        check_helo_access hash:/etc/postfix/helo_access

That last line checks a file for custom rules you’ve built in. Create the file:

sudo nano /etc/postfix/helo_access

Add the following lines, edited for your domain:

samhobbs.co.uk          REJECT          Get lost - you're lying about who you are
mail.samhobbs.co.uk      REJECT          Get lost - you're lying about who you are

Now tell postfix to map the file, and restart postfix:

sudo postmap /etc/postfix/helo_access
sudo service postfix restart

Now anyone who tries to ehlo with one of the hostnames you defined in that file gets rejected, and sees the “get lost” message. Your legitimate servers won’t have that problem, because they will already have been accepted higher up the list.

Neat, right? I found that little nugget of wisdom at unixwiz.net.

Moving on…

We’re almost done with Postfix now, athough there are a few bits of configuration that we’ll want to do once we’ve set up SASL with Dovecot, which I’ve chosen to lump in with the Dovecot tutorial.

In Raspberry Pi Email Server Part 2: Dovecot, we’ll set up Dovecot to provide SASL authentication and IMAP capability.

Please leave a comment if you’re having trouble with anything in this tutorial, and I’ll try and help you out!



No worries.

I think there's a little misunderstanding here: postfix isn't an email client like Thunderbird, it's a Mail Transfer Agent, the program that your raspberry pi email server will use to talk to other email servers. You don't interact directly with Postfix, you use a program like Thunderbird to talk to it.

Postfix has no graphical user interface (GUI), it's a process that operates behind the scenes.

That configuration wizard changes a few things, but apart from that it basically just creates a bunch of default configuration files... we are using a text editor to make additional changes to those configuration files (which are text files) in /etc/postfix to set up Postfix the way we want it.


Hi Sam, just goes to show you how much I know ??, so what you are saying Postfix is like my current ISP ?? is that correct , so I with my Pi I will be cutting out the middle man so to speak, and talking about that could I actually Host my own Web Sites if I wanted to, but for now lets not try running before we can walk.
So back to my next step which is "Dovecot" and lets see how we get on with this one, and again Thanks for all your help, Regards Eddie

Kind of, yes. Your current ISP maintains an email server with a Mail Transfer Agent that you can connect to to send emails (they may even be using Postfix!) so your Pi will be doing the same thing.

However, some (not all) ISPs block port 25 because spammers often infect computers with malware without the owners knowing and use them to spam people. So, the ISP will only allow you to send outgoing email through their own server so that they can keep an eye on everything and spot suspicious activity.

When this happens you have to set up Postfix to send emails to your ISP's email server, which will send them on to their destination, instead of having your Pi connect directly to the destination email server.

Basically, you may or may not be able to cut out the middle man, it depends! :)

As for hosting your own website, check out this tutorial for installing WordPress on a raspberry Pi. I think that is actually easier than setting up an email server.


Hi Sam, latest problem,
sudo cp -r /etc/skel/Maildir /home/USER/
sudo chown -R USER:USER /home/USER/Maildir
sudo chmod -R 700 /home/USER/Maildir

I entered here instead of "User" my ferrarispares.co.uk and I get "invalid user" ??? so again any help much appreciated, Regards Eddie

Hi Sam, Thanks again, my latest problem when typing in "permit_mynetworks," I typed in a 1 (one) instead of a lower case l (L) so how do I edit this with out redoing the lot, again your help much appreciated, Regards Eddie

Use your arrow keys to move around the file in nano, and press backspace to delete the text you don't want and type your new text instead.

There's no lower case L in that permit_mynetworks statement though, so I'm not quite sure what you mean!

HI Sam, this was the line "permit_sasl_authenticated," and how do I get it into "nano /path/to/filename" what is the file name, I tried telnet but did not load, so again Thanks, Regards Eddie

The tutorial gives you the filename in the sentence just above that step, it's /etc/postfix/main.cf.

So to open the file with nano, the text editor, you would do sudo nano /etc/postfix/main.cf.

To be honest I think you might struggle with setting up an email server just yet, it's not easy!

My advice would be to browse through the RasPi forums and find some beginner projects to start with, save this for when you're a little more comfortable with the command line and manually configuring packages.


Hi Sam, Thanks again well I thought I had found a nice little simple project to get me started, but as you say what I thought was simple is quite difficult for a beginner ?? but is hard to judge when you do not know till you get started, so can you point me in the direction of something more suitable for a beginner as I have tried and could not find any till I came across yours, again Thanks for all your help, Regards Eddie

Sorry for the late reply! I would recommend this website to get you familiar with the command line, it will be useful for all sorts of projects. I found it really helpful:


Don't give up!


Hi Sam,

great tutorial. Finally I got my own Mail-Server. Unfortunately my outgoing mails are blocked by most Email-Providers like gmx, gmail etc. since I have a dynamic IP. How can I use GMail as a relay in this configuration only for outgoing mails? I read some tutorials where I had to make a postmap sasl_passwd but it did not work.

Best regards


Hi Christian

Was it this tutorial [clearfoundation.com]?

It's possible that you had problems last time if you didn't postmap the file or reload postfix after you made your changes.

If you could try that, and if it doesn't work look in your /var/log/mail.log and tell me what you see, that should point us in the right direction!


Hi Sam,

indeed! I should have viewed the log mail.log before. Fixing my smtp relay Settings everything is fine now!


Thanks for all the info.
I am stuck on one part.
I setup the pi using raspbian minimal and all so far so good.
I am using root and this is where I am stuck.
Because I am using root I did not need to put in sudo.

cp -r /etc/skel/Maildir /home/USER/
chown -R USER:USER /home/USER/Maildir
chmod -R 700 /home/USER/Maildir

In the second line above I have no idea how to fix the USER:USER
I have added a new user to the raspbian but still stuck
Any ideas please?

Thanks - got it sorted eventually, it took a nights sleep !

Hey Sam.

Thanks for pushing this tutorial online. I´ve been planning to "take my email back" for a long time and I´m almost there.

I can receive emails (using Apple Mail) but not send. Here is the output from '$ sudo tail -f /var/log/mail.log'. I´m stripping out my username with "myusername".

Jul 25 15:45:15 rostur postfix/smtps/smtpd[3361]: warning: hostname dsldevice.lan does not resolve to address
Jul 25 15:45:15 rostur postfix/smtps/smtpd[3361]: connect from unknown[]
Jul 25 15:45:18 rostur postfix/smtps/smtpd[3361]: 0AA383F1B8: client=unknown[], sasl_method=PLAIN, sasl_username=myusername
Jul 25 15:45:18 rostur postfix/cleanup[3368]: 0AA383F1B8: message-id=<52EB7B4D-E084-48AC-A0F6-4FDCA985B9DF@rostur.org>
Jul 25 15:45:18 rostur postfix/qmgr[3351]: 0AA383F1B8: from=<"myusername"@rostur.org>, size=537, nrcpt=1 (queue active)
Jul 25 15:45:48 rostur postfix/smtp[3369]: connect to gmail-smtp-in.l.google.com[]:25: Connection timed out

Thanks for your help!


Hi! Can you tell me who your ISP is? It's possible that they are blocking traffic on port 25 - that would explain why your pi can't connect to the gmail SMTP server.

Also, can you try sending yourself an email from an external email address like gmail to see if it gets through? It's good that you can receive email sent locally but this should test whether there's a clear route in to your Pi.


Hi Sam, thanks for giving me a hand.

My ISP is www.siminn.is (I can telnet into their mailserver on port 25)

I CAN receive emails sent from external email address and according to my ISP port 25 is not blocked.

Another weird thing is that when I tried to send an email to my university email it did NOT timeout and my IP got blacklisted.

What are your thoughts on the first line in the log?
Jul 25 15:45:15 rostur postfix/smtps/smtpd[3361]: warning: hostname dsldevice.lan does not resolve to address

That message in the logs is because the Pi is doing DNS lookups on the IP address it receives a connection from (IP address to hostname and vice versa) to make sure it matches both ways. It's just a warning, not an error - I think it's possible to configure mail servers to reject connections unless the lookup checks out - you block more spam that way, but also block a significant amount of ham.

dsldevice.lan is your router, and apparently if you typed that hostname into a web browser it wouldn't connect you to the router because the router isn't set up to resolve that domain to its own IP address.

I don't have a similar warning in my logs because my OpenWrt router resolves openwrt.lan to The Pi is doing the check on your router because that's where it is receiving the connection from when you connect from your LAN.

Do you have the log entry covering your attempt to email the uni? Anything interesting in there? Did the email get through?


Hey Sam.

Thanks for a thorough explanation.

Here is the tail during the transfer of the mail to the Uni.

Jul 26 14:46:09 rostur postfix/smtps/smtpd[6257]: warning: hostname dsldevice.lan does not resolve to address
Jul 26 14:46:09 rostur postfix/smtps/smtpd[6257]: connect from unknown[]
Jul 26 14:46:10 rostur postfix/smtps/smtpd[6257]: 010A43F1A5: client=unknown[], sasl_method=PLAIN, sasl_username=levy
Jul 26 14:46:10 rostur postfix/cleanup[6260]: 010A43F1A5: message-id=<9F127A63-4696-44DC-8ED1-A1B0648427C4@rostur.org>
Jul 26 14:46:10 rostur postfix/qmgr[5954]: 010A43F1A5: from=, size=525, nrcpt=1 (queue active)
Jul 26 14:46:10 rostur postfix/smtp[6253]: 010A43F1A5: to=, relay=menja.rhi.hi.is[]:25, delay=0.3, delays=0.15/0.01/0.12/0.02, dsn=5.3.0, status=bounced (host menja.rhi.hi.is[] said: 553 5.3.0 Your IP is blacklisted (in reply to MAIL FROM command))
Jul 26 14:46:10 rostur postfix/cleanup[6260]: 499033F1CF: message-id=<20140726144610.499033F1CF@rostur.org>
Jul 26 14:46:10 rostur postfix/qmgr[5954]: 499033F1CF: from=<>, size=2328, nrcpt=1 (queue active)
Jul 26 14:46:10 rostur postfix/bounce[6261]: 010A43F1A5: sender non-delivery notification: 499033F1CF
Jul 26 14:46:10 rostur postfix/qmgr[5954]: 010A43F1A5: removed
Jul 26 14:46:10 rostur postfix/local[6262]: 499033F1CF: to=, relay=local, delay=0.1, delays=0.02/0.06/0/0.01, dsn=2.0.0, status=sent (delivered to maildir)
Jul 26 14:46:10 rostur postfix/qmgr[5954]: 499033F1CF: removed

It appears you are trying to relay email through your university's SMTP server - is that really what you're trying to do?

Your IP address was probably blacklisted already if you have a dynamic IP address, some mail servers blacklist whole ranges of dynamic IP addresses because most email coming from them is spam.


No relaying should be happening on my part. I followed the tutorial on a clean Pi. Not sure what´s going on.

Let me send you an email and see what happens.

Here is the tail

Jul 26 17:48:41 rostur postfix/smtps/smtpd[6393]: warning: hostname dsldevice.lan does not resolve to address
Jul 26 17:48:41 rostur postfix/smtps/smtpd[6393]: connect from unknown[]
Jul 26 17:48:43 rostur postfix/smtps/smtpd[6393]: 472223F228: client=unknown[], sasl_method=PLAIN, sasl_username=levy
Jul 26 17:48:43 rostur postfix/cleanup[6399]: 472223F228: message-id=
Jul 26 17:48:43 rostur postfix/qmgr[5954]: 472223F228: from=, size=600, nrcpt=1 (queue active)
Jul 26 17:49:13 rostur postfix/smtp[6391]: connect to samhobbs.co.uk[]:25: Connection timed out
Jul 26 17:49:13 rostur postfix/smtp[6391]: 472223F228: to=, relay=none, delay=31, delays=0.13/0.01/30/0, dsn=4.4.1, status=deferred (connect to samhobbs.co.uk[]:25: Connection timed out)
Jul 26 17:49:43 rostur postfix/smtps/smtpd[6393]: disconnect from unknown[]

Interesting. Try telnetting to me from your Pi, i.e.

telnet samhobbs.co.uk 25

Just to see if you can connect. Might be worth trying from your Mac too. Also, is your router an Apple device?


Just tried to telnet to your server but can´t establish a connection (Trying a.b.c.d.), neither from the Pi or my Mac. My router is a Technicolor TG589vn V1.

But, I can telnet to the Uni server (menja.rhi.hi.is) and the Siminn server (postur.simnet.is), through port 25.

Could the reason be that the Uni is part of the Siminn subnet and therefore I can connect?

That's just so strange, I don't get it!

Try my IP address directly just in case it's a DNS thing:

telnet 25



Add new comment