Code Monkey home page Code Monkey logo

mox's Introduction

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, [email protected]. 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 [email protected]

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.21. 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, 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 [email protected].

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.

mox's People

Contributors

belst avatar bobobo1618 avatar kou029w avatar lmeunier avatar mattfbacon avatar mjl- avatar mpldr avatar sehaas avatar tkivisik avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

mox's Issues

anti-featurerequest: don't add PGP/S-MIME signing

Since this is in the README

PGP or S/MIME

I just wanted to add my 2¢ and ask you not to do this. This absolutely defeats the purpose of signing outgoing mail and supports misbehaviours that some might be used to because of Exchange.

Why are messages signed? To guarantee to a degree not only that a person has access to a mailaccount, but that it is in fact the owner of a mailbox who's writing. Signing this on a server level obviously removes this and just adds a client-visible DKIM.

errors referencing existing addresses from v0.0.1 when adding new account on v0.0.4

I migrated from 0.0.1 to 0.0.4 and the first time I tried to add a new account I got multiple instances of this error, each for one of the existing mail accounts I had set up. The instance below is for my primary address, sherief at sherief dot fyi:

error: "deprecated: destination with localpart-only key will be removed in the future, replace it with a full email address, by appending the default domain" (pkg: mox; localpart: sherief; address: [email protected]; account: sherief)

I'm not sure what this means, or what's actionable on my part here. Any guidance?

Cannot connect with Microsoft outlook

Great email server, thank you. The reason I am writing here is that I had been having issues while connecting with Microsoft outlook. I have tried many things, but could not manage to connect. Apple mail works fine, other imap, smtp clients connect and work smoothly.

The error message I get on the Microsoft Outlook Client is as follows:

We couldn't connect to the outgoing (SMTP) server. Please check your email address and password and try again.

Here is the log the server outputs while trying to connect with outlook.

l=info m="new connection" pkg=imapserver remote=███.███.███.███:52746 local=███.███.███.███:993 tls=true listener=public cid=189998ea1b8 delta="30.911µs"
l=debug m="imap command done" pkg=imapserver cmd=capability duration="47.831µs" cid=189998ea1b8 delta=158.584929ms
l=debug m="imap command done" pkg=imapserver cmd=login duration=2.176562ms cid=189998ea1b8 delta=72.130866ms username=████████@████████.██
l=debug m="imap command done" pkg=imapserver cmd=enable duration="55.851µs" cid=189998ea1b8 delta=73.566251ms username=████████@████████.██
l=info m="imap command ioerror" err="get line: unexpected EOF (fatal io error)" pkg=imapserver cmd=idle duration="104.943µs" cid=189998ea1b8 delta=78.136528ms username=████████@████████.██
l=info m="connection closed" err="get line: unexpected EOF (fatal io error)" pkg=imapserver cid=189998ea1b8 delta="150.823µs" username=████████@████████.██
l=info m="new connection" pkg=smtpserver remote=███.███.███.███:52747 local=███.███.███.███:465 submission=true tls=true listener=public cid=189998ea1b9 delta="46.041µs"
l=debug m="smtp command result" pkg=smtpserver kind=submission cmd=ehlo code=250 ecode= duration="22.631µs" cid=189998ea1b9 delta=173.304877ms
l=debug m="smtp command result" pkg=smtpserver kind=submission cmd=auth code=235 ecode=2.7.0 duration=64.794801ms cid=189998ea1b9 delta=137.004119ms username=████████@████████.██
l=debug m="smtp command result" err="bad syntax: expected \"<\" (remaining \" <████████@████████.██>\")" pkg=smtpserver kind=submission cmd=mail code=501 ecode=5.5.2 duration="32.931µs" cid=189998ea1b9 delta=91.181126ms username=████████@████████.██
l=info m="connection closed" err="read: EOF (fatal io error)" pkg=smtpserver cid=189998ea1b9 delta=84.716772ms username=████████@████████.██
l=info m="connection closed" err="write: EOF (fatal io error)" pkg=imapserver cid=189998ea1ad delta=16m4.652620931s
l=info m="new connection" pkg=imapserver remote=███.███.███.███:57902 local=███.███.███.███:993 tls=true listener=public cid=189998ea1ba delta="28.871µs"

Any help is appreciated.

Feedback v0.0.3

Hi,

I've just migrated a couple of small domains from postfix+opendkim+dovecot to mox v0.0.3 (AMD64 binary).
The server runs Fedora 38. Mox is behid nginx (it proxies some complex sites: rainloop, nextcloud…), and I manage letsencrypt certificates by myself.
As the server installation is new I can't send emails for some weeks (provider's spam protection), so I haven't been able to test sending emails.

Configuration has been fairly easy, except my own mess with administration port (I was using autoconfig/mta-sms port). Perhaps it should be mentioned clearer that admin username is blank.
Anyway my main problem was that /etc/letsencrypt is owned by root:root, and mox reads the certificates after dropping root permissions to mox user, so I've had to chgrp some directories and files (cert and key).

I've successfully sent emails to different users of the configured domains.
IMAP also worked perfectly with these clients: mbsync, rainloop webmail, and Android's AquaMail app.

Some features I would appreciate:

  • Show username in logs for IMAP connections (info level and upper). For use in fail2ban-like programs.
  • Something like pflogsumm that generates daily/weekly/monthly reports/statistics which could also be sent by email
  • Calendaring server

Thanks a lot and congratulations for mox!

smtp may be too pedantic (for localserve)

Background: I'm trying to use mox localserve for testing Odoo's processing of both in- and outgoing mails - maybe not completely the intended use-case, but thanks to the new webmail feature something conveniently possible. Mox functions as both a replacement and extension of mailpit in this case.

Error description:

I use mox localserve, with pedantic deactivated. Ports/connections itself work just fine, but I got the error message: 5.5.2 bad syntax: need at least one char for subdomain.

Looking at the log, I see:

trace: "LS: 220 localhost ESMTP mox v0.0.6\r\n" (pkg: smtpserver; cid: 18a2c656776; delta: "174.221µs")
trace: "RC: ehlo MYHOSTNAME.\r\n" (pkg: smtpserver; cid: 18a2c656776; delta: "360.184µs")
debug: "smtp command result": "bad syntax: need at least one char for subdomain (remaining \"\")" (pkg: smtpserver; kind: submission; cmd: ehlo; code: 501; ecode: 5.5.2; duration: "33.644µs"; cid: 18a2c656776; delta: "128.314µs")

I guessed that the trailing dot of the hostname (as sent by Odoo and outside my practical sphere of influence) might be the issue.

Locally patching https://github.com/mjl-/mox/blob/61a5eb61a446581f59bc338aa23b6074cd068695/smtpserver/parse.go#L245C1-L249:

func (p *parser) xdomain() dns.Domain {
        s := p.xsubdomain()
        for p.take(".") {
                if !p.empty() { // <----- HAACK
                        s += "." + p.xsubdomain()
                }
        }

worked. AFAIU the referenced RFC, domain names with trailing dot are not explicitely forbidden, but I'm not sure, and I haven't dug out all the referenced RFCs and sections.

Is this a bug (and could be fixed generally), or if not, is it possible to allow it in non-pedantic mode for localserve?

Mox not able to send mail to Gmail

I've been testing Mox installation on the host system (without Docker). Receiving mail works well, sending mail does not work. Apparently, Mox is unable to connect to Gmail server, what could be the reason? I've also asked Mox to send mail to itself - also no delivery. Please find the Gmail sending errors log below.

Jun 12 00:05:21 xxxxxxxxxxx mox[426904]: l=debug m="queue deliverhost result" cid=188ace60a0d from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue host=alt3.gmail-smtp-in.l.google.com attempt=4 tlsmode=strict permanent=false badtls=false secodeopt= errmsg="dialing smtp server: dial tcp [2404:6800:4008:c13::1b]:25: i/o timeout" ok=false duration=30.01200778s
Jun 12 00:05:21 xxxxxxxxxxx mox[426904]: l=info m="delivering to remote" from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue remote=alt4.gmail-smtp-in.l.google.com queuecid=1686527937032
Jun 12 00:05:21 xxxxxxxxxxx mox[426904]: l=debug m="dns lookup result" cid=188ace60a0e pkg=dns pkg=queue type=ipaddr host=alt4.gmail-smtp-in.l.google.com. resp="[ip=173.194.202.27;ip=2607:f8b0:400e:c00::1a]" duration=72.877307ms
Jun 12 00:05:21 xxxxxxxxxxx mox[426904]: l=debug m="dialing remote smtp" cid=188ace60a0e from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue addr=173.194.202.27:25
Jun 12 00:05:36 xxxxxxxxxxx mox[426904]: l=debug m="connection attempt for smtp delivery" err="dial tcp 10.0.0.67:0->173.194.202.27:25: i/o timeout" cid=188ace60a0e from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue host=alt4.gmail-smtp-in.l.google.com addr=173.194.202.27:25 laddr=10.0.0.67:0
Jun 12 00:05:36 xxxxxxxxxxx mox[426904]: l=debug m="dialing remote smtp" cid=188ace60a0e from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue addr=[2607:f8b0:400e:c00::1a]:25
Jun 12 00:05:51 xxxxxxxxxxx mox[426904]: l=debug m="connection attempt for smtp delivery" err="dial tcp [2607:f8b0:400e:c00::1a]:25: i/o timeout" cid=188ace60a0e from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue host=alt4.gmail-smtp-in.l.google.com addr=[2607:f8b0:400e:c00::1a]:25 laddr=
Jun 12 00:05:51 xxxxxxxxxxx mox[426904]: l=debug m="connecting to remote smtp" err="dial tcp [2607:f8b0:400e:c00::1a]:25: i/o timeout" cid=188ace60a0e from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue host=alt4.gmail-smtp-in.l.google.com
Jun 12 00:05:51 xxxxxxxxxxx mox[426904]: l=debug m="queue deliverhost result" cid=188ace60a0e from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue host=alt4.gmail-smtp-in.l.google.com attempt=4 tlsmode=strict permanent=false badtls=false secodeopt= errmsg="dialing smtp server: dial tcp [2607:f8b0:400e:c00::1a]:25: i/o timeout" ok=false duration=30.000330764s
Jun 12 00:05:51 xxxxxxxxxxx mox[426904]: l=error m="temporary failure delivering from queue" err="dialing smtp server: dial tcp [2607:f8b0:400e:c00::1a]:25: i/o timeout" from=team@xxxxxxxxxxx [email protected] attempts=3 msgid=2 cid=188ace60a08 pkg=queue backoff=1h0m24s nextattempt="2023-06-12 01:03:44.952964679 +0000 UTC m=+3887.941291992"

Docker build feedback

Greetings,

please add a docker hub build.
So that we can update based on release tags.

Thank you.

I want to try out mox later. It looks exactly like what I have been looking for.

How to provide an already existing TLS certificate and key

Hi,

Thanks for developing this project, I learned about this in Digital Ocean Infrastructure-as-a-Newsletter, and I'm trying it.

I'd like to know if there is a way to provide the system the TLS certificate and private key files (e.g. for Let's Encrypt would be privkey.pem and fullchain.pem) without going through the auto configuration?

SMTP submissions with IPv6 fail

I'm using an email client that appears to attempt to connect over IPv6 but fails (without any useful logs).

Checking mox's logs, it appears to have trouble:

Jul 21 22:15:39 MyHost mox[4052580]: l=info m="new connection" pkg=smtpserver remote=[<redacted2>]:49313 local=[<redacted>]:465 submission=true tls=true listener=public cid=1897a17e07f delta="18.515µs"
Jul 21 22:15:39 MyHost mox[4052580]: l=info m="new connection" pkg=smtpserver remote=[<redacted2>]:49314 local=[<redacted>]:465 submission=true tls=true listener=public cid=1897a17e080 delta="16.672µs"
Jul 21 22:15:39 MyHost mox[4052580]: l=debug m="smtp command result" err="bad syntax: ip is not ipv4 (remaining \"\")" pkg=smtpserver kind=submission cmd=ehlo code=501 ecode=5.5.2 duration="20.98µs" cid=1897a17e080 delta=80.82411ms
Jul 21 22:15:39 MyHost mox[4052580]: l=debug m="smtp command result" err="bad syntax: ip is not ipv4 (remaining \"\")" pkg=smtpserver kind=submission cmd=ehlo code=501 ecode=5.5.2 duration="8.686µs" cid=1897a17e07f delta=84.789118ms
Jul 21 22:15:39 MyHost mox[4052580]: l=debug m="smtp command result" err="bad syntax: expected at least one char for subdomain (remaining \"[<redacted3>::]\")" pkg=smtpserver kind=submission cmd=helo code=501 ecode=5.5.2 duration="18.414µs" cid=1897a17e080 delta=4.828641ms
Jul 21 22:15:39 MyHost mox[4052580]: l=debug m="smtp command result" err="bad syntax: expected at least one char for subdomain (remaining \"[<redacted3>::]\")" pkg=smtpserver kind=submission cmd=helo code=501 ecode=5.5.2 duration="7.955µs" cid=1897a17e07f delta=5.75833ms
Jul 21 22:15:39 MyHost mox[4052580]: l=debug m="smtp command result" pkg=smtpserver kind=submission cmd=quit code=221 ecode=2.0.0 duration="7.635µs" cid=1897a17e080 delta=4.897753ms
Jul 21 22:15:39 MyHost mox[4052580]: l=info m="connection closed" pkg=smtpserver cid=1897a17e080 delta="59.031µs"
Jul 21 22:15:39 MyHost mox[4052580]: l=debug m="smtp command result" pkg=smtpserver kind=submission cmd=quit code=221 ecode=2.0.0 duration="2.956µs" cid=1897a17e07f delta=6.607045ms
Jul 21 22:15:39 MyHost mox[4052580]: l=info m="connection closed" pkg=smtpserver cid=1897a17e07f delta="47.119µs"

I can provide unredacted logs to a maintainer directly since I imagine the IPs would be helpful but I prefer not to post them publicly.

Improve docker support

First of all, I want to express my gratitude for this project. I was able to configure everything without using docker, it's really cool.

Now I would like to explain my use-case and ask if it is possible to do so as part of this project.

The main idea is to run the project in a docker and allow to proxy web traffic through traefik (or nginx, if someone wants to).

Because the project has to be started with network_mode: "host", it becomes very difficult to accomplish this task.

Here's an example of how I would like it to work (it's Ansible config, but the main idea is just to run docker container with needed configuration):

- name: Run mail container
  community.docker.docker_container:
    image: r.xmox.nl/mox:latest
    name: mox
    restart: true
    restart_policy: "unless-stopped"
    ports:
      - "25:25"
      - "143:143"
      - "465:465"
      - "587:587"
      - "993:993"
    volumes:
      - "{{ data_dir }}/mox/config:/mox/config"
      - "{{ data_dir }}/mox/data:/mox/data"
      - "{{ data_dir }}/mox/web:/mox/web"
      - "{{ server_dir }}/letsencrypt/certs/:/mox/certs:ro"
    env:
      MOX_DOCKER: "yes"
    working_dir: "/mox"
    labels:
      traefik.enable: "true"
      traefik.http.routers.moxauto.tls: "true"
      traefik.http.routers.moxauto.entrypoints: "websecure"
      traefik.http.routers.moxauto.tls.certresolver: "letsencrypt"
      traefik.http.routers.moxauto.rule: "Host(`autoconfig.{{ ansible_host }}`,`mta-sts.{{ ansible_host }}`)"
      traefik.http.routers.moxauto.middlewares: "no-auth-chain@file"
      traefik.http.routers.moxauto.service: "moxauto"
      traefik.http.services.moxauto.loadbalancer.server.port: "81"
      traefik.http.routers.mox.tls: "true"
      traefik.http.routers.mox.entrypoints: "websecure"
      traefik.http.routers.mox.tls.certresolver: "letsencrypt"
      traefik.http.routers.mox.rule: "Host(`mail.{{ ansible_host }}`)"
      traefik.http.routers.mox.middlewares: "auth-chain@file"
      traefik.http.routers.mox.service: "mox"
      traefik.http.services.mox.loadbalancer.server.port: "1080"

Thus, we explicitly specify the ports that need to be opened for the mail to work properly.
For web control and autoconfig requests, we proxy requests using traefik (autoconfig, mta-sts -> 81, web panel -> 1080). traefik here will get the certificates itself, we only need to provide a certificate for the mail services.

[Documentation Request] System Requirements

One reason I'd like to shift from Mailcow is the very heavy system requirements (6GB RAM recommended), especially given rspamd and other such resource-intensive components of Mailcow.

It'd be useful to have information on minimum and recommended system requirements.

Setting to automatically redirect all http -> https

From what I can see, the only way to get a redirect to https is through WebDomainRedirects, which will not allow cyclic redirects. What I am looking for is a setting that assumes all http connections should be redirected to https.

Setting admin and accounts password headless

I'm building a template for mox using the LXD-based framework of Nextcloud-related templates as available here: https://codeberg/pmarini/nc-env

As part of the provisioning I'm trying to pass the admin and an account password from the command line:

Example:

$ echo admin 321 | ./mox setaccountpassword [email protected]

fails.

Is there a flag or another shell technique that allows to pipe the password in setaccountpassword and setadminpassword?

Mox not able to send mail to itself

I've been testing Mox installation on the host system (without Docker). Receiving mail works well, sending mail does not work. To test the simpest case, I've asked Mox to send mail to itself - and it fails, please see the error log below. No, I have no idea why it tries to connect to 127.0.1.1, I don't have such address in mox.conf, it's only 127.0.0.1 there for internal use.

Jun 12 00:27:21 xxxxxxxxxxx mox[426904]: l=debug m="connection attempt for smtp delivery" err="dial tcp 10.0.0.67:0->127.0.1.1:25: connect: connection refused" cid=188ace60a13 from=team@xxxxxxxxxxx recipient=team@xxxxxxxxxxx attempts=3 msgid=4 cid=188ace60a12 pkg=queue host=xxxxxxxxxxx addr=127.0.1.1:25 laddr=10.0.0.67:0
Jun 12 00:27:21 xxxxxxxxxxx mox[426904]: l=debug m="connecting to remote smtp" err="dial tcp 10.0.0.67:0->127.0.1.1:25: connect: connection refused" cid=188ace60a13 from=team@xxxxxxxxxxx recipient=team@xxxxxxxxxxx attempts=3 msgid=4 cid=188ace60a12 pkg=queue host=xxxxxxxxxxx
Jun 12 00:27:21 xxxxxxxxxxx mox[426904]: l=debug m="queue deliverhost result" cid=188ace60a13 from=team@xxxxxxxxxxx recipient=team@xxxxxxxxxxx attempts=3 msgid=4 cid=188ace60a12 pkg=queue host=xxxxxxxxxxx attempt=4 tlsmode=opportunistic permanent=false badtls=false secodeopt= errmsg="dialing smtp server: dial tcp 10.0.0.67:0->127.0.1.1:25: connect: connection refused" ok=false duration=1.13015ms
Jun 12 00:27:21 xxxxxxxxxxx mox[426904]: l=error m="temporary failure delivering from queue" err="dialing smtp server: dial tcp 10.0.0.67:0->127.0.1.1:25: connect: connection refused" from=team@xxxxxxxxxxx recipient=team@xxxxxxxxxxx attempts=3 msgid=4 cid=188ace60a12 pkg=queue backoff=59m28s nextattempt="2023-06-12 01:26:49.051541254 +0000 UTC m=+5272.039868567"

Fatal: cannot assign requested address

Hi guys,

I someone could help me with running the service.

System: Fedora 37 amd64
User : mox
X.X.X.X - My External IP (Dynamic DNS), IP could change.
mymail.com - My domain

The command: ./mox serve gives me the following response:

l=debug m="autotls setting allowed hostnames" pkg=autotls hostnames=[mymail.com;mta-sts.mymail.com] publicips=[X.X.X.X]
l=print m="starting as root, initializing network listeners" pkg=serve version=v0.0.6 pid=9219 moxconf=/home/mox/config/mox.conf domainsconf=/home/mox/config/domains.conf
l=print m="listening for smtp" pkg=smtpserver listener=public address=X.X.X.X:50465 protocol=submissions
l=fatal m="smtp: listen for smtp" err="listen tcp4 X.X.X.X:50465: bind: cannot assign requested address" pkg=smtpserver protocol=submissions listener=public

I also have the following ports forwarded on my router:
image

My mox.conf as follows:


# Directory where all data is stored, e.g. queue, accounts and messages, ACME TLS
# certs/keys. If this is a relative path, it is relative to the directory of
# mox.conf.
DataDir: ../data

# Default log level, one of: error, info, debug, trace, traceauth, tracedata.
# Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with
# passwords, and tracedata on top of that also the full data exchanges (full
# messages), which can be a large amount of data.
LogLevel: debug

# User to switch to after binding to all sockets as root. Default: mox. If the
# value is not a known user, it is parsed as integer and used as uid and gid.
# (optional)
User: mox

# Full hostname of system, e.g. mail.<domain>
# Hostname: localhost.localdomain
Hostname: mymail.com

# If enabled, a single DNS TXT lookup of _updates.xmox.nl is done every 24h to
# check for a new release. Each time a new release is found, a changelog is
# fetched from https://updates.xmox.nl and delivered to the postmaster mailbox.
# (optional)
#
# RECOMMENDED: please enable to stay up to date
#
#CheckUpdates: true

# Automatic TLS configuration with ACME, e.g. through Let's Encrypt. The key is a
# name referenced in TLS configs, e.g. letsencrypt. (optional)
ACME:
	letsencrypt:

		# For letsencrypt, use https://acme-v02.api.letsencrypt.org/directory.
		DirectoryURL: https://acme-v02.api.letsencrypt.org/directory

		# Email address to register at ACME provider. The provider can email you when
		# certificates are about to expire. If you configure an address for which email is
		# delivered by this server, keep in mind that TLS misconfigurations could result
		# in such notification emails not arriving.
		ContactEmail: [email protected]

# File containing hash of admin password, for authentication in the web admin
# pages (if enabled). (optional)
AdminPasswordFile: adminpasswd

# Listeners are groups of IP addresses and services enabled on those IP addresses,
# such as SMTP/IMAP or internal endpoints for administration or Prometheus
# metrics. All listeners with SMTP/IMAP services enabled will serve all configured
# domains. If the listener is named 'public', it will get a few helpful additional
# configuration checks, for acme automatic tls certificates and monitoring of ips
# in dnsbls if those are configured.
Listeners:
	internal:

		# Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses, but
		# it is better to explicitly specify the IPs you want to use for email, as mox
		# will make sure outgoing connections will only be made from one of those IPs.
		IPs:
			- 127.0.0.1
			- ::1
			- 192.168.0.5
			- fd25:e2db:a5bc::263
			- fd25:e2db:a5bc:0:2e3:5cff:fe68:818a

		# If empty, the config global Hostname is used. (optional)
		Hostname: localhost

		# Account web interface, for email users wanting to change their accounts, e.g.
		# set new password, set new delivery rulesets. Served at /. (optional)
		AccountHTTP:
			Enabled: true

		# Admin web interface, for managing domains, accounts, etc. Served at /admin/.
		# Preferrably only enable on non-public IPs. Hint: use 'ssh -L 8080:localhost:80
		# you@yourmachine' and open http://localhost:8080/admin/, or set up a tunnel (e.g.
		# WireGuard) and add its IP to the mox 'internal' listener. (optional)
		AdminHTTP:
			Enabled: true

		# Serve prometheus metrics, for monitoring. You should not enable this on a public
		# IP. (optional)
		MetricsHTTP:
			Enabled: true
	public:

		# Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses, but
		# it is better to explicitly specify the IPs you want to use for email, as mox
		# will make sure outgoing connections will only be made from one of those IPs.
		IPs:
			- X.X.X.X

		# For SMTP/IMAP STARTTLS, direct TLS and HTTPS connections. (optional)
		TLS:

			# Name of provider from top-level configuration to use for ACME, e.g. letsencrypt.
			# (optional)
			ACME: letsencrypt

		# (optional)
		SMTP:
			Enabled: false

			# Addresses of DNS block lists for incoming messages. Block lists are only
			# consulted for connections/messages without enough reputation to make an
			# accept/reject decision. This prevents sending IPs of all communications to the
			# block list provider. If any of the listed DNSBLs contains a requested IP
			# address, the message is rejected as spam. The DNSBLs are checked for healthiness
			# before use, at most once per 4 hours. Example DNSBLs: sbl.spamhaus.org,
			# bl.spamcop.net (optional)
			#DNSBLs:
				#- sbl.spamhaus.org
				#- bl.spamcop.net

		# SMTP over TLS for submitting email, by email applications. Requires a TLS
		# config. (optional)
		Submissions:
			Enabled: true
			Port: 50465

		# IMAP over TLS for reading email, by email applications. Requires a TLS config.
		# (optional)
		IMAPS:
			Enabled: true

		# Serve autoconfiguration/autodiscovery to simplify configuring email
		# applications, will use port 443. Requires a TLS config. (optional)
		AutoconfigHTTPS:
			Enabled: false

		# Serve MTA-STS policies describing SMTP TLS requirements. Requires a TLS config.
		# (optional)
		MTASTSHTTPS:
			Enabled: true

		# All configured WebHandlers will serve on an enabled listener. (optional)
		WebserverHTTP:
			Enabled: true

		# All configured WebHandlers will serve on an enabled listener. Either ACME must
		# be configured, or for each WebHandler domain a TLS certificate must be
		# configured. (optional)
		WebserverHTTPS:
			Enabled: true

# Destination for emails delivered to postmaster address.
Postmaster:
	Account: mox

	# E.g. Postmaster or Inbox.
	Mailbox: Postmaster

My domains.conf as follows:


# Domains for which email is accepted. For internationalized domains, use their
# IDNA names in UTF-8.
Domains:
	mymail.com:

		# If not empty, only the string before the separator is used to for email delivery
		# decisions. For example, if set to "+", [email protected] will be
		# delivered to [email protected]. (optional)
		LocalpartCatchallSeparator: +

		# With DKIM signing, a domain is taking responsibility for (content of) emails it
		# sends, letting receiving mail servers build up a (hopefully positive) reputation
		# of the domain, which can help with mail delivery. (optional)
		DKIM:

			# Emails can be DKIM signed. Config parameters are per selector. A DNS record must
			# be created for each selector. Add the name to Sign to use the selector for
			# signing messages.
			Selectors:
				2023a:

					# Period a signature is valid after signing, as duration, e.g. 72h. The period
					# should be enough for delivery at the final destination, potentially with several
					# hops/relays. In the order of days at least. (optional)
					Expiration: 72h

					# Either an RSA or ed25519 private key file in PKCS8 PEM form.
					PrivateKeyFile: dkim/2023a._domainkey.mymail.com.20230510T232710.ed25519key.pkcs8.pem
				2023b:

					# Period a signature is valid after signing, as duration, e.g. 72h. The period
					# should be enough for delivery at the final destination, potentially with several
					# hops/relays. In the order of days at least. (optional)
					Expiration: 72h

					# Either an RSA or ed25519 private key file in PKCS8 PEM form.
					PrivateKeyFile: dkim/2023b._domainkey.mymail.com.20230510T232710.rsakey.pkcs8.pem
				2023c:

					# Period a signature is valid after signing, as duration, e.g. 72h. The period
					# should be enough for delivery at the final destination, potentially with several
					# hops/relays. In the order of days at least. (optional)
					Expiration: 72h

					# Either an RSA or ed25519 private key file in PKCS8 PEM form.
					PrivateKeyFile: dkim/2023c._domainkey.mymail.com.20230510T232710.ed25519key.pkcs8.pem
				2023d:

					# Period a signature is valid after signing, as duration, e.g. 72h. The period
					# should be enough for delivery at the final destination, potentially with several
					# hops/relays. In the order of days at least. (optional)
					Expiration: 72h

					# Either an RSA or ed25519 private key file in PKCS8 PEM form.
					PrivateKeyFile: dkim/2023d._domainkey.mymail.com.20230510T232710.rsakey.pkcs8.pem

			# List of selectors that emails will be signed with. (optional)
			Sign:
				- 2023a
				- 2023b

		# With DMARC, a domain publishes, in DNS, a policy on how other mail servers
		# should handle incoming messages with the From-header matching this domain and/or
		# subdomain (depending on the configured alignment). Receiving mail servers use
		# this to build up a reputation of this domain, which can help with mail delivery.
		# A domain can also publish an email address to which reports about DMARC
		# verification results can be sent by verifying mail servers, useful for
		# monitoring. Incoming DMARC reports are automatically parsed, validated, added to
		# metrics and stored in the reporting database for later display in the admin web
		# pages. (optional)
		DMARC:

			# Address-part before the @ that accepts DMARC reports. Must be
			# non-internationalized. Recommended value: dmarc-reports.
			Localpart: dmarc-reports

			# Account to deliver to.
			Account: mox

			# Mailbox to deliver to, e.g. DMARC.
			Mailbox: DMARC

		# With MTA-STS a domain publishes, in DNS, presence of a policy for
		# using/requiring TLS for SMTP connections. The policy is served over HTTPS.
		# (optional)
		MTASTS:

			# Policies are versioned. The version must be specified in the DNS record. If you
			# change a policy, first change it in mox, then update the DNS record.
			PolicyID: 20230510T222710

			# testing, enforce or none. If set to enforce, a remote SMTP server will not
			# deliver email to us if it cannot make a TLS connection.
			Mode: enforce

			# How long a remote mail server is allowed to cache a policy. Typically 1 or
			# several weeks.
			MaxAge: 24h0m0s

			# List of server names allowed for SMTP. If empty, the configured hostname is set.
			# Host names can contain a wildcard (*) as a leading label (matching a single
			# label, e.g. *.example matches host.example, not sub.host.example). (optional)
			MX:
				- localhost.localdomain

		# With TLSRPT a domain specifies in DNS where reports about encountered SMTP TLS
		# behaviour should be sent. Useful for monitoring. Incoming TLS reports are
		# automatically parsed, validated, added to metrics and stored in the reporting
		# database for later display in the admin web pages. (optional)
		TLSRPT:

			# Address-part before the @ that accepts TLSRPT reports. Recommended value:
			# tls-reports.
			Localpart: tls-reports

			# Account to deliver to.
			Account: mox

			# Mailbox to deliver to, e.g. TLSRPT.
			Mailbox: TLSRPT

# Accounts to which email can be delivered. An account can accept email for
# multiple domains, for multiple localparts, and deliver to multiple mailboxes.
Accounts:
	mox:

		# Default domain for addresses specified in Destinations. An address can specify a
		# domain override.
		Domain: mymail.com

		# Destinations, specified as (encoded) localpart for Domain, or a full address
		# including domain override.
		Destinations:
			[email protected]: nil
#			If you receive email from mailing lists, you probably want to configure them like the example below.
#			[email protected]:
#		
#				# Mailbox to deliver to if none of Rulesets match. Default: Inbox. (optional)
#				Mailbox: 
#		
#				# Delivery rules based on message and SMTP transaction. You may want to match each
#				# mailing list by SMTP MailFrom address, VerifiedDomain and/or List-ID header
#				# (typically <listname.example.org> if the list address is [email protected]),
#				# delivering them to their own mailbox. (optional)
#				Rulesets:
#					-
#		
#						# Matches if this regular expression matches (a substring of) the SMTP MAIL FROM
#						# address (not the message From-header). E.g. [email protected]. (optional)
#						SMTPMailFromRegexp: 
#		
#						# Matches if this domain matches an SPF- and/or DKIM-verified (sub)domain.
#						# (optional)
#						VerifiedDomain: list.example.org
#		
#						# Matches if these header field/value regular expressions all match (substrings
#						# of) the message headers. Header fields and valuees are converted to lower case
#						# before matching. Whitespace is trimmed from the value before matching. A header
#						# field can occur multiple times in a message, only one instance has to match. For
#						# mailing lists, you could match on ^list-id$ with the value typically the mailing
#						# list address in angled brackets with @ replaced with a dot, e.g.
#						# <name\.lists\.example\.org>. (optional)
#						HeadersRegexp:
#							^list-id$: <name\.list\.example\.org>
#		
#						# Influence the spam filtering, this does not change whether this ruleset applies
#						# to a message. If this domain matches an SPF- and/or DKIM-verified (sub)domain,
#						# the message is accepted without further spam checks, such as a junk filter or
#						# DMARC reject evaluation. DMARC rejects should not apply for mailing lists that
#						# are not configured to rewrite the From-header of messages that don't have a
#						# passing DKIM signature of the From-domain. Otherwise, by rejecting messages, you
#						# may be automatically unsubscribed from the mailing list. The assumption is that
#						# mailing lists do their own spam filtering/moderation. (optional)
#						ListAllowDomain: list.example.org
#		
#						# Mailbox to deliver to if this ruleset matches.
#						Mailbox: Lists/Example
#		

		# If configured, messages classified as weakly spam are rejected with instructions
		# to retry delivery, but this time with a signed token added to the subject.
		# During the next delivery attempt, the signed token will bypass the spam filter.
		# Messages with a clear spam signal, such as a known bad reputation, are
		# rejected/delayed without a signed token. (optional)
		SubjectPass:

			# How long unique values are accepted after generating, e.g. 12h.
			Period: 12h0m0s

		# Mail that looks like spam will be rejected, but a copy can be stored temporarily
		# in a mailbox, e.g. Rejects. If mail isn't coming in when you expect, you can
		# look there. The mail still isn't accepted, so the remote mail server may retry
		# (hopefully, if legitimate), or give up (hopefully, if indeed a spammer).
		# Messages are automatically removed from this mailbox, so do not set it to a
		# mailbox that has messages you want to keep. (optional)
		RejectsMailbox: Rejects

		# Automatically set $Junk and $NotJunk flags based on mailbox messages are
		# delivered/moved/copied to. Email clients typically have too limited
		# functionality to conveniently set these flags, especially $NonJunk, but they can
		# all move messages to a different mailbox, so this helps them. (optional)
		AutomaticJunkFlags:

			# If enabled, flags will be set automatically if they match a regular expression
			# below. When two of the three mailbox regular expressions are set, the remaining
			# one will match all unmatched messages. Messages are matched in the order
			# specified and the search stops on the first match. Mailboxes are lowercased
			# before matching.
			Enabled: true

			# Example: ^(junk|spam). (optional)
			JunkMailboxRegexp: ^(junk|spam)

			# Example: ^(inbox|neutral|postmaster|dmarc|tlsrpt|rejects), and you may wish to
			# add trash depending on how you use it, or leave this empty. (optional)
			NeutralMailboxRegexp: ^(inbox|neutral|postmaster|dmarc|tlsrpt|rejects)

		# Content-based filtering, using the junk-status of individual messages to rank
		# words in such messages as spam or ham. It is recommended you always set the
		# applicable (non)-junk status on messages, and that you do not empty your Trash
		# because those messages contain valuable ham/spam training information.
		# (optional)
		JunkFilter:

			# Approximate spaminess score between 0 and 1 above which emails are rejected as
			# spam. Each delivery attempt adds a little noise to make it slightly harder for
			# spammers to identify words that strongly indicate non-spaminess and use it to
			# bypass the filter. E.g. 0.95.
			Threshold: 0.950000
			Params:

				# Track ham/spam ranking for single words. (optional)
				Onegrams: true

				# Maximum power a word (combination) can have. If spaminess is 0.99, and max power
				# is 0.1, spaminess of the word will be set to 0.9. Similar for ham words.
				MaxPower: 0.010000

				# Number of most spammy/hammy words to use for calculating probability. E.g. 10.
				TopWords: 10

				# Ignore words that are this much away from 0.5 haminess/spaminess. E.g. 0.1,
				# causing word (combinations) of 0.4 to 0.6 to be ignored. (optional)
				IgnoreWords: 0.100000

				# Occurrences in word database until a word is considered rare and its influence
				# in calculating probability reduced. E.g. 1 or 2. (optional)
				RareWords: 2

Not sure what I am doing wrong. The error does not mean anything.

On hosts with a single routable interface, quickstart followed by mox serve fails when listening on :80 with "address already in use"

After doing a first mox quickstart and a mox serve I'm seeing a failure when binding to port 80:

l=fatal m="http: listen" err="listen tcp4 0.0.0.0:80: bind: address already in use" pkg=http addr=0.0.0.0:80

A strace shows bind() failing:

bind(34, {sa_family=AF_INET, sin_port=htons(80), sin_addr=inet_addr("0.0.0.0")}, 16) = -1 EADDRINUSE (Address already in use)

Interestingly, when running this a few times over, the failure sometimes happens when binding to 127.0.0.1, other times when binding to 0.0.0.0.

autocert issues

(I apologize if this is the wrong place and / or if my issue is considered as a support request - if so please point me towards the right channels)

I'm trying to set up mox for email with my own domain, on a separate VPS, and I don't seem to be able to get autocert to respond to LetsEncrypt's challenge. Here's the log output from a fresh run with LogLevel: debug

Mar 04 13:09:25 my-vps mox[33501]: l=print m="https listener" pkg=http name=public kinds=acme-tls-alpn01,autoconfig-https,mtasts-https address=<vps-ip>:443
Mar 04 13:09:25 my-vps mox[33501]: l=print m="listening for smtp" pkg=smtpserver listener=public address=<vps-ip>:25 protocol=smtp
Mar 04 13:09:25 my-vps mox[33501]: l=print m="listening for smtp" pkg=smtpserver listener=public address=<vps-ip>:465 protocol=submissions
Mar 04 13:09:25 my-vps mox[33501]: l=print m="listening for imap" pkg=imapserver listener=public addr=<vps-ip>:993 protocol=imaps
Mar 04 13:09:26 my-vps mox[33501]: l=print m="ensuring certificate availability" pkg=http hostname=mail.sherief.fyi
Mar 04 13:09:26 my-vps mox[33501]: l=info m="getting cert from dir cache" err="acme/autocert: certificate cache miss" pkg=autotls name=mail.sherief.fyi
Mar 04 13:09:26 my-vps mox[33501]: l=debug m="dircache get result" err="acme/autocert: certificate cache miss" pkg=autotls name=mail.sherief.fyi
Mar 04 13:09:26 my-vps mox[33501]: l=debug m="autotls hostpolicy result" pkg=autotls host=mail.sherief.fyi
Mar 04 13:09:27 my-vps mox[33501]: l=debug m="dircache put result" pkg=autotls name=mail.sherief.fyi+token
Mar 04 13:09:29 my-vps mox[33501]: l=info m="new connection" pkg=smtpserver remote=178.33.24.135:61000 local=<vps-ip>:465 submission=true tls=true listener=public cid=186acbdcf3e delta="53.036µs"
Mar 04 13:09:31 my-vps mox[33501]: l=info m="connection closed" err="write: tls: client offered only unsupported versions: [302 301] (fatal io error)" pkg=smtpserver cid=186acbdcf3e delta=1.950629207s
Mar 04 13:09:38 my-vps mox[33501]: l=error m="requesting automatic certificate" err="acme/autocert: unable to satisfy \"https://acme-v02.api.letsencrypt.org/acme/authz-v3/208140824327\" for domain \"mail.sherief.fyi\": no viable challenge type found" pkg=http hostname=mail.sherief.fyi
Mar 04 13:09:38 my-vps mox[33501]: l=debug m="dircache delete result" pkg=autotls name=mail.sherief.fyi+token

autotls seems to be able to satisfy tls-alpn-01 and mox is listening on port 443. Here's my mox.conf:

# certs/keys. If this is a relative path, it is relative to the directory of
# mox.conf.
DataDir: ../data

# Default log level, one of: error, info, debug, trace, traceauth, tracedata.
# Trace logs SMTP and IMAP protocol transcripts, with traceauth also messages with
# passwords, and tracedata on top of that also the full data exchanges (full
# messages), which can be a large amount of data.
LogLevel: debug

# Full hostname of system, e.g. mail.<domain>
Hostname: mail.sherief.fyi

# If enabled, a single DNS TXT lookup of _updates.xmox.nl is done every 24h to
# check for a new release. Each time a new release is found, a changelog is
# fetched from https://updates.xmox.nl and delivered to the postmaster mailbox.
# (optional)
#
# RECOMMENDED: please enable to stay up to date
#
#CheckUpdates: true

# Automatic TLS configuration with ACME, e.g. through Let's Encrypt. The key is a
# name referenced in TLS configs, e.g. letsencrypt. (optional)
ACME:
	letsencrypt:

		# For letsencrypt, use https://acme-v02.api.letsencrypt.org/directory.
		DirectoryURL: https://acme-v02.api.letsencrypt.org/directory

		# Email address to register at ACME provider. The provider can email you when
		# certificates are about to expire. If you configure an address for which email is
		# delivered by this server, keep in mind that TLS misconfigurations could result
		# in such notification emails not arriving.
		ContactEmail: <my email>

# File containing hash of admin password, for authentication in the web admin
# pages (if enabled). (optional)
AdminPasswordFile: adminpasswd

# Listeners are groups of IP addresses and services enabled on those IP addresses,
# such as SMTP/IMAP or internal endpoints for administration or Prometheus
# metrics. All listeners with SMTP/IMAP services enabled will serve all configured
# domains.
Listeners:
	internal:

		# Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses.
		IPs:
			- 127.0.0.1
			- ::1

		# If empty, the config global Hostname is used. (optional)
		Hostname: localhost

		# Account web interface, for email users wanting to change their accounts, e.g.
		# set new password, set new delivery rulesets. (optional)
		AccountHTTP:
			Enabled: true

		# Admin web interface, for managing domains, accounts, etc. Served at /admin/.
		# Preferrably only enable on non-public IPs. (optional)
		AdminHTTP:
			Enabled: true

		# Serve prometheus metrics, for monitoring. You should not enable this on a public
		# IP. (optional)
		MetricsHTTP:
			Enabled: true
	public:

		# Use 0.0.0.0 to listen on all IPv4 and/or :: to listen on all IPv6 addresses.
		IPs:
			- <vps-ipv4>

		# For SMTP/IMAP STARTTLS, direct TLS and HTTPS connections. (optional)
		TLS:

			# Name of provider from top-level configuration to use for ACME, e.g. letsencrypt.
			# (optional)
			ACME: letsencrypt

		# (optional)
		SMTP:
			Enabled: true

			# Addresses of DNS block lists for incoming messages. Block lists are only
			# consulted for connections/messages without enough reputation to make an
			# accept/reject decision. This prevents sending IPs of all communications to the
			# block list provider. If any of the listed DNSBLs contains a requested IP
			# address, the message is rejected as spam. The DNSBLs are checked for healthiness
			# before use, at most once per 4 hours. Example DNSBLs: sbl.spamhaus.org,
			# bl.spamcop.net (optional)
			#DNSBLs:
				#- sbl.spamhaus.org
				#- bl.spamcop.net

		# SMTP over TLS for submitting email, by email applications. Requires a TLS
		# config. (optional)
		Submissions:
			Enabled: true

		# IMAP over TLS for reading email, by email applications. Requires a TLS config.
		# (optional)
		IMAPS:
			Enabled: true

		# Serve autoconfiguration/autodiscovery to simplify configuring email
		# applications, will use port 443. Requires a TLS config. (optional)
		AutoconfigHTTPS:
			Enabled: true

		# Serve MTA-STS policies describing SMTP TLS requirements, will use port 443.
		# Requires a TLS config. (optional)
		MTASTSHTTPS:
			Enabled: true

# Destination for emails delivered to postmaster address.
Postmaster:
	Account: sherief

	# E.g. Postmaster or Inbox.
	Mailbox: Postmaster

Any pointers as to how I can debug this further? I'm not a domain expert so I might be missing some basic config items.

Wrong SRV check

I am launching a dnscheck and I am getting this:

SRVConf

error: Missing SRV record "submissions.tcp.test.mydomain.me"
error: Missing SRV record "submission.tcp.test.mydomain.me"
error: Missing SRV record "imaps.tcp.test.mydomain.me"
error: Missing SRV record "imap.tcp.test.mydomain.me"
error: Missing SRV record "pop3.tcp.test.mydomain.me"
error: Missing SRV record "pop3s.tcp.test.mydomain.me"

According to RFC2782:

Proto
The symbolic name of the desired protocol, with an underscore
(_) prepended to prevent collisions with DNS labels that occur
in nature. _TCP and _UDP are at present the most useful values
for this field, though any name defined by Assigned Numbers or
locally may be used (as for Service). The Proto is case
insensitive.

Then the record must be:
"submissions. tcp.test.mydomain.me" instead that "submissions.tcp.test.mydomain.me"

Logging to a file

Is there a way to log to a file?
This would be perfect to couple with fail2ban to block spammers and bots.

How to setup wildcard email?

Hi there! Loving mox, was up an running in minutes! Just wondering, is it possible to create wildcard email accounts that receive all emails not associated with other accounts? Kinda need this to convert from my existing setup.

Quickstart with subdomain produces no configuration

If I attempt to configure mox (using an existing web server) with a subdomain that my mail server will be on, I get no output (swapped my actual domain for whatevermydomainis in this output):

./mox quickstart -existing-webserver -hostname mail.whatevermydomainis.com [email protected] mox
Looking up IPs for hostname mail.whatevermydomainis.com...

WARNING: Quickstart assumed the hostname of this machine is mail.whatevermydomainis.com and generates a
config for that host, but could not retrieve that name from DNS:

	hostname not in dns, probably only in /etc/hosts

This likely means one of two things:

1. You don't have any DNS records for this machine at all. You should add them
   before continuing.
2. The hostname mentioned is not the correct host name of this machine. You will
   have to replace the hostname in the suggested DNS records and generated
   config/mox.conf file. Make sure your hostname resolves to your public IPs, and
   your public IPs resolve back (reverse) to your hostname.

Admin password: ABCDEFGHIJKL
generating static config: no elements

I have attempted to configure it without using the subdomain:
./mox quickstart -existing-webserver -hostname whatevermydomainis.com [email protected] mox
and that produces output that I can use but I am worried that it'll lead to garbage DMARC output since the hashes won't match.

My machine really is set to mail.whatevermydomainis.com if I query hostname.

Is there something I'm doing wrong? I am using 0.2.0. Thanks for the project BTW!

Should rspamd integrate with third-party anti-spam systems?

I'm currently running Postfix etc. with rspamd.

Is the anti-spam capability within mox already on par with third-party systems like rspamd or would mox benefit from integration? Is that something that's likely to happen or something that would be accepted in a PR?

Web interface screenshots or demo

It would be great to add some screenshots of the web interface to the readme or provide an online demo account to help adoption and lower the barrier to evaluate the project.

Possible user scenario: "I've heard about this shiny new email project, and I might switch to it from my existing solution, but does it worth it?"

Add JMAP support

I know this is a huge feature request, but I want to propose adding support for the JMAP protocol as specified by proposed standards RFC 8620 and RFC 8621. While the whole spec for JMAP (which includes contacts and calendars) is still in development, the core spec and the mail extension have been completed. For reference, this is the implementation guide.

JMAP has significant advantages over IMAP, especially regarding mobile network performance. It's modern, well documented and already has several server and client implementations. Server support has been (as expected) quite slow, but servers like Cypht have had experimental support for some time now.

The protocol was specifically meant to be compatible with the IMAP data model, but I don't enough about Mox to know how big of a change this would involve.

Call webhook when email bounces

Hello, I'm looking into using mox for sending transactional email from a SaaS web application. For handling transactional email, I would need some way to get notified when an email bounces, so the web application can take appropriate action (suppress sending to the bounced address for some time period or indefinitely, show email delivery status in UI, use a fallback email address, etc.). In transactional email services this is typically handled via webhooks: when an email bounces, the service calls a configured webhook with bounce details in the HTTP POST request body. The webhook address can either be pre-configured, or come from a designated email header.

@mjl- would you be interested in having something like this in mox? And, more generally, is the SaaS transactional emails use case something you would be interested in targeting? Thanks!

Inconsistency in SPF Record Suggestions

Inconsistency in SPF Record Suggestions

Overview:

Upon executing the command:

mox quickstart [email protected]

I was presented with two distinct SPF record suggestions:

; For the machine, only needs to be created for the first domain added.
mail.domain.com.                    IN TXT "v=spf1 a -all"
; Specify the MX host is allowed to send for our domain and for itself (for DSNs).
; ~all means softfail for anything else, which is done instead of -all to prevent older
; mail servers from rejecting the message because they never get to looking for a dkim/dmarc pass.
mail.domain.com.                    IN TXT "v=spf1 mx ~all"

Concern:

Adhering to the SPF specification, a domain should only have a single SPF record. Multiple SPF records can introduce unpredictable email behaviors.

Personal Resolution:

While I might be overlooking a nuance, it appeared to me that the second suggestion encapsulates all required permissions. To optimize for efficiency and reduce DNS queries for the receiving server, I opted for the ipv4 mechanism:

mail.domain.com.                    IN TXT "v=spf1 ip4:123.123.123.123 ~all"

Acknowledgment:

Thank you! I'm truly impressed by the exceptional quality of this project and the meticulous attention to detail!

custom certificate file and key

Hi, first of all thank you for this great project.

I am trying to use mox on my vps with an api already serving at http and https ports. I want to use both of them at same server. I started mox with mox quickstart [email protected] and edited the mox.conf as suggested at docs and replaced tls config with my certificate file path and private key. The mox works well if I use ACME but it panics when I change it like this:

DataDir: ../data
LogLevel: error
Hostname: mail.mydomain.com
CheckUpdates: true
AdminPasswordFile: adminpasswd

Listeners:
  internal:
    IPs:
      - 127.0.0.1
      - ::1
      - <some other public ip's>
    Hostname: localhost
    TLS:
      ACME: letsencrypt
      KeyCerts:
        - 
          CertFile: /path/to/the/cert
          KeyFile: /path/to/the/key
    SMTPMaxMessageSize: 1048576
    AccountHTTP:
      Enabled: false
    AdminHTTP:
      Enabled: false
    MetricsHTTP:
      Enabled: false
  public:
    IPs:
      - 0.0.0.0
      - ::
    TLS:
      ACME: letsencrypt
    SMTP:
      Enabled: true
    Submissions:
      Enabled: true
    IMAPS:
      Enabled: true
    AutoconfigHTTPS:
      Enabled: false
    MTASTSHTTPS:
      Enabled: false
Postmaster:
  Account: mail
  Mailbox: Postmaster

And this is the panic message:

panic: runtime error: invalid memory address or nil pointer dereference
[signal SIGSEGV: segmentation violation code=0x1 addr=0x8 pc=0x8e1c62]

goroutine 1 [running]:
github.com/mjl-/mox/mox-.PrepareStaticConfig({0x0?, 0x0?}, {0xca4e52, 0xf}, 0xc0000bd900, 0x0)
        /home/bulutlinux/go/pkg/mod/github.com/mjl-/[email protected]/mox-/config.go:440 +0xf42
github.com/mjl-/mox/mox-.ParseConfig({0xddcd58, 0xc000038080}, {0xca4e52, 0xf}, 0x0)
        /home/bulutlinux/go/pkg/mod/github.com/mjl-/[email protected]/mox-/config.go:347 +0x52c
github.com/mjl-/mox/mox-.LoadConfig({0xddcd58?, 0xc000038080?})
        /home/bulutlinux/go/pkg/mod/github.com/mjl-/[email protected]/mox-/config.go:310 +0x4e
github.com/mjl-/mox/mox-.MustLoadConfig()
        /home/bulutlinux/go/pkg/mod/github.com/mjl-/[email protected]/mox-/config.go:295 +0xc5
main.cmdServe(0xc0000b6f80)
        /home/bulutlinux/go/pkg/mod/github.com/mjl-/[email protected]/serve.go:135 +0x7c
main.main()
        /home/bulutlinux/go/pkg/mod/github.com/mjl-/[email protected]/main.go:407 +0x922

It doesnt panic if I change the line after KeyCerts to something like this

KeyCerts:
  - cert:

but this time it gives this error:

fatal: "loading config file": "parsing config/mox.conf: :<line number of "- cert:">: expected indent" (pkg: mox)

I do not understand how to enter the admin panel.

I do not understand how to enter the admin panel.

  1. Connected to local panel via ssh tunnel:
    sudo ssh -L 80:127.0.0.1:80 -N -f -l root xx.xx.xx.xx.xx -p 22
  2. I open the address in a browser http://127.0.0.1
  3. I enter the issued passwords:
    "Admin password: yyyyyyyyyy
    IMAP and SMTP submission password for [email protected]: xxxxxxxxxx"
  4. Login - [email protected], password - xxxxxxxxxxxx, everything is ok, I'm in.
    But how to get into the admin panel?
    Password I see - yyyyyyyyyy, what login and do I go there? Admin;yyyyyyyyy or admin;yyyyyyyyyy or [email protected];yyyyyyyyyyy?
    Thanks in advance, I know it's a stupid question, but I'm stuck on this))

Can only send from default/primary domain. DMARC always fails for others.

Additionally, I have received no DMARK reports, are the default mailto: addresses set up internally? Do I have to add them as aliases, or change them in the DNS record?

I noticed the DKIM headers on signed emails reference my default domain, not the domain I sent from, is that possibly the issue?

comparison with maddy

Hi, thank you for creating this lovely project!

I was wondering if you are aware of https://github.com/foxcpp/maddy and if you know how your compares to it? I am in the process of choosing a new solution for my self-hosted email and not sure if your project or Maddy would be more appropriate for a standalone email setup.

Thanks!

DMARC issues with GMail

I received a DMARC report from GMail, and recipients indicated my emails went to spam. Here's the report:

<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>[email protected]</email>
    <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
    <report_id>501446162164090683</report_id>
    <date_range>
      <begin>1679270400</begin>
      <end>1679356799</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>sherief.fyi</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>reject</p>
    <sp>reject</sp>
    <pct>100</pct>
  </policy_published>
  <record>
    <row>
      <source_ip>2607:5300:205:200::279f</source_ip>
      <count>2</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>sherief.fyi</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>fail</result>
        <selector></selector>
      </dkim>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>fail</result>
        <selector>2023b</selector>
      </dkim>
      <spf>
        <domain>sherief.fyi</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
  <record>
    <row>
      <source_ip>2607:5300:205:200::279f</source_ip>
      <count>2</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>fail</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>sherief.fyi</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>fail</result>
        <selector>2023a</selector>
      </dkim>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>fail</result>
        <selector>2023b</selector>
      </dkim>
      <spf>
        <domain>sherief.fyi</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

MXToolbox doesn't seem to show pertinent problems in its report: https://mxtoolbox.com/emailhealth/sherief.fyi/

I'm not sure what's going on here (I lack enough domain experience / knowledge). Any pointers to start looking into?

Unexpected EOF error message when using IMAP with an iPhone

Hi,

I just configured my mail powered by Mox on my iPhone. Initially I had some issues. I found out that I needed to specify the IMAPS port in the incoming mailserver. Also in the Advanced Settings, I had to tick the 'Use SSL' option. After that, mail was coming in.

They are however some 'unexpected EOF error messages in the log. See the logs below. Maybe it is an client issue but maybe not so just sharing with you what I am experiencing:

Jun 13 22:24:02 mail mox[442]: l=info m="new connection" pkg=imapserver remote=84.241.202.251:31796 local=46.19.33.172:993 tls=true listener=public cid=188b1503298 delta="26.966µs"
Jun 13 22:24:02 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=authenticate duration=39.519169ms cid=188b1503298 delta=175.422065ms username=me@mydomain
Jun 13 22:24:02 mail mox[442]: l=info m="client id" pkg=imapserver params="map[name:iPhone Mail os:iOS os-version:16.5 (20F66) version:20F66]" cid=188b1503298 delta=46.736494ms username=me@mydomain
Jun 13 22:24:02 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=id duration="457.512µs" cid=188b1503298 delta="431.192µs" username=me@mydomain
Jun 13 22:24:02 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=list duration="122.654µs" cid=188b1503298 delta=39.431873ms username=me@mydomain
Jun 13 22:24:02 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=list duration=1.225618ms cid=188b1503298 delta=38.943354ms username=me@mydomain
Jun 13 22:24:02 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=list duration="531.21µs" cid=188b1503298 delta=311.639876ms username=me@mydomain
Jun 13 22:24:17 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=noop duration="116.384µs" cid=188b1503298 delta=14.469507125s username=me@mydomain
Jun 13 22:24:17 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd=select duration="350.692µs" cid=188b1503298 delta=48.239783ms username=me@mydomain
Jun 13 22:24:17 mail mox[442]: l=debug m="imap command done" pkg=imapserver cmd="uid search" duration="639.469µs" cid=188b1503298 delta=64.666156ms username=me@mydomain
Jun 13 22:24:17 mail mox[442]: l=info m="imap command ioerror" err="unexpected EOF (fatal io error)" pkg=imapserver cmd= duration=47.791878ms cid=188b1503298 delta=47.177274ms username=me@mydomain
Jun 13 22:24:17 mail mox[442]: l=info m="connection closed" err="unexpected EOF (fatal io error)" pkg=imapserver cid=188b1503298 delta="253.692µs" username=me@mydomain

Help understanding DMARC failures in GMail report

I've received the following report from GMail for my domain:

<feedback>
  <report_metadata>
    <org_name>google.com</org_name>
    <email>[email protected]</email>
    <extra_contact_info>https://support.google.com/a/answer/2466580</extra_contact_info>
    <report_id>17335918400413062210</report_id>
    <date_range>
      <begin>1689379200</begin>
      <end>1689465599</end>
    </date_range>
  </report_metadata>
  <policy_published>
    <domain>sherief.fyi</domain>
    <adkim>r</adkim>
    <aspf>r</aspf>
    <p>reject</p>
    <sp>reject</sp>
    <pct>100</pct>
    <np>reject</np>
  </policy_published>
  <record>
    <row>
      <source_ip>2607:5300:205:200::279f</source_ip>
      <count>7</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>sherief.fyi</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>fail</result>
        <selector></selector>
      </dkim>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>pass</result>
        <selector>2023b</selector>
      </dkim>
      <spf>
        <domain>sherief.fyi</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
  <record>
    <row>
      <source_ip>2607:5300:205:200::279f</source_ip>
      <count>2</count>
      <policy_evaluated>
        <disposition>none</disposition>
        <dkim>pass</dkim>
        <spf>pass</spf>
      </policy_evaluated>
    </row>
    <identifiers>
      <header_from>sherief.fyi</header_from>
    </identifiers>
    <auth_results>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>fail</result>
        <selector>2023a</selector>
      </dkim>
      <dkim>
        <domain>sherief.fyi</domain>
        <result>pass</result>
        <selector>2023b</selector>
      </dkim>
      <spf>
        <domain>sherief.fyi</domain>
        <result>pass</result>
      </spf>
    </auth_results>
  </record>
</feedback>

I'm not sure I understand the failure for selector 2023a. I'm not a domain expert, but I've used tools like MxToolbox to check that selector and everything seems to be a pass (or at least give no errors / warnings in that area). Can you point me towards what might be the issue?

Comparison table with other self-hosted email solutions

I've came across #1 and instantly thought, we could generalize this and future comparison requests.

Maybe a table in the readme could provide some comparison to the other solutions, something like this:

Feature mox maddy mailcow ...
SMTP ✔️ ✔️
IMAP ✔️ ✔️
POP3 ✔️
Auto TLS cert ✔️
... ... ... ... ...

Contributors could fill and extend the table based on their knowledge of the included tools.

Running at scale...

Can this scale to 10's of 1000's of users on a big server?
No, probably not. <- FROM HACKER NEWS

+1 I'm interested in this as well...

It looks like you have begun the limiting work you mentioned. I also see the shipping of indexes as the biggest hurdle to overcome. IPFS-Cluster could be used to mitigate the file size of the stored messages. But the trick is getting the INDEX DB up to date with continual small changes.

I feel like solving scalability could create the missing arc for all in one mail hosting solution both for the hobbiest and professionals alike. Once that hurdle is overcome this may be endlessly horizontally scalable with Anycast DNS using BGP on Low-End-Boxes.

Sadly, that is likely going to become a problem for spammers too. If they can create a cluster to send 10M+ email at less than $1000/mo the business value of spam will increase. All of the DNS security in the world does not help if you can register a new domain and redeploy in a day.

Nevertheless, I feel like unless we have a solution that scales to the size of SendGrid there will still be significant vendor lock-in and price fixing that results from the oligopoly. Business people, even more than individuals have a real need to run things securely on premise.

Can't wait to see where this goes!!!

Docker issues

Mox is an interesting software. At first I thought it's a simple pet project, but actually it's quite smart!

I only have some concerns about the Docker setup. I think the instructions provided in docker-compose.yml cannot work. First, there is no mox user within the container, and creating it there must be a part of Dockerfile. In principle, it would not be a big problem to do docker-compose run mox mox quickstart [email protected] root, since this root belongs to the container, right?

Another issue is with ports. Mox container attaches to a host network and tries to bind the priviledged ports. I think it's not possible without priviledged: true mode added into docker-compose.yml, do you agree?

Thanks for your great work!

Don't bind to 443

Hi,

I have already nginx running on that machine and just wanted to try mox, but I tries to bind to 443. I'd happily reverse proxy it but I need to be able to change the port mox binds to.

Is this configurable? Also what would I need to proxy or disable for it to not bind to 443?

testing on mac

Trying to get it going on a mac just to test it..

fails with:
"chown receveidid.key" err="chown data/receivedid.key: operation not permitted" pkg=serve path=data/receivedid.key uid=502 gid=0

# apple is my user name on the mac... so had to add it.
mox quickstart [email protected] apple

mox serve
l=debug m="autotls setting allowed hostnames" pkg=autotls hostnames=[autoconfig.example.com;mta-sts.example.com;x-macbook-pro-2.local] publicips=[201:90d4:4808:1a92:4898:45f:5842:5d2e]
l=print m="starting as unprivileged user" pkg=serve user=apple uid=502 gid=20 pid=90088
l=error m="chown receveidid.key" err="chown data/receivedid.key: operation not permitted" pkg=serve path=data/receivedid.key uid=502 gid=0
l=fatal m="smtp: listen for smtp" err="no file descriptor for listener [201:90d4:4808:1a92:4898:45f:5842:5d2e]:25" pkg=smtpserver protocol=smtp listener=public

Questions about deleting messages

Is it possible to configure mox in such a way that messages are never fully deleted, or can not be deleted (only trashed) by users? I'm interested in using it in a small business setting, and this is desirable. I poked around the data dir a bit, but I'm not 100% sure what happens with deleting messages and I don't want to guess.

Feature request: support for sytemd-resolved.

When running quickstart, I get errors like this:

WARNING: checking your public IP 46.19.33.172 in DNS block list sbl.spamhaus.org: temperror  (dnsbl: dns error: lookup 172.33.19.46.sbl.spamhaus.org. on [::1]:53: read udp [::1]:56813->[::1]:53: read: connection refused)

I checked the DNS config on my 'out-of-the-box' VPS and apparently it is configured with systemd-resolved. I wil find my way around it but it would be nice if mox would work with systemd-resolved.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.