# 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.
