Files
crockery/README.md

4.6 KiB

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.
  • Maildir/mbox support. Imports and exports via IMAP, backups by "copy this file"
  • Bring your own X (where X is MTA, IMAP server, database, etc, etc)
  • Multiple-domain support (maybe 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.