modern full-featured open source secure mail server for low-maintenance self-hosted email
Find a file
2024-12-21 09:44:11 +01:00
.github/workflows automatically install typescript into ./node_modules if missing during build 2024-04-24 19:48:01 +02:00
.go mox! 2023-01-30 14:27:06 +01:00
admin implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
apidiff move func PartStructure from webhook to queue, so it isn't tracked anymore for apidiff changes 2024-12-07 13:57:07 +01:00
autotls instead of using loglevel error for printing a warning, just log it as "warn" error level, and don't log message parsing errors as loglevel error 2024-12-07 19:07:16 +01:00
config add an option for the smtp delivery listener to enable/disable tls session tickets 2024-12-06 14:50:02 +01:00
dane use debug logging in tests 2024-05-10 15:51:48 +02:00
dkim only use constant strings in string formatting 2024-12-14 09:38:56 +01:00
dmarc switch to math/rand/v2 in most places 2024-11-29 13:45:19 +01:00
dmarcdb switch to math/rand/v2 in most places 2024-11-29 13:45:19 +01:00
dmarcrpt update to latest sherpats fixing typo in error message, handle absent dmarc "policy override" reason 2024-03-09 15:43:49 +01:00
dns admin: better handling of disabled mta-sts during self-check 2024-11-24 13:30:29 +01:00
dnsbl replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
dsn add a webapi and webhooks for a simple http/json-based api 2024-04-15 21:49:02 +02:00
http do not try to get a tls cert for autoconfig.<domain> at startup if there is no listener with autoconfig enabled 2024-12-07 20:28:52 +01:00
imapclient implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
imapserver only use constant strings in string formatting 2024-12-14 09:38:56 +01:00
iprev replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
junk junk filter: fix adjusting word counts after train/untrain 2024-12-07 16:53:53 +01:00
licenses add subcommand that prints licenses, and link to licenses from the webadmin/webaccount/webmail interfaces 2024-10-04 09:31:31 +02:00
message move checking whether a message needs smtputf8 (has utf8 in any of the header sections) to package message 2024-12-07 13:05:09 +01:00
metrics implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
mlog add metrics that track how many error/warn/info logging is happening 2024-12-06 15:07:42 +01:00
mox- instead of using loglevel error for printing a warning, just log it as "warn" error level, and don't log message parsing errors as loglevel error 2024-12-07 19:07:16 +01:00
moxio add a webapi and webhooks for a simple http/json-based api 2024-04-15 21:49:02 +02:00
moxvar include goversion used to compile mox in the mox version 2024-11-28 16:28:05 +01:00
mtasts use debug logging in tests 2024-05-10 15:51:48 +02:00
mtastsdb switch to math/rand/v2 in most places 2024-11-29 13:45:19 +01:00
publicsuffix replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
queue move func PartStructure from webhook to queue, so it isn't tracked anymore for apidiff changes 2024-12-07 13:57:07 +01:00
ratelimit add more documentation, examples with tests to illustrate reusable components 2023-12-14 20:20:17 +01:00
rfc get rid of some more gnulinuxisms 2024-09-14 20:53:21 +02:00
sasl tweak doucmentation for sasl and scram 2024-12-06 15:59:22 +01:00
scram tweak doucmentation for sasl and scram 2024-12-06 15:59:22 +01:00
smtp fix parsing message headers with addresses that need double quotes 2024-08-22 16:03:52 +02:00
smtpclient implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
smtpserver only use constant strings in string formatting 2024-12-14 09:38:56 +01:00
spf replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
store instead of using loglevel error for printing a warning, just log it as "warn" error level, and don't log message parsing errors as loglevel error 2024-12-07 19:07:16 +01:00
stub replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
subjectpass use shorter smtp.NewAddress() instead of smtp.Address{...} 2024-05-09 21:26:22 +02:00
testdata implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
tlsrpt smtpserver: add prometheus metric for failing starttls handshakes for incoming deliveries 2024-11-29 12:43:21 +01:00
tlsrptdb add debug logging about bstore db schema upgrades 2024-05-10 14:44:37 +02:00
tlsrptsend switch to math/rand/v2 in most places 2024-11-29 13:45:19 +01:00
updates replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
vendor update to golang.org/x/net/html (slow parsing fixed) and other golang.org/x deps 2024-12-21 09:44:11 +01:00
webaccount add Content-Disposition and Filename to the payload of incoming webhooks 2024-12-06 14:19:39 +01:00
webadmin try clarifying that aliases are lists, not to be used for simply adding an address to an account 2024-12-07 19:10:02 +01:00
webapi add Content-Disposition and Filename to the payload of incoming webhooks 2024-12-06 14:19:39 +01:00
webapisrv move func PartStructure from webhook to queue, so it isn't tracked anymore for apidiff changes 2024-12-07 13:57:07 +01:00
webauth when login sessions to admin/account/webmail interfaces expiry or are no longer valid, explain the behaviour in the message 2024-08-23 14:48:45 +02:00
webhook move func PartStructure from webhook to queue, so it isn't tracked anymore for apidiff changes 2024-12-07 13:57:07 +01:00
webmail webmail: move 2 config options from localstorage to the settings popup, storing their values on the server 2024-12-07 12:32:54 +01:00
webops webmail: add export functionality 2024-04-22 13:41:40 +02:00
website add v0.0.13 to website 2024-11-06 23:20:44 +01:00
.dockerignore don't pass git history to docker container builds 2023-07-03 09:12:25 +02:00
.gitignore new website for www.xmox.nl 2024-01-10 17:22:03 +01:00
.jshintrc improve webserver, add domain redirects (aliases), add tests and admin page ui to manage the config 2023-03-02 18:15:54 +01:00
apidiff.sh move func PartStructure from webhook to queue, so it isn't tracked anymore for apidiff changes 2024-12-07 13:57:07 +01:00
backup.go implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
compatibility.txt add notes on tests with microsoft outlook. 2023-02-05 17:54:00 +01:00
ctl.go mox retrain: make the parameter, for account, optional and retrain all accounts when absent 2024-12-07 17:00:00 +01:00
ctl_test.go implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
develop.txt tweak docs for release process 2024-10-06 13:07:11 +02:00
doc.go quickstart: write all output to a file "quickstart.log" for later reference 2024-12-07 21:14:43 +01:00
docker-compose-imaptest.yml change "mox setaccountpassword" to use an account name as parameter, not email address 2023-09-23 17:18:49 +02:00
docker-compose-integration.yml more strict junk checks for some first-time senders: when TLS isn't used and when recipient address isn't in To/Cc header 2023-11-27 10:34:01 +01:00
docker-compose.yml help user run "mox localserve" using docker 2023-12-11 15:56:29 +01:00
docker-release.sh replace use of docker registry docker.io (hub.docker.com) with self-hosted r.xmox.nl 2023-03-20 09:35:49 +01:00
Dockerfile add timezone db files to docker images 2023-03-07 16:53:55 +01:00
Dockerfile.imaptest help run mox with docker 2023-02-24 14:16:51 +01:00
Dockerfile.moximaptest help run mox with docker 2023-02-24 14:16:51 +01:00
Dockerfile.release fix cross-compiled docker images 2023-02-27 13:46:29 +01:00
examples.go add a webapi and webhooks for a simple http/json-based api 2024-04-15 21:49:02 +02:00
export.go add debug logging about bstore db schema upgrades 2024-05-10 14:44:37 +02:00
gendoc.sh get rid of some more gnulinuxisms 2024-09-14 20:53:21 +02:00
genlicenses.sh add subcommand that prints licenses, and link to licenses from the webadmin/webaccount/webmail interfaces 2024-10-04 09:31:31 +02:00
gentestdata.go implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
gents.sh don't use bash if not needed 2024-02-11 21:46:45 +01:00
genwebsite.sh on build page, mention that changes can be tested easily with mox localserve 2024-03-17 07:58:02 +01:00
go.mod update to golang.org/x/net/html (slow parsing fixed) and other golang.org/x deps 2024-12-21 09:44:11 +01:00
go.sum update to golang.org/x/net/html (slow parsing fixed) and other golang.org/x deps 2024-12-21 09:44:11 +01:00
import.go mention that imported messages are not deduplicated 2024-06-24 11:46:50 +02:00
integration_test.go replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
junk.go switch to math/rand/v2 in most places 2024-11-29 13:45:19 +01:00
lib.ts add a webapi and webhooks for a simple http/json-based api 2024-04-15 21:49:02 +02:00
LICENSE.MIT mox! 2023-01-30 14:27:06 +01:00
LICENSE.MPLv2.0 mox! 2023-01-30 14:27:06 +01:00
licenses.go add missing file from previous commit 2024-10-04 09:34:37 +02:00
localserve.go move config-changing code from package mox-/ to admin/ 2024-12-02 22:03:18 +01:00
main.go try clarifying that aliases are lists, not to be used for simply adding an address to an account 2024-12-07 19:10:02 +01:00
Makefile add subcommand that prints licenses, and link to licenses from the webadmin/webaccount/webmail interfaces 2024-10-04 09:31:31 +02:00
metrics.go replace packages slog and slices from golang.org/x/exp with stdlib 2024-02-08 14:49:01 +01:00
mox.service log when mox root process cannot forward signals to unprivileged child 2024-11-21 21:59:36 +01:00
package-lock.json change javascript into typescript for webaccount and webadmin interface 2023-12-31 12:05:31 +01:00
package.json change javascript into typescript for webaccount and webadmin interface 2023-12-31 12:05:31 +01:00
profile.go add flag to mox to store execution trace, similar to cpu/memory profiling 2023-09-12 14:43:52 +02:00
prometheus.rules smtpserver: add prometheus metric for failing starttls handshakes for incoming deliveries 2024-11-29 12:43:21 +01:00
queue.go add a webapi and webhooks for a simple http/json-based api 2024-04-15 21:49:02 +02:00
quickstart.go quickstart: for -existing-webserver, also tls key/cert placeholder for mail.$domain 2024-12-08 10:18:57 +01:00
README.md added link to Matrix Chat Room 2024-11-01 12:11:10 +01:00
sendmail.go implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
serve.go implement tls client certificate authentication 2024-12-06 10:08:17 +01:00
serve_unix.go move config-changing code from package mox-/ to admin/ 2024-12-02 22:03:18 +01:00
serve_windows.go make mox compile on windows, without "mox serve" but with working "mox localserve" 2023-10-14 10:54:07 +02:00
test-upgrade.sh increase memory limit during tests for upgrade 2024-03-04 19:11:53 +01:00
tools.go add webmail 2023-08-07 21:57:03 +02:00
tsc.sh get rid of some more gnulinuxisms 2024-09-14 20:53:21 +02:00
unexpand.go get rid of some more gnulinuxisms 2024-09-14 20:53:21 +02:00
updates.go remove debug print 2023-04-24 10:06:59 +02:00
verifydata.go implement tls client certificate authentication 2024-12-06 10:08:17 +01:00

Mox is a modern full-featured open source secure mail server for low-maintenance self-hosted email.

For more details, see the mox website, https://www.xmox.nl.

See Quickstart below to get started.

Features

  • Quick and easy to start/maintain mail server, for your own domain(s).
  • SMTP (with extensions) for receiving, submitting and delivering email.
  • IMAP4 (with extensions) for giving email clients access to email.
  • Webmail for reading/sending email from the browser.
  • SPF/DKIM/DMARC for authenticating messages/delivery, also DMARC aggregate reports.
  • Reputation tracking, learning (per user) host-, domain- and sender address-based reputation from (Non-)Junk email classification.
  • Bayesian spam filtering that learns (per user) from (Non-)Junk email.
  • Slowing down senders with no/low reputation or questionable email content (similar to greylisting). Rejected emails are stored in a mailbox called Rejects for a short period, helping with misclassified legitimate synchronous signup/login/transactional emails.
  • Internationalized email, with unicode in email address usernames ("localparts"), and in domain names (IDNA).
  • Automatic TLS with ACME, for use with Let's Encrypt and other CA's.
  • DANE and MTA-STS for inbound and outbound delivery over SMTP with STARTTLS, including REQUIRETLS and with incoming/outgoing TLSRPT reporting.
  • Web admin interface that helps you set up your domains, accounts and list aliases (instructions to create DNS records, configure SPF/DKIM/DMARC/TLSRPT/MTA-STS), for status information, and modifying the configuration file.
  • Account autodiscovery (with SRV records, Microsoft-style, Thunderbird-style, and Apple device management profiles) for easy account setup (though client support is limited).
  • Webserver with serving static files and forwarding requests (reverse proxy), so port 443 can also be used to serve websites.
  • Simple HTTP/JSON API for sending transaction email and receiving delivery events and incoming messages (webapi and webhooks).
  • Prometheus metrics and structured logging for operational insight.
  • "mox localserve" subcommand for running mox locally for email-related testing/developing, including pedantic mode.
  • Most non-server Go packages mox consists of are written to be reusable.

Mox is available under the MIT-license and was created by Mechiel Lukkien, mechiel@ueber.net. Mox includes BSD-3-claused code from the Go Authors, and the Public Suffix List by Mozilla under Mozilla Public License, v2.0.

Mox has automated tests, including for interoperability with Postfix for SMTP. Mox is manually tested with email clients: Mozilla Thunderbird, mutt, iOS Mail, macOS Mail, Android Mail, Microsoft Outlook. Mox is also manually tested to interoperate with popular cloud providers: gmail.com, outlook.com, yahoo.com, proton.me.

The code is heavily cross-referenced with the RFCs for readability/maintainability.

Quickstart

The easiest way to get started with serving email for your domain is to get a (virtual) machine dedicated to serving email, name it [host].[domain] (e.g. mail.example.com). Having a DNSSEC-verifying resolver installed, such as unbound, is highly recommended. Run as root:

# Create mox user and homedir (or pick another name or homedir):
useradd -m -d /home/mox mox

cd /home/mox
... compile or download mox to this directory, see below ...

# Generate config files for your address/domain:
./mox quickstart you@example.com

The quickstart:

  • Creates configuration files mox.conf and domains.conf.
  • Adds the domain and an account for the email address to domains.conf
  • Generates an admin and account password.
  • Prints the DNS records you need to add, for the machine and domain.
  • Prints commands to start mox, and optionally install mox as a service.

A machine that doesn't already run a webserver is highly recommended because modern email requires HTTPS, and mox currently needs to run a webserver for automatic TLS with ACME. You could combine mox with an existing webserver, but it requires a lot more configuration. If you want to serve websites on the same machine, consider using the webserver built into mox. It's pretty good! If you want to run an existing webserver on port 443/80, see mox help quickstart.

After starting, you can access the admin web interface on internal IPs.

Download

Download a mox binary from https://beta.gobuilds.org/github.com/mjl-/mox@latest/linux-amd64-latest/.

Symlink or rename it to "mox".

The URL above always resolves to the latest release for linux/amd64 built with the latest Go toolchain. See the links at the bottom of that page for binaries for other platforms.

Compiling

You can easily (cross) compile mox yourself. You need a recent Go toolchain installed. Run go version, it must be >= 1.22. Download the latest version from https://go.dev/dl/ or see https://go.dev/doc/manage-install.

To download the source code of the latest release, and compile it to binary "mox":

GOBIN=$PWD CGO_ENABLED=0 go install github.com/mjl-/mox@latest

Mox only compiles for and fully works on unix systems. Mox also compiles for Windows, but "mox serve" does not yet work, though "mox localserve" (for a local test instance) and most other subcommands do. Mox does not compile for Plan 9.

Docker

Although not recommended, you can also run mox with docker image r.xmox.nl/mox, with tags like v0.0.1 and v0.0.1-go1.20.1-alpine3.17.2, see https://r.xmox.nl/r/mox/. See https://github.com/mjl-/mox/blob/main/docker-compose.yml to get started.

New docker images aren't (automatically) generated for new Go runtime/compile releases.

It is important to run with docker host networking, so mox can use the public IPs and has correct remote IP information for incoming connections (important for junk filtering and rate-limiting).

Future/development

See develop.txt for instructions/tips for developing on mox.

Mox will receive funding for essentially full-time continued work from August 2023 to August 2024 through NLnet/EU's NGI0 Entrust, see https://nlnet.nl/project/Mox/.

Roadmap

  • Calendaring with CalDAV/iCal
  • More IMAP extensions (PREVIEW, WITHIN, IMPORTANT, COMPRESS=DEFLATE, CREATE-SPECIAL-USE, SAVEDATE, UNAUTHENTICATE, REPLACE, QUOTA, NOTIFY, MULTIAPPEND, OBJECTID, MULTISEARCH, THREAD, SORT)
  • SMTP DSN extension
  • "mox setup" command, with webapp for interactive setup
  • Introbox, to which first-time senders are delivered
  • ARC, with forwarded email from trusted source
  • Forwarding (to an external address)
  • Add special IMAP mailbox ("Queue?") that contains queued but undelivered messages, updated with IMAP flags/keywords/tags and message headers.
  • External addresses in aliases/lists.
  • Autoresponder (out of office/vacation)
  • OAUTH2 support, for single sign on
  • IMAP extensions for "online"/non-syncing/webmail clients (SORT (including DISPLAYFROM, DISPLAYTO), THREAD, PARTIAL, CONTEXT=SEARCH CONTEXT=SORT ESORT, FILTERS)
  • Improve support for mobile clients with extensions: IMAP URLAUTH, SMTP CHUNKING and BINARYMIME, IMAP CATENATE
  • Mailing list manager
  • Privilege separation, isolating parts of the application to more restricted sandbox (e.g. new unauthenticated connections)
  • Using mox as backup MX
  • JMAP
  • Sieve for filtering (for now see Rulesets in the account config)
  • Milter support, for integration with external tools
  • IMAP Sieve extension, to run Sieve scripts after message changes (not only new deliveries)

There are many smaller improvements to make as well, search for "todo" in the code.

Not supported/planned

There is currently no plan to implement the following. Though this may change in the future.

  • Functioning as SMTP relay
  • POP3
  • Delivery to (unix) OS system users
  • Support for pluggable delivery mechanisms
  • iOS Mail push notifications (with XAPPLEPUSHSERVICE undocumented imap extension and hard to get APNS certificate)

FAQ - Frequently Asked Questions

Why a new mail server implementation?

Mox aims to make "running a mail server" easy and nearly effortless. Excellent quality (open source) mail server software exists, but getting a working setup typically requires you configure half a dozen services (SMTP, IMAP, SPF/DKIM/DMARC, spam filtering), which are often written in C (where small bugs often have large consequences). That seems to lead to people no longer running their own mail servers, instead switching to one of the few centralized email providers. Email with SMTP is a long-time decentralized messaging protocol. To keep it decentralized, people need to run their own mail server. Mox aims to make that easy.

Where is the documentation?

To keep mox as a project maintainable, documentation is integrated into, and generated from the code.

A list of mox commands, and their help output, are at https://www.xmox.nl/commands/.

Mox is configured through configuration files, and each field comes with documentation. See https://www.xmox.nl/config/ for config files containing all fields and their documentation.

You can get the same information by running "mox" without arguments to list its subcommands and usage, and "mox help [subcommand]" for more details.

The example config files are printed by "mox config describe-static" and "mox config describe-dynamic".

If you're missing some documentation, please create an issue describing what is unclear or confusing, and we'll try to improve the documentation.

Is Mox affected by SMTP smuggling?

Mox itself is not affected: it only treats "\r\n.\r\n" as SMTP end-of-message. But read on for caveats.

SMTP smuggling exploits differences in handling by SMTP servers of: carriage returns (CR, or "\r"), newlines (line feeds, LF, "\n") in the context of "dot stuffing". SMTP is a text-based protocol. An SMTP transaction to send a message is finalized with a "\r\n.\r\n" sequence. This sequence could occur in the message being transferred, so any verbatim "." at the start of a line in a message is "escaped" with another dot ("dot stuffing"), to not trigger the SMTP end-of-message. SMTP smuggling takes advantage of bugs in some mail servers that interpret other sequences than "\r\n.\r\n" as SMTP end-of-message. For example "\n.\n" or even "\r.\r", and perhaps even other magic character combinations.

Before v0.0.9, mox accepted SMTP transactions with bare carriage returns (without newline) for compatibility with real-world email messages, considering them meaningless and therefore innocuous.

Since v0.0.9, SMTP transactions with bare carriage returns are rejected. Sending messages with bare carriage returns to buggy mail servers can cause those mail servers to materialize non-existent messages. Now that mox rejects messages with bare carriage returns, sending a message through mox can no longer be used to trigger those bugs.

Mox can still handle bare carriage returns in email messages, e.g. those imported from mbox files or Maildirs, or from messages added over IMAP. Mox still fixes up messages with bare newlines by adding the missing carriage returns.

Before v0.0.9, an SMTP transaction for a message containing "\n.\n" would result in a non-specific error message, and "\r\n.\n" would result in the dot being dropped. Since v0.0.9, these sequences are rejected with a message mentioning SMTP smuggling.

How do I import/export email?

Use the import functionality on the accounts web page to import a zip/tgz with maildirs/mbox files, or use the "mox import maildir" or "mox import mbox" subcommands. You could also use your IMAP email client, add your mox account, and copy or move messages from one account to the other.

Similarly, see the export functionality on the accounts web page and the "mox export maildir" and "mox export mbox" subcommands to export email.

Importing large mailboxes may require a lot of memory (a limitation of the current database). Splitting up mailboxes in smaller parts (e.g. 100k messages) would help.

How can I help?

Mox needs users and testing in real-life setups! So just give it a try, send and receive emails through it with your favourite email clients, and file an issue if you encounter a problem or would like to see a feature/functionality implemented.

Instead of switching email for your domain over to mox, you could simply configure mox for a subdomain, e.g. [you]@moxtest.[yourdomain].

If you have experience with how the email protocols are used in the wild, e.g. compatibility issues, limitations, anti-spam measures, specification violations, that would be interesting to hear about.

Pull requests for bug fixes and new code are welcome too. If the changes are large, it helps to start a discussion (create an "issue") before doing all the work. In practice, starting with a small contribution and growing from there has the highest chance of success.

By contributing (e.g. code), you agree your contributions are licensed under the MIT license (like mox), and have the rights to do so.

Where can I discuss mox?

Join #mox on irc.oftc.net, or #mox:matrix.org (https://matrix.to/#/#mox:matrix.org), or #mox on the "Gopher slack".

For bug reports, please file an issue at https://github.com/mjl-/mox/issues/new.

How do I change my password?

Regular users (doing IMAP/SMTP with authentication) can change their password at the account page, e.g. http://localhost/. Or you can set a password with "mox setaccountpassword".

The admin can change the password of any account through the admin page, at http://localhost/admin/ by default (leave username empty when logging in).

The account and admin pages are served on localhost for configs created with the quickstart. To access these from your browser, run ssh -L 8080:localhost:80 you@yourmachine locally and open http://localhost:8080/[...].

The admin password can be changed with "mox setadminpassword".

How do I configure a second mox instance as a backup MX?

Unfortunately, mox does not yet provide an option for that. Mox does spam filtering based on reputation of received messages. It will take a good amount of work to share that information with a backup MX. Without that information, spammers could use a backup MX to get their spam accepted.

Until mox has a proper solution, you can simply run a single SMTP server. The author has run a single mail server for over a decade without issues. Machines and network connectivity are stable nowadays, and email delivery will be retried for many hours during temporary errors (e.g. when rebooting a machine after updates).

How do I stay up to date?

Please set "CheckUpdates: true" in mox.conf. Mox will check for a new version through a DNS TXT request for _updates.xmox.nl once per 24h. Only if a new version is published will the changelog be fetched and delivered to the postmaster mailbox.

The changelog, including latest update instructions, is at https://updates.xmox.nl/changelog.

You can also monitor newly added releases on this repository with the github "watch" feature, or use the github RSS feed for tags (https://github.com/mjl-/mox/tags.atom) or releases (https://github.com/mjl-/mox/releases.atom), or monitor the docker images.

Keep in mind you have a responsibility to keep the internet-connected software you run up to date and secure.

How do I upgrade my mox installation?

We try to make upgrades effortless and you can typically just put a new binary in place and restart. If manual actions are required, the release notes mention them. Check the release notes of all version between your current installation and the release you're upgrading to.

Before upgrading, make a backup of the data directory with mox backup <destdir>. This writes consistent snapshots of the database files, and duplicates message files from the outgoing queue and accounts. Using the new mox binary, run mox verifydata <backupdir> (do NOT use the "live" data directory!) for a dry run. If this fails, an upgrade will probably fail too. Important: verifydata with the new mox binary can modify the database files (due to automatic schema upgrades). So make a fresh backup again before the actual upgrade. See the help output of the "backup" and "verifydata" commands for more details.

During backup, message files are hardlinked if possible, and copied otherwise. Using a destination directory like data/tmp/backup increases the odds hardlinking succeeds: the default mox systemd service file mounts the data directory separately, so hardlinks to outside the data directory are cross-device and will fail.

If an upgrade fails and you have to restore (parts) of the data directory, you should run mox verifydata <datadir> (with the original binary) on the restored directory before starting mox again. If problematic files are found, for example queue or account message files that are not in the database, run mox verifydata -fix <datadir> to move away those files. After a restore, you may also want to run mox bumpuidvalidity <account> for each account for which messages in a mailbox changed, to force IMAP clients to synchronize mailbox state.

How secure is mox?

Security is high on the priority list for mox. Mox is young, so don't expect no bugs at all. Mox does have automated tests for some security aspects, e.g. for login, and uses fuzzing. Mox is written in Go, so some classes of bugs such as buffer mishandling do not typically result in privilege escalation. Of course logic bugs will still exist. If you find any security issues, please email them to mechiel@ueber.net.

I'm now running an email server, but how does email work?

Congrats and welcome to the club! Running an email server on the internet comes with some responsibilities so you should understand how it works. See https://explained-from-first-principles.com/email/ for a thorough explanation.

What are the minimum requirements to run mox?

Mox does not need much. Nowadays most machines are larger than mox needs. You can start with a machine with 512MB RAM, any CPU will do. For storage you should account for the size of the email messages (no compression currently), an additional 15% overhead for the meta data, and add some more headroom. Expand as necessary.

Won't the big email providers block my email?

It is a common misconception that it is impossible to run your own email server nowadays. The claim is that the handful big email providers will simply block your email. However, you can run your own email server just fine, and your email will be accepted, provided you are doing it right.

If your email is rejected, it is often because your IP address has a bad email sending reputation. Email servers often use IP blocklists to reject email networks with a bad email sending reputation. These blocklists often work at the level of whole network ranges. So if you try to run an email server from a hosting provider with a bad reputation (which happens if they don't monitor their network or don't act on abuse/spam reports), your IP too will have a bad reputation and other mail servers (both large and small) may reject messages coming from you. During the quickstart, mox checks if your IPs are on a few often-used blocklists. It's typically not a good idea to host an email server on the cheapest or largest cloud providers: They often don't spend the resources necessary for a good reputation, or they simply block all outgoing SMTP traffic. It's better to look for a technically-focused local provider. They too may initially block outgoing SMTP connections on new machines to prevent spam from their networks. But they will either automatically open up outgoing SMTP traffic after a cool down period (e.g. 24 hours), or after you've contacted their support.

After you get past the IP blocklist checks, email servers use many more signals to determine if your email message could be spam and should be rejected. Mox helps you set up a system that doesn't trigger most of the technical signals (e.g. with SPF/DKIM/DMARC). But there are more signals, for example: Sending to a mail server or address for the first time. Sending from a newly registered domain (especially if you're sending automated messages, and if you send more messages after previous messages were rejected), domains that existed for a few weeks to a month are treated more friendly. Sending messages with content that resembles known spam messages.

Should your email be rejected, you will typically get an error message during the SMTP transaction that explains why. In the case of big email providers the error message often has instructions on how to prove to them you are a legitimate sender.

Can mox deliver through a smarthost?

Yes, you can configure a "Transport" in mox.conf and configure "Routes" in domains.conf to send some or all messages through the transport. A transport can be an SMTP relay or authenticated submission, or making mox make outgoing connections through a SOCKS proxy.

For an example, see https://www.xmox.nl/config/#hdr-example-transport. For details about Transports and Routes, see https://www.xmox.nl/config/#cfg-mox-conf-Transports and https://www.xmox.nl/config/#cfg-domains-conf-Routes.

Remember to add the IP addresses of the transport to the SPF records of your domains. Keep in mind some 3rd party submission servers may mishandle your messages, for example by replacing your Message-Id header and thereby invalidating your DKIM-signatures, or rejecting messages with more than one DKIM-signature.

Can I use mox to send transactional email?

Yes. While you can use SMTP submission to send messages you've composed yourself, and monitor a mailbox for DSNs, a more convenient option is to use the mox HTTP/JSON-based webapi and webhooks.

The mox webapi can be used to send outgoing messages that mox composes. The web api can also be used to deal with messages stored in an account, like changing message flags, retrieving messages in parsed form or individual parts of multipart messages, or moving messages to another mailbox or deleting messages altogether.

Mox webhooks can be used to receive updates about incoming and outgoing deliveries. Mox can automatically manage per account suppression lists.

See https://www.xmox.nl/features/#hdr-webapi-and-webhooks for details.

Can I use existing TLS certificates/keys?

Yes. The quickstart command creates a config that uses ACME with Let's Encrypt, but you can change the config file to use existing certificate and key files.

You'll see "ACME: letsencrypt" in the "TLS" section of the "public" Listener. Remove or comment out the ACME-line, and add a "KeyCerts" section, see https://www.xmox.nl/config/#cfg-mox-conf-Listeners-x-TLS-KeyCerts

You can have multiple certificates and keys: The line with the "-" (dash) is the start of a list item. Duplicate that line up to and including the line with KeyFile for each certificate/key you have. Mox makes a TLS config that holds all specified certificates/keys, and uses it for all services for that Listener (including a webserver), choosing the correct certificate for incoming requests.

Keep in mind that for each email domain you host, you will need a certificate for mta-sts.<domain>, autoconfig.<domain> and mail.<domain>, unless you disable MTA-STS, autoconfig and the client-settings-domain for that domain.

Mox opens the key and certificate files during initial startup, as root (and passes file descriptors to the unprivileged process). No special permissions are needed on the key and certificate files.

Can I directly access mailboxes through the file system?

No, mox only provides access to email through protocols like IMAP.

While it can be convenient for users/email clients to access email through conventions like Maildir, providing such access puts quite a burden on the server: The server has to continuously watch for changes made to the mail store by external programs, and sync its internal state. By only providing access to emails through mox, the storage/state management is simpler and easier to implement reliably.

Not providing direct file system access also allows future improvements in the storage mechanism. Such as encryption of all stored messages. Programs won't be able to access such messages directly.

Mox stores metadata about delivered messages in its per-account message index database, more than fits in a simple (filename-based) format like Maildir. The IP address of the remote SMTP server during delivery, SPF/DKIM/DMARC domains and validation status, and more...

For efficiency, mox doesn't prepend message headers generated during delivery (e.g. Authentication-Results) to the on-disk message file, but only stores it in the database. This prevents a rewrite of the entire message file. When reading a message, mox combines the prepended headers from the database with the message file.

Mox user accounts have no relation to operating system user accounts. Multiple system users reading their email on a single machine is not very common anymore. All data (for all accounts) stored by mox is accessible only by the mox process. Messages are currently stored as individual files in standard Internet Message Format (IMF), at data/accounts/<account>/msg/<dir>/<msgid>: msgid is a consecutive unique integer id assigned by the per-account message index database; dir groups 8k consecutive message ids into a directory, ensuring they don't become too large. The message index database file for an account is at data/accounts/<account>/index.db, accessed with the bstore database library, which uses bbolt (formerly BoltDB) for storage, a transactional key/value library/file format inspired by LMDB.