Raspberry Pi Email Server

Powered by Drupal

raspberry-pi-email-server.png

The RasPi’s small size and low power consumption make it an ideal choice for use as a home email server. After trying a couple of different pieces of software, I finally found an excellent combination: Postfix with Dovecot and Squirrelmail, plus Spamasssassin and Sieve for spam filtering. There are many, many tutorials out there for the first trilogy of programs, but since the configuration is slightly different for each distribution I kept coming unstuck when setting mine up on the Pi. Having finally got mine configured properly, I’ve put together a set of 5 tutorials, which will take you from a vanilla Raspbian image to a fully functioning email server in no time. When writing the tutorial I made an effort to explain what each setting does instead of just dumping commands. With a bit of luck at the end of the process you’ll not only have a working server, you’ll understand how it works… without having to wade through reams of documentation like I did! If you follow the tutorials from start to finish, here’s what you’ll end up with:

  1. An email server that you can run 24/7/365 for under £5 of electricity per year
  2. Personalised email address like you@yourdomain.com (requires you to have registered a domain name with a registrar like namecheap.com - see my DNS basics tutorial)
  3. The ability to connect from anywhere, and read & send email, using a secure IMAP connection on your phone, tablet or computer
  4. Log in to webmail using any web browser on a secure HTTPS connection, read & send email
  5. Complete control over your personal communication. Your emails are stored on YOUR server, and nobody is scanning them to sell you adverts.
  6. Smart spam filtering with Spamassassin
  7. Customisable mail sorting with Sieve rules

Postfix, the Mail Transfer Agent

Postfix Logo

Postfix is the program that lets you send and receive email using Simple Mail Transfer Protocol (SMTP). Whilst you, the user, may connect to your email server using IMAP (on port 143 or 993), or POP (on port 110 or 995), email servers talk to each other using SMTP on port 25. So, this is the basic core of the server. Without it, you wouldn’t be able to send or receive any emails! I’ve covered the setup here: Raspberry Pi Email Server Part 1: Postfix

Dovecot, the POP/IMAP Server

dovecotLogo-300x130_0.png

Dovecot is used for two things:

  1. It provides you with IMAP functionality
  2. It checks that you are who you say you are using Simple Authentication and Security Layer (SASL) before you send or fetch mail

If you’re not interested in connecting with IMAP on your devices, you still need Dovecot. Not only is it doing SASL for you, but Squirrelmail connects using IMAP in order to provide you with webmail. I’ve covered Dovecot installation and configuration here: Raspberry Pi Email Server Part 2: Dovecot

Squirrelmail, for Webmail

Squirrelmail Logo

Squirrelmail is handy because it allows you to check your email in any browser, from anywhere. Of the first three, it’s probably the easiest to configure. I’ve covered it here: Raspberry Pi Email Server Part 3: Squirrelmail

Spamassassin, for Marking Spam

Spamassassin Logo

Spamassassin is the program that we will use to audit incoming mail and decide whether or not it’s spam. Spamassassin doesn’t actually sort the mail into the spam folder, it only changes information in the headers based on the results of the scan. I’ve covered it here: Raspberry Pi Email Server Part 4: Spam Detection with Spamassassin.

LMTP & Sieve for Spam Sorting & Mailbox Organisation

After Spamassassin has checked incoming mail to see if it’s spam or not, we need another program to sort it into the right mail folder. This final step will be done with Dovecot’s Local Mail Transfer Protocol (LMTP) daemon and a Sieve plugin. Sieve is a simple programming language that allows users to define what to do with incoming email based on a predefined set of rules – think “if the header contains this flag, put it in the spam folder” kind of thing and you’ll get the gist. Aside from spam filtering, Sieve can be used to automatically sort & de-clutter your inbox. These steps are covered in the final tutorial: Raspberry Pi Email Server Part 5: Spam Sorting with LMTP & Sieve Enjoy! I’d love to hear how you get on, so leave a comment below :)

Comments

OK. Assuming all of the Pi are on your LAN, this should be quite easy (because it won't require authentication).
  1. Install Postfix and Mutt on each satellite Pi
  2. On each satellite pi, add relayhost = yourdomain.com to /etc/postfix/main.cf
  3. On your mail server Pi, change mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 to mynetworks = 127.0.0.0/8 192.168.1.0/24 [::ffff:127.0.0.0]/104 [::1]/128 to include your whole LAN (assuming your router's IP address is 192.168.1.1)
  4. On the mail server Pi, make sure the permit_mynetworks lines are uncommented at the start of each restriction list
  5. Reload postfix (all Pi)
  6. Send test email with Mutt
If you have Pi in other places (not on your LAN) then this could get trickier because we'll need to provide a way for the satellite Pi to authenticate before relaying email. Sam

Four or my pi's are 100 miles away on a different IP. I'm using tls on, tls_trust_file /usr/share/ca-certificates/mozilla/Equifax_Secure_CA.crt when I send through ssmtp through gmail.

I've also installed fail2ban on all pi's - per your tutorials.

An important practice is to change ssh port from 22 on any computer using ssh. Fail2ban protected me from thousand of attempts by the Chinese on this one - then I changed my ssh port number. The passwords on all pi's are very strong.

Lol, of course they are - anything else would be easy ;) New instructions below... (edited! I realised my first set required postfix version >3.0 for smtp_tls_wrappermode, so the port in relayhost has changed (to 25) and the wrappermode line has disappeared)
  1. Install Postfix and Mutt on each satellite Pi
  2. On each satellite pi, add the following parameters to /etc/postfix/main.cf:
    • relayhost = yourdomain.com:25 (to tell your pi to send all email via your mail server)
    • smtp_sasl_auth_enable = yes (to enable authentication)
    • smtp_sasl_password_maps = hash:/etc/postfix/saslpasswd (to provide the pi with a username and password for authentication)
    • smtp_tls_security_level = encrypt (to require postfix to upgrade to an encrypted connection via STARTTLS - this is particularly important because port 25 only offers authentication after encryption)
  3. On the satellite pi, create the file /etc/postfix/saslpasswd and add the line: yourdomain.com username:password
  4. Hash the password file on the satellite Pi: sudo postmap /etc/postfix/saslpasswd
  5. Reload postfix (all satellite Pi)
  6. Send test email with Mutt
P.S. For SSH, publickey authentication is even stronger ;) Sam

I'm trying to get my pi's to use my pi email server to send mail and NOT use gmail:

I configured mutt using instructions from http://go2linux.garron.me/linux/2010/10/how-send-email-command-line-gma…

Following the above instructions at instruction 4 I get a warning:
sudo postmap /etc/postfix/saslpasswd
postmap: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol.

Can you please help??

When I do:
sudo service postfix restart
[....] Stopping Postfix Mail Transport Agent: postfixpostmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postfix: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
. ok
[....] Starting Postfix Mail Transport Agent: postfixpostmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
postmulti: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
postfix: warning: inet_protocols: disabling IPv6 name/address support: Address family not supported by protocol
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd
/usr/sbin/postconf: warning: /etc/postfix/main.cf: unused parameter: smtp-sasl_password_maps=hash:/etc/postfix/saslpasswd

I am able to send email using gmail from a satellite pi using mutt. Mutt uses these settings in /etc/ssmtp/ssmtp.conf:

cat /etc/ssmtp/ssmtp.conf
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=postmaster

# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
mailhub=smtp.gmail.com:587

# Where will the mail seem to come from?
#rewriteDomain=

# The full hostname
hostname=homepi

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES
AuthUser=user@gmail.com
AuthPass=PASSWORD
FromLineOverride=YES
mailhub=smtp.gmail.com:587
UseSTARTTLS=YES

Then I followed the above instructions and changed the setting in /etc/ssmtp/ssmtp.conf to:
#
# Config file for sSMTP sendmail
#
# The person who gets all mail for userids < 1000
# Make this empty to disable rewriting.
root=postmaster

# The place where the mail goes. The actual machine name is required no
# MX records are consulted. Commonly mailhosts are named mail.domain.com
mailhub=mydomain:587

# Where will the mail seem to come from?
#rewriteDomain=

# The full hostname
hostname=homepi

# Are users allowed to set their own From: address?
# YES - Allow the user to specify their own From: address
# NO - Use the system generated From: address
FromLineOverride=YES
AuthUser=user@mydomain
AuthPass=password
FromLineOverride=YES
mailhub=mydomain:587
UseSTARTTLS=YES

On the pi email server I send a message using:
echo "sample text" | mutt -s "Subject" username@mydomain
(the prompt returns immediately)

and watch with tail -f /var/log/mail.log and I see:
Nov 22 21:03:30 mydomain postfix/smtpd[22079]: connect from (ip)
Nov 22 21:03:30 mycomain postfix/smtpd[22079]: disconnect from (ip)

The send is unsuccessful. Can you see anything that I am missing?

Thanks!

Right about public key.

I use: Strong password, change port from 22, PublicAuthentication - with large keys, HostbasedAuthentication, PasswordAuthentication no, PermitRootLogin no, fail2ban, SSH Protocol 2, Idle Logout Timeout, TCP Wrappers, Rate limiting, deny hosts, arpwatch, and real time display of authentication status in conky window for all computers on my networks. My pi's email me if there is a problem with security.

Ya gotta be careful and vigilant!

Thanks for all you help along the way.

You're welcome, and you're definitely right about being vigilant. Best way to notice problems is to review the logs! BTW, I updated those instructions, so you'll want to refresh the page before following them. Sam

Warren Moore

Sat, 06/20/2015 - 16:15

Hi Sam

I'd followed your guide and got everything working...had been working fine for weeks...then after coming back from vacation I've found that while I can can use smtp and imap just fine without ssl, when I try using them with ssl I get connection refused. I'm guessing its a certificate problem
openssl s_client -connect localhost:993 gets me a response of

depth=0 CN = *********.net
verify error:num=20:unable to get local issuer certificate
verify return:1
depth=0 CN = *********.net
verify error:num=27:certificate not trusted
verify return:1
depth=0 CN = *********.net
verify error:num=21:unable to verify the first certificate
verify return:1

Help!!! ;)

nope, can restart both without error...followed the instructions on how to verify the capath...but not joy...still being refused when I try to use ssl

I'm not sure what I should be looking for in /var/log/mail.log. I've followed the guide,recreated an entire installation on a new sd card and still get connection refused when I try ssl. Can I send you a txt file with the contents of mail.log ....you at least know what to look for?

Thanks for all your help

I think it may have happened because various SSL/TLS protocols have been disabled because of downgrade attacks etc. I'll have to look into it and get back to you! Sam

Thanks. I had no idea what the problem was, and it didn't help that I'd just installed a DD-WRT router etc, a new NAS etc. Lesson for the future, one change at a time. At one point was convinced that I'd set up the forwards wrong in the router, but alas, it couldn't be that simple.

Again, many thanks for all your help

I now appear to have a fully functional e-mail server running on the RPi next to my elbow. I have only followed through with the Postfix, Dovecot and CaCert part of things. A couple of observations and I was not stringent in documenting my experience so I will have missed some things....

It is possible/likely that someone else has mentioned these but I'll be lazy and not hunt for the answers in the comments. It is also extremely likely that I did something wrong and 'fixed' it in a broken way.

My /etc/postfix/main.cf includes

inet_protocols = ipv4
home_mailbox = Maildir/
mailbox_command =
smtpd_recipient_restrictions =
permit_sasl_authenticated,
permit_mynetworks,
reject_unauth_destination
smtpd_helo_required = yes
smtpd_helo_restrictions =
permit_mynetworks,
permit_sasl_authenticated,
reject_invalid_helo_hostname,
reject_non_fqdn_helo_hostname,
reject_unknown_helo_hostname
check_helo_access hash:/etc/postfix/helo_access

smtpd_sasl_type = dovecot
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes
smtpd_tls_auth_only = yes

Now I assume that 'permit_sasl_authenticated' should have allowed me to send e-mails if I was 'authenticated'. As I suggest I may have got something else wrong but when I tried to send an e-mail I got a '192.168.0.1 Client Host Rejected Access Denied'. As a result I went and bodged..

mynetworks = 127.0.0.0/8 [::ffff:127.0.0.0]/104 [::1]/128 192.168.0.0/24 192.168.1.0/24

in order to include the addresses that might/will exist on my local [mess]network and that appears to have worked. Was that necessary or have I borged the set up of SASL authenticated? In my case it does not really matter because I don't expect the RPi to have to deal with anyone trying to send e-mail external to the local network. Otherwise I kind of wonder if 'the rules' are 'mutually exclusive' or some sort of other logic.

In respect of IMAP... that was a bit of an eye opener. I've been running POP3 via another provider under Evolution for quite a while so I have a shed-load of stuff in a local account. It has been set up to delete downloaded messages from the remote server. I did, kind of, know about this synchronization stuff and then smacked my head into it when I tried copying some files from the old POP3 account into the new IMAP account under Evolution. That scoffed 3% of the 8GB microSD card as folders got synchronized.

I suppose I should really revert back to POP3 on the RPi but my knuckles hang low and scrape on the floor so I went and deleted some folders under Evolution on the local machine and that action was duplicated on the RPi..

root@spud:/home/spud/Maildir# ls -al
total 60
drwx------ 5 spud spud 4096 Jun 22 14:28 .
drwxr-xr-x 3 spud spud 4096 Jun 21 11:47 ..
drwx------ 2 spud spud 4096 Jun 22 14:28 cur
-rw------- 1 spud spud 16384 Jun 22 13:02 dovecot.index.cache
-rw------- 1 spud spud 7552 Jun 22 14:28 dovecot.index.log
-rw------- 1 spud spud 18 Jun 22 11:03 dovecot-keywords
-rw------- 1 spud spud 432 Jun 22 13:21 dovecot.mailbox.log
-rw------- 1 spud spud 218 Jun 22 14:28 dovecot-uidlist
-rw------- 1 spud spud 8 Jun 22 13:20 dovecot-uidvalidity
-r--r--r-- 1 spud spud 0 Jun 21 14:04 dovecot-uidvalidity.mumble
drwx------ 2 spud spud 4096 Jun 22 14:12 new
-rw------- 1 spud spud 0 Jun 22 13:21 subscriptions
drwx------ 2 spud spud 4096 Jun 22 14:10 tmp
root@spud:/home/spud/Maildir#

Then I set up some message rules under Evolution to redirect incoming fire into the original POP3 account and it would appear... well things almost work like POP3. I can mess about with the local files without affecting what is on the RPi, things are no longer being synchronized, and all that is left on the RPi with content is in the /home/spud/Maildir/cur folder which I can occasionally 'log in to and nuke from orbit'.

I guess I really did not want IMAP but maybe I did so I have had to cripple things to almost behave like POP3.

No doubt at this juncture you are resting your head in your palms gently shaking it from side to side but it is entirely your fault for delivering such a good tutorial.

In respect of CaCert, as I mentioned I did not document my experience... things appear to have gone well and the only hiccup was some sort of moan about 'registered' domains in respect of *.spud.co.uk IIRC my csr[?] file requested it but CaCert barfed at the concept and I had to register the request online. Apologies if that did not make sense.

Anyway. Once again thanks for the tutorial. I seem to be up and running but likely to fall into some 'spam bot trap' given my ISP will not give me PTR/rDNS so I have to rely on SPF.

Hi and thanks for these pages they're nice and straightforward to follow, I've got as fair as Squirrelmail however while that's all working no emails are getting out...

/var/log/mail.log shows the following for mails to external addresses, I don't think I've missed anything after following the tutorials

Oct 18 16:58:14 OriginalPi postfix/smtp[18930]: 3C9DA41E91: to=, relay=none, delay=2232, delays=2232/0.23/0/0, dsn=4.4.3, status=deferred (Host or domain name not found. Name service error for name=hotmail.com type=MX: Host not found, try again)

I am using Google for resolving DNS via my router not the ISPs (PlusNet) on a DHCP reservation.

Any thoughts? I will post addition configs if needed :)

Hmm, what happens if you do an MX lookup with dig on the server?
dig hotmail.com MX
It might not actually be a DNS failure, plusnet could be blocking the outgoing connection, but then I'd expect a "host unreachable" message. BTW if you don't have a static IP, mine only cost me a one off £5 admin fee with plusnet... dynamic IP addresses often have more blocking than static ones so it's well worth it. Sam

Thanks for coming back so quickly! I have a static IP already as I serve a virtual radar page too (http://jollyweb.co.uk:8077/VirtualRadar/desktop.html), this email server is a side project as I had to upgrade the Raspberry part of this to a Pi2! Anyway... The dig results are as follows
; <<>> DiG 9.9.5-9+deb8u3-Raspbian <<>> hotmail.com MX
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 45940
;; flags: qr rd ra; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;hotmail.com. IN MX

;; ANSWER SECTION:
hotmail.com. 1131 IN MX 5 mx2.hotmail.com.
hotmail.com. 1131 IN MX 5 mx1.hotmail.com.
hotmail.com. 1131 IN MX 5 mx3.hotmail.com.
hotmail.com. 1131 IN MX 5 mx4.hotmail.com.

;; Query time: 22 msec
;; SERVER: 8.8.8.8#53(8.8.8.8)
;; WHEN: Mon Oct 19 07:53:48 UTC 2015
;; MSG SIZE rcvd: 120

So that looks OK - This is frustrating to say the least :(

It started working for a bit as a flood of test email can through from gmail/hotmail etc. but it's giving host not found again and I'm now getting this popping up in the log too!

Oct 19 14:51:10 mail postfix/lmtp[4367]: C41B342AD1: to=, relay=none, delay=0.66, delays=0.53/0.07/0.06/0, dsn=4.4.1, status=deferred (connect to mail.jollyweb.co.uk[private/dovecot-lmtp]: Permission denied)

Oct 19 14:54:31 mail postfix/smtp[5623]: ADA3F42AC9: to=, relay=none, delay=481, delays=481/0.18/0/0, dsn=4.4.3, status=deferred (Host or domain name not found. Name service error for name=samhobbs.co.uk type=MX: Host not found, try again

Sam Hobbs

Wed, 10/21/2015 - 21:13

Sure, just create an MX record for the 2nd domain that points to the A record of your primary domain. Then append your 2nd domain to the "mydestination" parameter so the server knows it should accept mail addressed to that domain too. Note that system account "foo" will get mail from both "foo@domain1.com" and "foo@domain2.com" delivered to the same Maildir. Sam

Hi Sam,

Just wondering...

Is it possible to get Outlook to work with my new email server? If so, how would I do it?

Regards,

Jo

Hi i was wondering if it could be a problem to do this tutorial on a pi that is already running as my website from home
(by the way followed your tutorial its GREAT!!! thank you)
would you say its not recommended to run email and hosting on the same pi on the same home network or is it fine?
should i dedicate a pi for hosting and a pi for email?

regards
Daniel

Hi Sam, my RPi email server has been working quite nicely, but recently it has stopped receiving emails. After sending a test message from another account I received a warning saying the message had been delayed and there was a "socket error". On running a test from an MX checker service on the internet I discovered there is no MX record. I am using DynDNS to update my IP address and the site seems to work fine. I can even send messages from my RPi server, just nothing coming in. I followed the DynDNS checks and checked the ports, 992 and 465 in this case and they are open at the router (but then again this was already working), so I am mystified about what has happened. Any ideas?

Add new comment

The content of this field is kept private and will not be shown publicly.

Filtered HTML

  • Web page addresses and email addresses turn into links automatically.
  • Allowed HTML tags: <a href hreflang> <em> <strong> <cite> <blockquote cite> <code> <ul type> <ol start type> <li> <dl> <dt> <dd>
  • Lines and paragraphs break automatically.