Simple self-hosted email
Not all features are implemented. See the features board for more details of current status.
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:
(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:
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:
Probably other stuff. Email is big, and just keeps getting bigger.
Copyright (C) 2018 Nick Thomas email@example.com
This program is free software: you can redistribute it and/or modify it under the terms of version 3 of the GNU Affero General Public License as published by the Free Software Foundation.
This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public License for more details.
You should have received a copy of the GNU Affero General Public License along with this program. If not, see https://www.gnu.org/licenses/.
Contributions are very welcome. Feel free to open a merge request against the GitLab hosted project, or to email patches or a link to a hosted git branch, directly to the author.
To be accepted, contributions must:
Signed-off-by:line in each commit message
$ 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.
You may also provide these capabilities via systemd by using lines like these in
CapabilityBoundingSet=CAP_NET_BIND_SERVICE AmbientCapabilities=CAP_NET_BIND_SERVICE NoNewPrivileges=true
If you're doing this, you may also want to set:
PrivateTmp=true PrivateDevices=true ProtectHome=true ProtectSystem=full ReadWriteDirectories=/var/lib/caddy
TODO: write up a .service file that can be dropped in
$ 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>
By default, crockery will initialize the current user's home directory. You can
provide a custom directory to work with by specifying
$ crockery \ --home <home-directory> \ init \ --domain <domain-name> \ --cert <cert-file> \ --key <key-file> \ --postmaster-password <password>
Again, you can use
--home <directory> if the default of
$HOME doesn't suit.
Crockery will load the configuration from the database and begin serving mail
based on it. Received emails are stored in a mailbox determined by the username,
to be found in the
Mostly non-existent, aside from that listed above.
We'll need to have a few offline commands baked into the
init as detailed above. Some ideas:
$ crockery change x y z (domain, user password, etc) $ crockery reindex [account] (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,