Moving to my own email server
2017-08-03
There I was, a loyal user of http://mail.zoho.com, when I decided to download all of my emails. For archival purposes, you know.
So I fired up mbsync, set everything up, let 'er rip, but after only about 10,000 emails downloaded, I got this error:
IMAP command 'AUTHENTICATE PLAIN <authdata>' returned an error: NO [ALERT] Your account is currently not accessible via IMAP due to excessive usage. Kindly try after some time.
*** IMAP ALERT *** Your account is currently not accessible via IMAP due to excessive usage. Kindly try after some time.
What sort of...anyway, this was unacceptable, so I decided to set up my web server as a mail server.
Prerequisites
Everything you need to run a mail server is already installed on
OpenBSD. Of course, if you want to use DKIM (and you really do, or
your mail will be sent to spam or just not received by anyone), you
need to install dkimproxy
.
$ doas pkg_add dkimproxy
That's basically it.
Setting up OpenSMTPD
OpenSMTPD has a pf-inspired config file. That is to say, it's very easy to grok.
Step 1: Set up an SSL certificate
This is very easy with acme-client
, which comes with OpenBSD.
Your /etc/acme-client.conf
should already have the letsencrypt
authorities in it, so you just need to add your domain to the bottom.
It's so easy, look at man acme-client.conf
. For reference, here is
my domain entry:
domain earendil.kaashif.co.uk {
alternative names { kaashif.co.uk git.kaashif.co.uk
www.kaashif.co.uk mail.kaashif.co.uk }
domain key "/etc/ssl/private/earendil.kaashif.co.uk.key"
domain certificate "/etc/ssl/earendil.kaashif.co.uk.crt"
domain full chain certificate "/etc/ssl/earendil.kaashif.co.uk.fullchain.pem"
sign with letsencrypt
}
Then you run acme-client -vFAD earendil.kaashif.co.uk
as the man page
suggests and everything will Just Work, with your new certificates
ending up where you specified.
Put that command in /etc/monthly.local
and it will run every month,
keeping everything valid and non-expired.
Step 2: Set up your virtual users
My mail server will be single user, so I just slapped this into
/etc/mail/virtuals
:
kaashif@mail.kaashif.co.uk kaashif
I don't even think you really need it, but in the future you may want to add a webmaster email, or mailing lists for specific projects, etc, so its good to have it.
Although you didn't add anything to /etc/mail/aliases
, you should
still run newaliases
just to generate the aliases.db
that
OpenSMTPD uses.
Step 3: /etc/mail/smtpd.conf
This is the big one, where the magic happens.
Actually, this file is so simple, I can just dump it here and explain it:
pki mail.kaashif.co.uk certificate "/etc/ssl/earendil.kaashif.co.uk.crt"
pki mail.kaashif.co.uk key "/etc/ssl/private/earendil.kaashif.co.uk.key"
These are the letsencrypt certs you made earlier that smtpd will use.
table aliases file:/etc/mail/aliases
table virtuals file:/etc/mail/virtuals
This declares the tables so you can use them later on in the file as
<aliases>
and <virtuals>
.
listen on all
listen on all port 10028 tag DKIM
This requires some explanation. We listen on all interfaces on the
usual smtp ports for mail (this is where mailservers will send us
mail). But on port 10028, we listen for mail tagged DKIM. This is
where dkimproxy
comes in.
When we send mail from this server, we want it signed with DKIM. So
the dkimproxy_out
daemon listens on port 10027, we send it mail and
it sends it back (signed) on port 10028 and the session has a DKIM
tag.
accept from any for domain "mail.kaashif.co.uk" virtual <virtuals> deliver to mda "/usr/local/bin/procmail"
Procmail is a well-known mail filtering agent. Explaining how to
configure it is out of the scope of this post, but basically you just
make a ~/.procmailrc
in the users' home and put some rules in
there. Where the mail ends up (mailbox, maildir, somewhere else) is
entirely up to Procmail, smtpd forgets about it after that.
accept from local for local alias <aliases> deliver to mbox
We don't want to mix local and non-local mail, so all that local-only
daily output and insecurity output will end up in our normal mbox in
/var/mail
. But of course, there's nothing stopping you from
configuring Procmail to put some non-local mail in /var/mail
too.
accept tagged DKIM for any relay
accept from local for any relay via smtp://127.0.0.1:10027
The only sessions that will ever be tagged DKIM are ones made by
dkimproxy
. So it is safe to just relay them all. Any mail sent from
here is sent to dkimproxy
on port 10027, to be signed and returned
later.
Setting up DKIM and SPF
Step 1: Generating a key
DKIM works by signing messages with a private key stored locally. Then untrusting mail servers get the public key from a DNS TXT record and check the signature. We don't have any keys yet.
$ mkdir -p /etc/mail/dkim
$ cd /etc/mail/dkim
$ openssl genrsa -out private.key 1024
$ openssl rsa -in private.key -pubout -out public.key
Why only 1024 bits? Because that's all that fits in a single TXT record, it's a bit incovenient otherwise.
Now, make those readable by dkimproxy and no-one else:
$ chmod 0600 *.key
$ chown _dkimproxy:_dkimproxy *.key
Now edit /etc/dkimproxy_out.conf
's keyfile
line to point to the
private key you just made:
keyfile /etc/mail/dkim/private.key
Step 2: Putting everything into DNS
This is important since people will have no idea how to verify your sigs if they don't know your public key.
Make a record on selector1._domainkey.your.domain.tld
, type TXT,
with the following content:
v=DKIM1; k=rsa; p=<your public key>
When I say your public key, I mean go to your public key file, ignore the header and footer lines, concatenate each line then paste it there.
Also take the opportunity to set up SPF. Add a TXT record to
your.domain.tld
, with:
v=spf1 a mx ip4:<your ip address> ~all
Where your IP address is your static IP. If you don't have a static IP address, you'll probably forever be on every spam list ever. Contact your ISP to get a static IP, or get a VPS.
Final touches
Now just start everything:
$ rcctl enable dkimproxy_out
$ rcctl restart dkimproxy_out smtpd
And everything should work!
But now you wonder how I read mail? Easy, I SSH in and use mutt. Couldn't be any simpler.
But how do I check it on my phone? Dude, I just told you! SSH and
mutt. I can use mail(1)
if I really can't deal with a complicated
TUI.
To my surprise, everything worked. http://www.mail-tester.com gave me a clean bill of health and I found my mails were able to reach all my friends and family.
And no arbitrary usage limits! I can download my many gigabytes of mail as many times as I want!
But of course, I do have to still download them from Zoho to upload them to my new server...