title:Hosting your Own Email Part 1
date: 2020-10-10 18:00
tags: email opensmtpd
summary: Hosting Email takes some tweaking
---

I have wanted to host my own email for some time now.  I have not realized this
goal yet, but I am discovering that hosting your own email involves a fair
amount of different moving parts.  I have often heard from fairly technical
people that hosting your own email, is really complicated!  This post is an
explanation of what email is, and how guix system may be the best solution for
setting up email.  Please note that this is a multi-series blog post.  This is
part 1.

The [Archlinux wiki](https://wiki.archlinux.org) is perhaps the best wiki to
help you configure software.  The [Mail server wiki
page](https://wiki.archlinux.org/index.php/Mail_server) is a great place to
start learning about hosting your own email.  Let's start with the high level
view, as outlined by the archlinux guide.  Essentially hosting your own email
requires three bits of software:

- a mail transfer agent (MTA) receives and sends email  (opensmtpd)
- a mail delivery agent (MDA), which gets the email from the MTA, and stores it
  for a user.  (opensmtpd)
- Remote users can access the emails via an MUA (mail user agent), via an IMAP
  server. (dovecot)

Since, guix has packaged an opensmtpd service already, I decided to use it, and
according to the arch wiki it looks like opensmtpd is an mail transfer agent and
a mail delivery agent!  So that's two of my issues sorted right there!  The last
set, which is letting remote users access the email, is handled by dovecot,
which is the IMAP email server.

By convention sending emails is done by `smtp.<yourdomainname>.com`, and your
mail user agent (like Mozilla's Thunderbird), retrieves your email via
`imap.<yourdomainname>.com`.  So I've decided get Let's Encrypt certificates
for my domain "gnucode.me" for the subdomains `smtp` and `imap`.  Like so:

```scheme
(use-service-modules certbot)

(define %nginx-deploy-hook
  (program-file
   "nginx-deploy-hook"
   #~(let ((pid (call-with-input-file "/var/run/nginx/pid" read)))
       (kill pid SIGHUP))))

(service certbot-service-type
         (certbot-configuration
          (email "jbranso@dismail.de")
          (webroot "/srv/www")
          (certificates
           (list
            (certificate-configuration
             (name "gnucode.me")
             (domains '("gnucode.me" "www.gnucode.me" "imap.gnucode.me"
             "smtp.gnucode.me" "mail.gnucode.me"))
             (deploy-hook %nginx-deploy-hook))))))
```

The [Archlinux opensmtpd
page](https://wiki.archlinux.org/index.php/OpenSMTPD#Simple_OpenSMTPD/mbox_configuration)
has a great guide on setting up a simple mail server.  I've modified it to
deliver emails in the maildir format.
```scheme
(use-modules (guix gexp))

(define creds
  (plain-file "creds"
              "joshua $6$somelonghashofstrings"))

(define vdoms
  (plain-file
   "vdoms"
   "gnucode.me
gnu-hurd.com"))

(define vusers
  (plain-file
   "vusers"
   "joshua@gnucode.me  joshua
jbranso@gnucode.me     joshua")

(service opensmtpd-service-type
         (opensmtpd-configuration
          (config-file
           (mixed-text-file "smtpd.conf"
                            "
# This is the smtpd server system-wide configuration file.
# See smtpd.conf(5) for more information.
# borrowed from the archlinux guix
# https://wiki.archlinux.org/index.php/OpenSMTPD#Simple_OpenSMTPD/mbox_configuration

# My TLS certificate and key
table aliases file:/etc/aliases
pki mail.gnucode.me cert \"/etc/letsencrypt/live/gnucode.me/fullchain.pem\"
pki mail.gnucode.me key \"/etc/letsencrypt/live/gnucode.me/privkey.pem\"

table creds \"" creds "\"
table vdoms \"" vdoms "\"
table vusers \"" vusers "\"

# listen on eth0, fairly explainatory
listen on eth0 tls pki mail.gnucode.me
listen on eth0 port 465 mails pki mail.gnucode.me auth <creds>
listen on eth0 port 587 tls-require pki mail.gnucode.me auth <creds>

action receive maildir virtual <vusers>
action send relay

match from any for domain <vdoms> action receive
match for any action send"))))
```

To serve your emails via imap, you also need a program to serve those files.
Dovecot is probably one of the better ones to use.  And it is conveniently
packaged in guix!

```scheme
(use-service-modules mail)
;; be default dovecot-service serves mail located in ~/Maildir, which is
;; what we have configured above.
(dovecot-service)
```

Ideally the above would be enough to get you sorted, but it's not.  There are
three things you should do to make certain that your sent email is not flagged
as spam:

- proving you sent your email (DKIM)
- Sender Policy Framework (SPF)
- What should other email account do if your email fails the above two tests?
  (DMARC)

I found [this detailed email setup
guide](https://poolp.org/posts/2019-09-14/setting-up-a-mail-server-with-opensmtpd-dovecot-and-rspamd/)
that I've found helpful.  Fair warning, it's like trying to drink water from a
fire hose.

The above configuration for opensmtpd is enough for me to receive emails for
joshua AT gnucode.me, but I am unable to send emails.  Also dovecot refuses to
authenticate my email client (gnus).  Fixes to those problems will appear in a
later post.
