build/blog/mailserver/index.html (view raw)
1<!DOCTYPE html>
2<html lang=en>
3<link rel="stylesheet" href="/static/style.css" type="text/css">
4<link rel="stylesheet" href="/static/syntax.css" type="text/css">
5<link rel="shortcut icon" type="images/x-icon" href="/static/favicon.ico">
6<meta name="description" content="This is probably a terrible idea…">
7<meta name="viewport" content="initial-scale=1">
8<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
9<meta content="#021012" name="theme-color">
10<meta name="HandheldFriendly" content="true">
11<meta name="twitter:card" content="summary_large_image">
12<meta name="twitter:site" content="@icyphox">
13<meta name="twitter:title" content="Setting up my personal mailserver">
14<meta name="twitter:description" content="This is probably a terrible idea…">
15<meta name="twitter:image" content="/static/icyphox.png">
16<meta property="og:title" content="Setting up my personal mailserver">
17<meta property="og:type" content="website">
18<meta property="og:description" content="This is probably a terrible idea…">
19<meta property="og:url" content="https://icyphox.sh">
20<meta property="og:image" content="/static/icyphox.png">
21<html>
22 <title>
23 Setting up my personal mailserver
24 </title>
25<script src="//instant.page/1.1.0" type="module" integrity="sha384-EwBObn5QAxP8f09iemwAJljc+sU+eUXeL9vSBw1eNmVarwhKk2F9vBEpaN9rsrtp"></script>
26<div class="container-text">
27 <header class="header">
28
29 <a href="/">home</a>
30 <a href="/blog">blog</a>
31 <a href="/reading">reading</a>
32 <a href="https://twitter.com/icyphox">twitter</a>
33 <a href="/about">about</a>
34
35 </header>
36<body>
37 <div class="content">
38 <div align="left">
39 <p> 2019-08-15 </p>
40 <h1> Setting up my personal mailserver </h1>
41 <h2> This is probably a terrible idea… </h2>
42 <p>A mailserver was a long time coming. I’d made an attempt at setting one up
43around ~4 years ago (ish), and IIRC, I quit when it came to DNS. And
44I almost did this time too.<sup class="footnote-ref" id="fnref-1"><a href="#fn-1">1</a></sup></p>
45
46<p>For this attempt, I wanted a simpler approach. I recall how terribly
47confusing Dovecot & Postfix were to configure and hence I decided to look
48for a containerized solution, that most importantly, runs on my cheap $5
49Digital Ocean VPS — 1 vCPU and 1 GB memory. Of which only around 500 MB
50is actually available. So yeah, <em>pretty</em> tight.</p>
51
52<h3 id="whats-available">What’s available</h3>
53
54<p>Turns out, there are quite a few of these OOTB, ready to deply solutions.
55These are the ones I came across:</p>
56
57<ul>
58<li><p><a href="https://poste.io">poste.io</a>: Based on an “open core” model. The base install is open source
59and free (as in beer), but you’ll have to pay for the extra stuff.</p></li>
60<li><p><a href="https://mailu.io">mailu.io</a>: Free software. Draws inspiration from poste.io,
61but ships with a web UI that I didn’t need. </p></li>
62<li><p><a href="https://mailcow.email">mailcow.email</a>: These fancy domains are getting ridiculous. But more importantly
63they need 2 GiB of RAM <em>plus</em> swap?! Nope.</p></li>
64<li><p><a href="https://mailinabox.email">Mail-in-a-Box</a>: Unlike the ones above, not a Docker-based solution but definitely worth
65a mention. It however, needs a fresh box to work with. A box with absolutely
66nothing else on it. I can’t afford to do that.</p></li>
67<li><p><a href="https://github.com/tomav/docker-mailserver/">docker-mailserver</a>: <strong>The winner</strong>. </p></li>
68</ul>
69
70<h3 id="so-docker-mailserver">So… <code>docker-mailserver</code></h3>
71
72<p>The first thing that caught my eye in the README:</p>
73
74<blockquote>
75 <p>Recommended:</p>
76
77 <ul>
78 <li>1 CPU</li>
79 <li>1GB RAM</li>
80 </ul>
81
82 <p>Minimum:</p>
83
84 <ul>
85 <li>1 CPU</li>
86 <li>512MB RAM</li>
87 </ul>
88</blockquote>
89
90<p>Fantastic, I can somehow squeeze this into my existing VPS.
91Setup was fairly simple & the docs are pretty good. It employs a single
92<code>.env</code> file for configuration, which is great.
93However, I did run into a couple of hiccups here and there.</p>
94
95<p>One especially nasty one was <code>docker</code> / <code>docker-compose</code> running out
96of memory.</p>
97
98<pre><code>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
99</code></pre>
100
101<p>But it eventually worked after a couple of attempts.</p>
102
103<p>The next thing I struggled with — DNS. Specifically, the with the step where
104the DKIM keys are generated<sup class="footnote-ref" id="fnref-2"><a href="#fn-2">2</a></sup>. The output under <br />
105<code>config/opendkim/keys/domain.tld/mail.txt</code> <br />
106isn’t exactly CloudFlare friendly; they can’t be directly copy-pasted into
107a <code>TXT</code> record. </p>
108
109<p>This is what it looks like.</p>
110
111<pre><code>mail._domainkey IN TXT ( "v=DKIM1; h=sha256; k=rsa; "
112 "p=<key>"
113 "<more key>" ) ; ----- DKIM key mail for icyphox.sh
114</code></pre>
115
116<p>But while configuring the record, you set “Type” to <code>TXT</code>, “Name” to <code>mail._domainkey</code>,
117and the “Value” to what’s inside the parenthesis <code>( )</code>, <em>removing</em> the quotes <code>""</code>.
118Also remove the part that appears to be a comment <code>; ----- ...</code>.</p>
119
120<p>To simplify debugging DNS issues later, it’s probably a good idea to
121point to your mailserver using a subdomain like <code>mail.domain.tld</code> using an
122<code>A</code> record.
123You’ll then have to set an <code>MX</code> record with the “Name” as <code>@</code> (or whatever your DNS provider
124uses to denote the root domain) and the “Value” to <code>mail.domain.tld</code>.
125And finally, the <code>PTR</code> (pointer record, I think), which is the reverse of
126your <code>A</code> record — “Name” as the server IP and “Value” as <code>mail.domain.tld</code>.
127I learnt this part the hard way, when my outgoing email kept getting
128rejected by Tutanota’s servers.</p>
129
130<p>Yet another hurdle — SSL/TLS certificates. This isn’t very properly
131documented, unless you read through the <a href="https://github.com/tomav/docker-mailserver/wiki/Installation-Examples">wiki</a>
132and look at an example. In short, install <code>certbot</code>, have port 80 free,
133and run </p>
134
135<div class="codehilite"><pre><span></span><code>$ certbot certonly --standalone -d mail.domain.tld
136</code></pre></div>
137
138<p>Once that’s done, edit the <code>docker-compose.yml</code> file to mount <code>/etc/letsencrypt</code> in
139the container, something like so:</p>
140
141<div class="codehilite"><pre><span></span><code><span class="nn">...</span>
142
143<span class="nt">volumes</span><span class="p">:</span>
144 <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">maildata:/var/mail</span>
145 <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">mailstate:/var/mail-state</span>
146 <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">./config/:/tmp/docker-mailserver/</span>
147 <span class="p p-Indicator">-</span> <span class="l l-Scalar l-Scalar-Plain">/etc/letsencrypt:/etc/letsencrypt</span>
148
149<span class="nn">...</span>
150</code></pre></div>
151
152<p>With this done, you shouldn’t have mail clients complaining about
153wonky certs for which you’ll have to add an exception manually.</p>
154
155<h3 id="why-would-you">Why would you…?</h3>
156
157<p>There are a few good reasons for this:</p>
158
159<h4 id="privacy">Privacy</h4>
160
161<p>No really, this is <em>the</em> best choice for truly private
162email. Not ProtonMail, not Tutanota. Sure, they claim so and I don’t
163dispute it. Quoting Drew Devault<sup class="footnote-ref" id="fnref-3"><a href="#fn-3">3</a></sup>,</p>
164
165<blockquote>
166 <p>Truly secure systems do not require you to trust the service provider.</p>
167</blockquote>
168
169<p>But you have to <em>trust</em> ProtonMail. They run open source software, but
170how can you really be sure that it isn’t a backdoored version of it?</p>
171
172<p>When you host your own mailserver, you truly own your email without having to rely on any
173third-party.
174This isn’t an attempt to spread FUD. In the end, it all depends on your
175threat model™.</p>
176
177<h4 id="decentralization">Decentralization</h4>
178
179<p>Email today is basically run by Google. Gmail has over 1.2 <em>billion</em>
180active users. That’s obscene.
181Email was designed to be decentralized but big corps swooped in and
182made it a product. They now control your data, and it isn’t unknown that
183Google reads your mail. This again loops back to my previous point, privacy.
184Decentralization guarantees privacy. When you control your mail, you subsequently
185control who reads it.</p>
186
187<h4 id="personalization">Personalization</h4>
188
189<p>Can’t ignore this one. It’s cool to have a custom email address to flex.</p>
190
191<p><code>x@icyphox.sh</code> vs <code>gabe.newell4321@gmail.com</code></p>
192
193<p>Pfft, this is no competition.</p>
194
195<div class="footnotes">
196<hr />
197<ol>
198<li id="fn-1">
199<p>My <a href="https://twitter.com/icyphox/status/1161648321548566528">tweet</a> of frustration. <a href="#fnref-1" class="footnoteBackLink" title="Jump back to footnote 1 in the text.">↩</a></p>
200</li>
201
202<li id="fn-2">
203<p><a href="https://github.com/tomav/docker-mailserver#generate-dkim-keys">Link</a> to step in the docs. <a href="#fnref-2" class="footnoteBackLink" title="Jump back to footnote 2 in the text.">↩</a></p>
204</li>
205
206<li id="fn-3">
207<p>From his <a href="https://drewdevault.com/2018/08/08/Signal.html">article</a> on why he doesn’t trust Signal. <a href="#fnref-3" class="footnoteBackLink" title="Jump back to footnote 3 in the text.">↩</a></p>
208</li>
209</ol>
210</div>
211
212 </div>
213 <hr />
214 <p class="muted">Questions or comments? Open an issue at <a href="https://github.com/icyphox/site">this repo</a>, or send a plain-text email to <a href="mailto:x@icyphox.sh">x@icyphox.sh</a>.</p>
215 <footer>
216 <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">
217 <img src="https://licensebuttons.net/l/by-nc-sa/4.0/80x15.png">
218 </a>
219 </footer>
220 </body>
221 </div>
222 </html>