all repos — site @ fcf383887b033bdb79aae706ed77dd655f0acf45

source for my site, found at icyphox.sh

pages/txt/mailserver.txt (view raw)

  1---
  2date: '2019-08-15'
  3subtitle: This is probably a terrible idea...
  4template: text.html
  5title: Setting up my personal mailserver
  6url: mailserver
  7---
  8
  9A mailserver was a long time coming. I'd made an attempt at setting one
 10up around \~4 years ago (ish), and IIRC, I quit when it came to DNS. And
 11I almost did this time too.[^1]
 12
 13For this attempt, I wanted a simpler approach. I recall how terribly
 14confusing Dovecot & Postfix were to configure and hence I decided to
 15look for a containerized solution, that most importantly, runs on my
 16cheap \$5 Digital Ocean VPS --- 1 vCPU and 1 GB memory. Of which only
 17around 500 MB is actually available. So yeah, *pretty* tight.
 18
 19What's available
 20----------------
 21
 22Turns out, there are quite a few of these OOTB, ready to deply
 23solutions. These are the ones I came across:
 24
 25-   [poste.io](https://poste.io): Based on an "open core" model. The
 26    base install is open source and free (as in beer), but you'll have
 27    to pay for the extra stuff.
 28
 29-   [mailu.io](https://mailu.io): Free software. Draws inspiration from
 30    poste.io, but ships with a web UI that I didn't need.
 31
 32-   [mailcow.email](https://mailcow.email): These fancy domains are
 33    getting ridiculous. But more importantly they need 2 GiB of RAM
 34    *plus* swap?! Nope.
 35
 36-   [Mail-in-a-Box](https://mailinabox.email): Unlike the ones above,
 37    not a Docker-based solution but definitely worth a mention. It
 38    however, needs a fresh box to work with. A box with absolutely
 39    nothing else on it. I can't afford to do that.
 40
 41-   [docker-mailserver](https://github.com/tomav/docker-mailserver/):
 42    **The winner**.
 43
 44So... `docker-mailserver`
 45-------------------------
 46
 47The first thing that caught my eye in the README:
 48
 49> Recommended:
 50>
 51> -   1 CPU
 52> -   1GB RAM
 53>
 54> Minimum:
 55>
 56> -   1 CPU
 57> -   512MB RAM
 58
 59Fantastic, I can somehow squeeze this into my existing VPS. Setup was
 60fairly simple & the docs are pretty good. It employs a single `.env`
 61file for configuration, which is great. However, I did run into a couple
 62of hiccups here and there.
 63
 64One especially nasty one was `docker` / `docker-compose` running out of
 65memory.
 66
 67    Error response from daemon: cannot stop container: 2377e5c0b456: Cannot kill container 2377e5c0b456226ecaa66a5ac18071fc5885b8a9912feeefb07593638b9a40d1: OCI runtime state failed: runc did not terminate sucessfully: fatal error: runtime: out of memory
 68
 69But it eventually worked after a couple of attempts.
 70
 71The next thing I struggled with --- DNS. Specifically, the with the step
 72where the DKIM keys are generated[^2]. The output under\
 73`config/opendkim/keys/domain.tld/mail.txt`\
 74isn't exactly CloudFlare friendly; they can't be directly copy-pasted
 75into a `TXT` record.
 76
 77This is what it looks like.
 78
 79    mail._domainkey IN  TXT ( "v=DKIM1; h=sha256; k=rsa; "
 80          "p=<key>"
 81          "<more key>" )  ; ----- DKIM key mail for icyphox.sh
 82
 83But while configuring the record, you set "Type" to `TXT`, "Name" to
 84`mail._domainkey`, and the "Value" to what's inside the parenthesis
 85`(  )`, *removing* the quotes `""`. Also remove the part that appears to
 86be a comment `; ----- ...`.
 87
 88To simplify debugging DNS issues later, it's probably a good idea to
 89point to your mailserver using a subdomain like `mail.domain.tld` using
 90an `A` record. You'll then have to set an `MX` record with the "Name" as
 91`@` (or whatever your DNS provider uses to denote the root domain) and
 92the "Value" to `mail.domain.tld`. And finally, the `PTR` (pointer
 93record, I think), which is the reverse of your `A` record --- "Name" as
 94the server IP and "Value" as `mail.domain.tld`. I learnt this part the
 95hard way, when my outgoing email kept getting rejected by Tutanota's
 96servers.
 97
 98Yet another hurdle --- SSL/TLS certificates. This isn't very properly
 99documented, unless you read through the
100[wiki](https://github.com/tomav/docker-mailserver/wiki/Installation-Examples)
101and look at an example. In short, install `certbot`, have port 80 free,
102and run
103
104``` {.shell}
105$ certbot certonly --standalone -d mail.domain.tld
106```
107
108Once that's done, edit the `docker-compose.yml` file to mount
109`/etc/letsencrypt` in the container, something like so:
110
111``` {.yaml}
112...
113
114volumes:
115    - maildata:/var/mail
116    - mailstate:/var/mail-state
117    - ./config/:/tmp/docker-mailserver/
118    - /etc/letsencrypt:/etc/letsencrypt
119
120...
121```
122
123With this done, you shouldn't have mail clients complaining about wonky
124certs for which you'll have to add an exception manually.
125
126Why would you...?
127-----------------
128
129There are a few good reasons for this:
130
131### Privacy
132
133No really, this is *the* best choice for truly private email. Not
134ProtonMail, not Tutanota. Sure, they claim so and I don't dispute it.
135Quoting Drew Devault[^3],
136
137> Truly secure systems do not require you to trust the service provider.
138
139But you have to *trust* ProtonMail. They run open source software, but
140how can you really be sure that it isn't a backdoored version of it?
141
142When you host your own mailserver, you truly own your email without
143having to rely on any third-party. This isn't an attempt to spread FUD.
144In the end, it all depends on your threat modelâ„¢.
145
146### Decentralization
147
148Email today is basically run by Google. Gmail has over 1.2 *billion*
149active users. That's obscene. Email was designed to be decentralized but
150big corps swooped in and made it a product. They now control your data,
151and it isn't unknown that Google reads your mail. This again loops back
152to my previous point, privacy. Decentralization guarantees privacy. When
153you control your mail, you subsequently control who reads it.
154
155### Personalization
156
157Can't ignore this one. It's cool to have a custom email address to flex.
158
159`x@icyphox.sh` vs `gabe.newell4321@gmail.com`
160
161Pfft, this is no competition.
162
163[^1]: My [tweet](https://twitter.com/icyphox/status/1161648321548566528)
164    of frustration.
165
166[^2]: [Link](https://github.com/tomav/docker-mailserver#generate-dkim-keys)
167    to step in the docs.
168
169[^3]: From his [article](https://drewdevault.com/2018/08/08/Signal.html)
170    on why he doesn't trust Signal.