Crockery - simple email hosting
What
- SMTP + IMAP email, plus bundled HTTP webmail client
- Devoted to the task of serving email for a single domain
- Can get its own valid TLS certificates via LE, or use supplied ones
- Built-in anti-spam & anti-virus measures
- Built-in DKIM support
- Built-in DMARC support
- Can tell you what DNS records you need, and check them for validity
- Multiple email accounts for your domain
- A "master" wildcard account (if desired)
- Simple import from GMail, etc
- Simple export to GMail, etc
- Nice fast search
- Interact with crockery with simple, natural-ish emails to do things
- SMTP TLS verification - enabled by default
- Try to email foo@shady.net - verification fails, email marked pending, fail in 7 days
- Crockery emails user, "Yo. We can't send this email securely. Here are your options:"
- User hits reply-to (goes to unique email address on same domain) saying what to do:
- Cancel
- Retry
- Send just this email
- Whitelist shady.net (pins certificate)
- What other interactions might we like?
What not
- JMAP. Not today.
- Bring your own X (where X is MTA, IMAP server, database, etc, etc)
- Multiple-domain support (maaaaaaaaaaaaybe later)
- CalDAV/Carddav (yet)
- Externally sourced accounts (yet)
- Sending email without having an account
- Managesieve (for now)
Why
Email architecture is really complicated, and setting up a mail server of your own is painful. Various projects exist to try to make it easier, eg:
- iRedMail
- docker-mailserver
- symbiosis
- ...
(Personally, I had some ansible recipes!)
Even among people who run their own websites, it's rare to run your own email. It's just too painful. Much of this pain is caused by ultra-configurable components that need to be orchestrated. Each has its own (remarkably obtuse) configuration language, and each can do far more than the common case for a small, single-domain site.
So, let's make a single binary where all you have to do is:
- Register a domain
- Upload some DNS records
- Run the binary
and it gives you a sensible email setup without any additional configuration!
If it has to share the domain with a HTTP server (quite common), allow the HTTP-specific parts of mail to be served via reverse proxying. This includes:
- activesync push notifications
- autodiscovery
Probably other stuff. Email is big, and just keeps getting bigger.
How
Building a binary
$ go build ur.gs/crockery/cmd/crockery
$ sudo setcap 'cap_net_bind_service=+ep' ./crockery
The second step allows crockery to bind to the various low-numbered ports it needs (25, 587, 149, 993) without running as root. Don't bother with it if you're going to be running crockery as root, e.g., as a container or a single- purpose system.
Initialize a new database
crockery init \
--domain <domain-name> \
--cert <cert-file> \
--key <key-file> \
--postmaster-password <password>
You can also provide the postmaster password in an environment variable:
CROCKERY_POSTMASTER_PASSWORD="<password>" crockery init --domain <domain-name> ---cert <cert-file> --key <key-file>
You can provide a custom database name with --db <filename>
:
crockery --db foo.db init --domain <domain-name> ---cert <cert-file> --key <key-file>
Run the server
./crockery run
Again, you can use --db <filename>
if the default of ./crockery.db
doesn't
suit. Crockery will load the configuration from the database and begin serving
mail based on it. Received emails are also stored in the same file.
Configuration
Mostly non-existent, aside from that listed above.
We'll need to have a few offline commands baked into the crockery
binary,
apart from init
as detailed above. Some ideas:
$ crockery change x y z (domain, user password, etc)
$ crockery reindex (throw away existing indexes, regenerate)
$ crockery whitelist tls <domain> (allow the domain to be sent to with insecure/no TLS)
$ crockery whitelist receipt <domain> (bypass antispam for this domain)
$ crockery blacklist receipt <domain> (no emails to be permitted from this domain
It's inconvenient for some of these functions to require the server to be offline, so we'll need to provide another configuration interface too.
I like sending emails to it.
Since we're going to need a HTTP server anyway, we could expose admin functions
using that, if logged in as postmaster. It could also expose an API that the
crockery X
commands could connect to, rather than hitting the store directly.
We can use the .well-known
integration to avoid the need to configure there,
too.