After having mastered the set up of a LAMP server (Apache, MySQL, PHP, PHPMyAdmin) solution on my Raspberry Pi 3, and rounding it out with with a cloud solution for the file server (OwnCloud), and a content manager for the web server (Joomla), it was time for the next step: a mail server. Many thanks to Sam Hobbs, who invested countless hours in documenting and perfecting the Pi implementation, and carefully explaining it in detail. His instructions are more elaborate than mine, and worth visiting, as I have simplified his implementation significantly, and there are other features that he has implemented which you may want to replicate.
Below instructions assume that you have built the LAMP server solution already. Please do this before continuing; the instructions can be found at:
https://www.hackster.io/gulyasal/raspbian-stretch-with-joomla-owncloud-d29ccf
Mail servers are very popular for hackers who want to hijack it to send out spam in your name, so it's rather important that you change your password:
sudo passwd pi
Change password to something other than raspberry.
Implement Postfix and Dovecotsudo apt-get update
sudo apt-get install postfix
sudo apt-get install dovecot-common dovecot-imapd
Select 'Internet Site' and then set the mail name to your domain name. In this article, I refer to the domain name as example.com
cd /etc/postfix/
sudo nano /etc/postfix/main.cf
Edit the following:
myhostname = example.com
Add the following:
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
milter_protocol = 2
milter_default_action = accept
smtpd_milters = inet:localhost:12301
non_smtpd_milters = inet:localhost:12301
Ctrl-X to exit, and Y to save.
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
sudo maildirmake.dovecot /etc/skel/Maildir/.Junk
sudo cp -r /etc/skel/Maildir /home/pi/
sudo chown -R pi:pi /home/pi/Maildir
sudo chmod -R 700 /home/pi/Maildir
sudo nano /etc/postfix/helo_access
Add the following:
example.com REJECT Email rejected - cannot verify identity
mail.example.com REJECT Email rejected - cannot verify identity
Ctrl-X to exit, and Y to save.
sudo postmap /etc/postfix/helo_access
sudo nano /etc/dovecot/dovecot.conf
Edit:
listen = *
Ctrl-X to exit, and Y to save.
sudo nano /etc/dovecot/conf.d/10-mail.conf
Edit:
mail_location = maildir:~/Maildir
Ctrl-X to exit, and Y to save.
sudo nano /etc/dovecot/conf.d/10-master.conf
Edit:
service imap-login {
inet_listener imap {
port = 143
}
inet_listener imaps {
port = 993
ssl = yes
}
}
service auth {
unix_listener /var/spool/postfix/private/auth {
mode = 0660
user = postfix
group = postfix
}
}
Ctrl-X to exit, and Y to save.
sudo nano /etc/dovecot/conf.d/10-auth.conf
Edit:
disable_plaintext_auth = no
auth_mechanisms = plain login
Ctrl-X to exit, and Y to save.
sudo nano /etc/dovecot/conf.d/10-ssl.conf
Edit:
ssl = yes
ssl_protocols = !SSLv2 !SSLv3
ssl_cert = </etc/letsencrypt/live/example.com/fullchain.pem
ssl_key = </etc/letsencrypt/live/example.com/privkey.pem
You will note that rather than building a new SSL certificate, we are leveraging the certificate from Let's Encrypt that was already previously built.
Ctrl-X to exit, and Y to save. Now you will need to use the below "adduser" command to add each email address that you wish to set up. For example, to set up johnsmith@example.com:
sudo adduser johnsmith
sudo nano /etc/postfix/master.cf
Edit:
smtps inet n - - - - smtpd
smtps inet n - - - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
smtp inet n - - - - smtpd
-o content_filter=spamassassin
Add:
smtps inet n - - - - smtpd
-o syslog_name=postfix/smtps
-o smtpd_tls_wrappermode=yes
-o smtpd_recipient_restrictions=permit_sasl_authenticated,reject
spamassassin unix - n n - - pipe user=debian-spamd argv=/usr/bin/spamc -f -e /usr/sbin/sendmail -oi -f ${sender} ${recipient}
Ctrl-X to exit, and Y to save.
Add DKIM to stop your emails from being treated as spamsudo apt-get install opendkim opendkim-tools
sudo nano /etc/opendkim.conf
Add:
AutoRestart Yes
AutoRestartRate 10/1h
SyslogSuccess Yes
LogWhy Yes
Canonicalization relaxed/simple
ExternalIgnoreList refile:/etc/opendkim/TrustedHosts
InternalHosts refile:/etc/opendkim/TrustedHosts
KeyTable refile:/etc/opendkim/KeyTable
SigningTable refile:/etc/opendkim/SigningTable
Mode sv
PidFile /var/run/opendkim/opendkim.pid
SignatureAlgorithm rsa-sha256
UserID opendkim:opendkim
Socket inet:12301@localhost
Ctrl-X to exit, and Y to save.
sudo nano /etc/default/opendkim
Edit:
SOCKET="inet:12301@localhost"
Ctrl-X to exit, and Y to save.
sudo mkdir /etc/opendkim
sudo mkdir /etc/opendkim/keys
sudo nano /etc/opendkim/TrustedHosts
Add:
127.0.0.1
localhost
192.168.0.1/24
*.example.com
Ctrl-X to exit, and Y to save.
sudo nano /etc/opendkim/KeyTable
Add:
mail._domainkey.example.com example.com:mail:/etc/opendkim/keys/example.com/mail.private
Ctrl-X to exit, and Y to save.
sudo nano /etc/opendkim/SigningTable
Add:
*@example.com mail._domainkey.example.com
Ctrl-X to exit, and Y to save.
cd /etc/opendkim/keys
sudo mkdir example.com
cd example.com
sudo opendkim-genkey -s mail -d example.com
sudo chown opendkim:opendkim mail.private
sudo chmod 777 mail.txt
sudo nano -$ mail.txt
Go to your domain registrar (e.g., EuroDNS, GoDaddy, etc.). Use this output to set up a TXT record, with hostname: mail._domainkey and with value: v=DKIM1; k=rsa; p=MIG....
sudo service dovecot reload
sudo service dovecot restart
sudo service postfix reload
sudo service postfix restart
sudo service opendkim restart
Identify incoming spam email with SpamAssassinsudo apt-get install spamassassin
sudo nano /etc/spamassassin/local.cf
Edit:
rewrite_header Subject [***** SPAM _SCORE_ *****]
report_safe 0
required_score 5.0
use_bayes 1
Ctrl-X to exit, and Y to save.
sudo nano /etc/default/spamassassin
Edit:
ENABLED=1
Ctrl-X to exit, and Y to save.
sudo service spamassassin start
sudo systemctl enable spamassassin
sudo service dovecot restart
sudo service postfix restart
Web-based Email Client: RainLoopThere are other webclients like SquirrelMail which are quite effective, but I am rather a fan of the RainLoop web client. It's graphically pleasing to the eye:
sudo wget https://www.rainloop.net/repository/webmail/rainloop-community-latest.zip
sudo mkdir /var/www/html/mail
sudo unzip rainloop-community-latest.zip -d /var/www/html/mail
sudo chown -R www-data:www-data /var/www
sudo chmod -R 755 /var/www
sudo systemctl daemon-reload
sudo systemctl restart apache2.service
sudo mysql -u root -p
CREATE DATABASE rainloop;
quit
Configure the webmail client at: https://example.com/mail/?admin
User name: admin Password: 12345
Change the configuration settings as follows:
- Login: default domain: example.com
- Contacts: enable contacts: yes, type: MySQL, user: root, password: my_password. Click on Test
- Domains: untick Gmail. add domain: name: example.com, IMAP server: example.com, secure SSL/TLS, port 993, use short login: yes, SMTP server: example.com, secure SSL/TLS, port 465, use short login: yes, use authentication: yes. Click on Add
- Security: enter current and new password (x2). Click on Update Password.
There are other features which you can configure, but above are the more important ones. Enter the webmail client with https://example.com/mail
Port forwardingFinally, you must forward all the used ports for this implementation to your RPi3 on your router: 25, 110, 143, 993, 465, 995, 12301
You're done! Enjoy using your mail server!
Comments