How to set up a free self hosted email server for home in 2020

Outcome Summary

  • This ‘How To’ article will show you step by step how to set up and install the Zimbra mail server, arguably the best professional mail system you can get as an open source free alternative to cloud and proprietary solutions. There is also another frontrunner though, SOGo mail server. If you’re after something simpler, this may be for you.
  • This article includes installation of anti-spam technology
  • This article includes proper implementation of email sending so that it is not detected as spam by recipient services

I actually did this project while in lockdown because I was frustrated with the cost of decent email and forgot to publish it. Since that time obviously centos has got a new contender in the space, but the instructions will still work and I suspect people will get some use out of it. The server I built out of this guide is still running happily today serving many happy customers with email. Happy emailing. 😀

Why might I want to do this?

Pros

  • Because you’re tired of paying $7 per month for one email account and you need more accounts!
  • Because you’re tired of paying for an extra domain only to be told you also need to pay for an extra account on top
  • Because you want to know your personal email isn’t being mined and analysed for information (not naming you because I’m scared of you)
  • You’re a geek and you need admin sending accounts and so on (and let’s face it you are)
  • Because your provider keeps marking email as SPAM when it isn’t (thanks Microsoft, why don’t you listen to your forums!)
  • Because your provider loses email when it shouldn’t (I’m not naming you but you know who you are)
  • Because you’re so tired of cloud everything, and it fails to deliver sometimes (and you’ve tried enough of them to know)
  • Because $7 + $7 +$7 +$7 ‘per user’ for everything cloud begins to become unviable and it’s more cost effective to do it yourself!

Cons

  • You have to administer it
  • You may experience slightly more downtime

Implementation

Zimbra Mail Server – Amazon Simple Email Service (SES) for sending

Problem

Most residential ISP’s either don’t allow or don’t provide a PTR record (that is a reverse DNS lookup that can only be provisioned by the owner of an IP address).  While many email providers have now done away with PTR validation including the big ones such as google and Microsoft), many still use this validation technique, so without a PTR you are likely to be unable to send to many addresses.

Architecture Summary

This howto will set up a Zimbra mail server, that receives on your local server but sends via an external mail relay, Amazon Simple Email Services.  Using an official mail relay gets around the problem of PTR.  Amazon is chosen because even though there are free mail relays available, Amazon has a high reputation and very low cost solution that is likely to cost less than 10c per month for most people.  You can easily change this out if required, just search online for ‘email relay’ to find another choice.

Further Recommendations

It’s a good idea to run a backup MX either in the cloud or with a friend as a store and forward, this way if your ISP or email server experiences an outage, your mail will be safe and senders will not receive email delivery delay messages.

Pre-requisites

Domain Setup

  • DNS A record server.yourdomain.com pointing to public IP of your mail server (NAT OK)
  • MX record yourdomain.com points to server.yourdomain.com 10
  • Set up Internally facing DNS pointing to mail server in firewall e.g. kirk.yourdomain.com (some firewalls may just use the public IP OK, OPNSENSE doesn’t and this is better anyway).

Amazon Simple Email Service

  • In AWS console
    • Set up domain and DKIM – very important
    • Request sending limit increase (takes 24 hours) so that you don’t have to validate every email address recipient and can increase from default 200 emails per day sending if desired.

Email Server System Requirements

  • 2.0GHz 64 bit CPU
  • 8 GB RAM
  • 10GB Disk Space for software and logs (allows for 5GB logs) + Mail storage
  • See here for more information

Operating System

  • Minimal CentOS 7 server (minimal chosen to avoid conflicts with Zimbra in-built mail systems such as postfix) see here for other supported Operating systems
  • Ext4
  • NTP configured and running

Summary Steps

High Level Summary Steps

The below lists the high level summary of steps we’re about to take during this howto.

Virtualisation settings

  • Provision in qcow format to limit disk space usage
  • Install and create a new minimal CentOS Virtual Machine or equivalent
  • 8-16GB RAM / 4CPU
  • Note the Network Mac address from the VM template and assign a static IP from your router

CentOS Install

  • Don’t forget to turn on network and configure hostname at your domain during install
  • You don’t need to create a zimbra user, it’s created by the install script automatically.

Build

  • Add your Zimbra user to the sudo group
  • # usermod -aG wheel Zimbra
  • Note you may have to log out and back in for the sudo command to take effect.
  • Update your packages to latest
  • $ sudo yum update
  • Disable the inbuilt firewall (make sure you have a network firewall obviously)
  • $ sudo systemctl disable firewalld
  • $ sudo systemctl stop firewalld
  • Disable selinux
  • $ sudo setenforce 0
  • $ sudo nano /etc
  • Change selinux to SELINUX=disabled in the below file
  • $ sudo vi /etc/selinux/config
  • Install dependencies (+ wget and nano)
  • $ sudo yum -y install unzip net-tools sysstat openssh-clients perl-core libaio nmap-ncat libstdc++.so.6 wget nano
  • Remove unwanted stuff
  • $ sudo systemctl stop postfix
  • $ sudo systemctl disable postfix
  • $ sudo yum remove postfix
  • $ sudo hostnamectl set-hostname kirk
  • Add the following into /etc/hosts
  • 192.168.1.41             kirk.yourdomain.net            kirk
  • Download Zimbra
  • Get the link for the latest red hat 7 edition from here
  • $ sudo wget https://files.zimbra.com/downloads/8.8.15_GA/zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  • Extract it to the zimbra home folder
  • $ tar -xvf zcs-8.8.15_GA_3869.RHEL7_64.20190918004220.tgz
  • Run the install script
  • $ sudo ./install.sh –platform-override
  • Accept licence agreement [Y]
  • Use Zimbra’s package repository [Y]
  • Accept all the defaults for the package installation (imapd correctly defaults to no, for others [Y]
  • The system will be modified [Y]
  • DNS Error Resolve MX for kirk.yourdomain.com
  • Change domain name? [No]
  • In the menu, press 7 and 4 to set the admin password
  • Press r to return
  • Press a to apply
  • Say yes to save configuration and note the path as you may need this depending on your proxy setups etc.
  • The system will be modified [Yes]
  • Notify Zimbra of your installation  [No]
  • Configuration complete, press return to exit.

Configuring Zimba

  • From a web browser go to your mail server on port 7071 via https e.g. https://kirk.yourdomain.com:7071
  • Accept the self signed certificate, you’re likely using a reverse proxy anyway
  • Login with admin and the password you created previously.
  • You now have a fully functioning mail server.
  • The server can be uninstalled by
  • $ sudo ./install.sh -u
  • Also, you can reinstall it safely over the top if you want to change some settings (it detects what is already existing in the configuration automatically.

Connecting to the web mail address

Best practice and easiest would be to set up a reverse proxy to the webmail server over https e.g.

server {
    listen 443 ssl;
    listen [::]:443 ssl;
    server_name webmail.yourdomain.com;
    include /config/nginx/ssl.conf;
    client_max_body_size 0;
    # enable for ldap auth, fill in ldap details in ldap.conf
    #include /config/nginx/ldap.conf;
    location / {
        include /config/nginx/proxy.conf;
        resolver 127.0.0.11 valid=30s;
        set $upstream_app 192.168.43.41;
        set $upstream_port 443;
        set $upstream_proto https;
        proxy_pass $upstream_proto://$upstream_app:$upstream_port;
    }
}

Or you can directly connect to the webmail self-signed install by port forwarding to port 443 on the server IP.

In Zimbra administration

  • Go to configure, domains, new
  • Add your proper domain (i.e. without the host part)
  • e.g Domain name electropositive.net
  • Click next and choose the mail server from the drop down list.
  • Click finish (skipping the remainder of the screens.
  • Go to configure, global settings, and chance default domain to the correct default domain (i.e take out the host).  e.g yourdomain.com is all that should remain.
  • Go to configure, class of service, default, preferences and choose your default time zone.  Save.
  • Go to Manage, accounts, new
  • Add your email address and relevant domain
  • Add your First / Last name
  • Set your password details and time Zone
  • Skip the remainder of questions and click finish

If you get an error about “unknown command sent to server: ZxChatRequest”, the fix is to do the following:

mv /opt/zimbra/lib/ext/openchat/zal.jar /tmp
cp -rp /opt/zimbra/lib/ext/zimbradrive/zal.jar /opt/zimbra/lib/ext/openchat/zal.jar
su - zimbra
zmmailboxdctl restart

Amazon Simple Email Services setup

  • Setup your Amazon dkim etc if you haven’t already.
  • Get your smtp username and password.
  • su – zimbra
  • create an authentication file for amazon:
  • nano /opt/ zimbra/conf/relay_password
  • email-smtp.eu-west-1.amazonaws.com AKIATNTTHISISDUMMYCODEF36NNR: BVm74Oor0nB1XDUMBvFs2xtEmla8Ki
  • postmap lmdb:/opt/zimbra/conf/relay_password
  • Configure zimbra to use this username and password:
  • zmprov mcf zimbraMtaSmtpSaslPasswordMaps lmdb:/opt/zimbra/conf/relay_password
  • zmprov mcf zimbraMtaSmtpSaslAuthEnable yes
  • zmprov mcf zimbraMtaSmtpCnameOverridesServername no
  • zmprov mcf zimbraMtaSmtpTlsSecurityLevel may
  • zmprov mcf zimbraMtaSmtpSaslSecurityOptions noanonymous
  • Create a lookup file where you put the domains you want to send via amazon or skip to the bottom where you can just route all non-local mail to amazon via the GUI.
  • nano /opt/zimbra/conf/relay_amazon
  • inside that file put 
  • kirk.yourdomain.net smtp:email-smtp.eu-west-1.amazonaws.com
  • postmap lmdb:/opt/zimbra/conf/relay_amazon
  • Of Course, you can add extra domains to the list above in an editor of your liking. Remember to run the postmap command after every change.
  • Tell zimbra to use the above mapping:
  • zmprov mcf zimbraMtaTransportMaps lmdb:/opt/zimbra/conf/relay_amazon,proxy:ldap:/opt/zimbra/conf/ldap-transport.cf
  • Activate the configuration
  • zmmtactl reload

Configure all non local mail to amazon via GUI

  • Go to configure, global settings, MTA, network.
  • Add email-smtp.eu-west-1.amazonaws.com to relay MTA for external delivery port 587
  • Save

Adding an extra domain

  • Add a new domain to zimbra
  • Add the new accounts on that domain
  • Validate the domain on amazon or your other relay
  • Do it in this order so that any downtime between old and new providers has the mail turning up in one of the accounts.  Failure to do so may create some non-delivery.
  • Caldav and cardave work on port 443 so reverse proxy is good for that
[td_block_21 modules_on_row="" modules_gap="" image_width="28" image_floated="float_left" meta_padding="0" image_radius="8" image_height="70" meta_info_horiz="" modules_category="" modules_category_margin="-1px 10px 0 0" show_excerpt="none" show_btn="none" show_com="none" show_author="none" show_cat="" image_size="td_324x400" block_template_id="" f_title_font_line_height="eyJhbGwiOiIxLjIiLCJwb3J0cmFpdCI6IjEuMSIsImxhbmRzY2FwZSI6IjEuMSIsInBob25lIjoiMS4xIn0=" f_title_font_family="406" f_title_font_size="eyJhbGwiOiIxOCIsImxhbmRzY2FwZSI6IjE2IiwicG9ydHJhaXQiOiIxNCIsInBob25lIjoiMTYifQ==" f_title_font_weight="eyJhbGwiOiI4MDAiLCJwb3J0cmFpdCI6IjYwMCJ9" f_cat_font_size="eyJhbGwiOiIxMSIsImxhbmRzY2FwZSI6IjEwIiwicG9ydHJhaXQiOiI5IiwicGhvbmUiOiIxMCJ9" f_cat_font_weight="800" f_cat_font_family="406" f_cat_font_transform="uppercase" f_meta_font_size="eyJhbGwiOiIxMSIsImxhbmRzY2FwZSI6IjEwIiwicG9ydHJhaXQiOiI5IiwicGhvbmUiOiIxMCJ9" f_meta_font_transform="uppercase" f_meta_font_family="406" all_modules_space="eyJhbGwiOiI0MiIsImxhbmRzY2FwZSI6IjM0IiwicG9ydHJhaXQiOiIyNCIsInBob25lIjoiMzIifQ==" meta_info_align="center" art_title="eyJhbGwiOiIwIDAgMTJweCIsImxhbmRzY2FwZSI6IjAgMCA4cHgiLCJwb3J0cmFpdCI6IjAgMCA2cHgiLCJwaG9uZSI6IjAgMCA4cHgifQ==" modules_category_padding="3px 0 4px" cat_txt="#0d42a2" cat_bg="rgba(13,66,162,0)" f_meta_font_weight="800" tdc_css="eyJhbGwiOnsibWFyZ2luLXRvcCI6IjIwIiwibWFyZ2luLWJvdHRvbSI6IjAiLCJkaXNwbGF5IjoiIn0sInBob25lIjp7ImRpc3BsYXkiOiIifSwicGhvbmVfbWF4X3dpZHRoIjo3Njd9" hide_image="yes" modules_divider="solid" title_txt="#000000" related_articles_posts_limit="5" sort="popular" custom_title="Popular Articles"]
spot_img

Related Stories

Stay on op - Ge the daily news in your inbox