Guide to hosting your own email

2020-10-28 @Technology

I’ve been hosting my own email on a Virtual Private Server (VPS) for the last few months. The setup was not trivial by any means, and this in spite of having leveraged a script that automates much of the setup procedure.

Even after the largely automated process, I still had to perform numerous customizations to suit my needs. Here I’ll attempt to relate the experience, explain what a typical email host configuration entails, as well as cover the additional steps I underwent.


Email Server Components

I used the Email wizard on my Debian VPS server to install and generate a (largely) working configuration for the email components described here. You can follow the instructions and the prerequisites highlighted in the repository. Here I’ll aim to provide any supplementary overview.

The typical components inherent to Unix-based email server are the following:

  1. Postfix, responsible primarily for the sending and receipt of your email. That is, email interchange between the outside world and your email server. This includes the SMTP configuration, the security, the host names, the aliases and custom delivery settings.
  2. Dovecot, the framework responsible for email delivery to your email client. The IMAP configuration, the local mail storage format, and the related security settings take place here.
  3. Spamassassin, self explanatory.
  4. OpenDKIM, part of the reliable email deliverability framework, further below.

The script strictly enables IMAP as the means of retrieving email. This suffices for my purposes, as I access email via mutt, synced locally with mbsync. However, graphical interfaces (ie Roundcube, Squirrel Mail) aren’t challenging to install for whoever be interested.

SSL and encryption

You need by all means create an SSL certificate for your mail server (for the mail subdomain as well as the primary email domains). The script README also relates this step.

The Let’s Encrypt authority provides free SSL certificates, interfaced locally via certbot.

Certbot is quiet easy to manage and integrates nicely with the mainstream web servers of (at least) Apache and Nginx. I mention a web server here, since an SSL certificate requires you to have a running web site for whatever domain/subdomain you desire the certificate be issued (be it a dummy ‘hello world’ site and nothing more). In this case, it’s the mail subdomain that need have a running web site instance.

I use nginx. To install certbot plus the certbot-nginx connector on a Debian-like system and issue a certificate:

apt install nginx certbot python-certbot-nginx 
certbot --nginx

The last command initiates a wizard that guides you through the steps of specifying the domain(s)/subdomain(s) for the requested certificate and the HTTPS redirection setting. And as long as you already have the ‘dummy’ web site configured, the wizard detects it from the nginx config. Analogous steps apply to the Apache web server.

It also requires that you have a DNS CNAME record created for your ‘mail’ subdomain in your domain registrar (more on DNS below).

Aliases and email forwarding

I use a different email domain from the primary host domain of my VPS, a scenario the emailwizard does not handle. Now there’s probably more than one way to approach the situation.

In my case, I let the wizard configure the mail components for the default HOSTDOMAIN as is, creating a mail server at mail.HOSTDOMAIN along with the necessary DNS settings. Afterwards, I

  1. created an alias that points EMAILDOMAIN to HOSTDOMAIN
  2. Added a DNS MX (mail-exchange) record for the EMAILDOMAIN that points to mail.HOSTDOMAIN. (The HOSTDOMAIN also requires the same MX record).

The alias specifics involved the following:

  1. A virtual alias map within the postfix configuration /etc/postfix/

    virtual_alias_maps = hash:/etc/postfix/virtual
  2. Indicate specific aliases within /etc/postfix/virtual:

    addr@EMAILDOMAIN localmailuser
    addr2@EMAILDOMAIN localmailuser

    Where localmailuser is a physical user assigned to the local mail group, that first and foremost collects mail at the address localmailuser@HOSTDOMAIN. Now most likely you’ll have the same username for both EMAIL and HOST domains, with an entry

    user@EMAILDOMAIN user.

  3. Having configured the above alias(es), load them into the alias database and restart postfix:

    postmap /etc/postfix/virtual
    postfix reload

Email deliverability

This aspect has given me most trouble ever since I abandoned Google as a hosting platform sometime last year in favour of independent options. Unlike 20-30 years ago, when email spoofing and spamming was incredibly easy, these days, plenty of protective measures take place, especially among the major cloud email platforms.

I’ve lost count how many of my emails didn’t get delivered in a timely manner in my early days of non-Google email hosting, due to my having been inexperienced with this infrastructure.

It follows, if you wish your email to be delivered anywhere but the spam folder (if delivered at all), you need to configure the following components within your email solution.

The emailwizard does some of the work in generating default DNS TXT entries for incorporation into your registrar (see below).

However, certain custom steps are still involved, and the negligence in any one detail could mean failed delivery, the debugging of which can be challenging. I say this, because I’ve always neglected some subtlety each time I switched my email hosting to something extravagant. But the independence from cloud solutions and the increased privacy makes the trouble worthwhile!

DKIM (DomainKeys Identified Mail)

DKIM appeals to a key pair encryption method to validate the identity and the integrity of your email message. Many email hosts, Gmail especially, will simply reject emails without a legitimate DKIM signature. It works as follows:

OpenDKIM generates a private key, stored securely on the email server. It also generates a public key made available in a DNS TXT entry of your registrar, for every domain you send email from.

Upon sending an email, OpenDKIM generates a signature of your email message using your DKIM private key, incorporating it in the email header. The receiver of the email then queries your domain for the respective public key, using that to decrypt the email signature.

If the message content doesn’t match the decrypted signature, this indicates that either

  1. the message was tampered mid-course, or
  2. some other email server sent out an email on your behalf, that is, spoofed your address.

In either of these cases, or if either the DKIM DNS record or the DKIM signature in the email header are absent, the receiver should either reject your email or mark it as spam.

SPF (Sender Policy Framework)

SPF is additional security measure that involves a DNS TXT entry for your domain, indicating all possible domains authorized to send email on your behalf.

The email receiver then queries the DNS record of your domain, and if the IP address of your outbound email server doesn’t match (or indirectly resolve) to one of the domains indicated in the SPF record policy, the receiver will reject or spam your message.

The SPF record generally includes at least your email server. And if, for example, you leverage an email subscription framework to also send out emails on your behalf, you would either directly include their domain in the record, or a pointer to their own SPF record.

It follows that, presuming the SPF validation passed, whichever authorized host actually sent out your email, the receiver then checks that hosts DKIM record for the DKIM validation (above).


Dmark is yet another security measure, although less crucial if SPF and DKIM are properly configured (per my knowledge). Nonetheless, an improper or an absent dmark record, could, in theory, result in email misdelivery. I will not indulge in detail, but suffice to say it involves yet another DNS TXT entry to add in your domain registrar.

Reverse DNS

Other reasons aside, the email recipient must match the sending IP address against the authorized senders in the spf record. As an spf record normally specifies a domain rather than an IP, you must configure a reverse DNS entry on your host to translate from one to the other. In the case of a VPS, this is typically handled in the VPS instance configuration.

Also, this reverse DNS pointer entry you must configure individually for IPV4 and IPV6 configurations, provided your host leverages IPV6 for sending email and in general.

Checking for proper configuration

While not foolproof, appmaildev conducts a fairly comprehensive test of proper dkim, spf, dmark, reverse DNS settings, and more. It has bailed me out a time too many.

Firewall ports

If you have a firewall enabled, either on the actual VPS or, at the more abstract layer of the VPS instance settings, make sure to enable the respectful ports.

This, by default, entails ports 587 and 993 for SMTP and IMAP, as well as possibly the unsecure SMTP port 25 (not for base operation, but some other, possibly deliverability reason that escapes me).


Primary email host domain

You must add/insure a series of DNS entries for your email host domain in the registrar. Let’s suppose this to be

Alias (optional)

The emailwizard generates the TXT records for the primary domain, but not for any alias, as happens to be my case. As such, if you send out your email not from the domain, but (be they the same physical host), you need insure the following DNS entries for in your registrar:

The above handled, and the individual issues addressed, you’ll have a working email server at your total control. Follow the Email Wizard.

Sources referenced

  1. Email Wizard
  2. mbsync
  3. mutt
  4. letsencrypt
  5. certbot
  6. On encryption
  7. dkim
  8. opendkim
  9. spf
  10. dmark
  11. appmaildev

Questions, comments? Connect.