What I'm wondering: Are the salaries high? Not just because you've been employed at the job for a long time with regular raises, but because it's hard to find developers.
HN user
mjl-
https://github.com/mjl- https://www.ueber.net/who/mjl/ mechiel@ueber.net
Congrats on the release! Having calendaring (and address book) along with your email makes it easy to run your own self-hosted PIM infrastructure.
Using tls client auth certificates for submission would make slightly more sense indeed. But who would request LE certificates to install them on desktops/phones of individuals? That sounds more complicated than managing your own client certificates.
In my mail server, accounts can use TLS client authentication with submission and imap. But only the public key in the certificate is used, to identify the account. No verification of name or before/after time. You just save the public key with an account, or remove it when you no longer want to allow it. No external CA to trust, or internal CA to run, and no automatic expiration of your connectivity.
As for LE: I think they want to keep things simple. AFAIK they are a relatively small organization. Every task they take on weighs on them. They also don't sign certificates for use with S/MIME.
Most SMTP traffic is encrypted nowadays, at least "opportunistically", without verification.
Only with MTA-STS enabled for the server will an SMTP client (that's delivering to an SMTP server) verify the TLS certificate against PKI (with DANE, it's verified against "self-signed" or CA certs in DNS). (I'm the developer of a mail server that sets up TLS for SMTP with MTA-STS and DANE using Let's Encrypt certificates by default).
I have never heard of any SMTP server doing TLS client certificate authentication. I'm pretty sure there's no standard for that, so it can't be a requirement for all incoming email. It could be a requirement between parties that have made agreements about that explicitly. And theoretically, some mail servers could use it as a signal of authenticity of the sender. But email has other, standardized mechanisms for that. And I suspect you might see delivery failures if you start requesting TLS client cert authentication from all SMTP clients.
I started writing a guide to IMAP back when I was working on an email client
I would be very interested in hearing from developers about how they write email clients that need to work with all the servers out there, with the varying levels of IMAP4 (original, rev1, rev2, combinations of at least a dozen extensions) and various levels of buggy behaviour.
I'm assuming a client developer would implement various "profiles". With an "advanced" profile for servers that implement things like CONDSTORE/QRESYNC, and a "very basic" profile that only do the absolute minimum. And probably a profile or two in between. When you encounter unexpected behaviour (eg bad syntax in protocol), you would downgrade the profile for that server for a while (it may get fixed)? If it works like this, I'm curious to the profiles developer choose. If it's not like this, I wonder how client developers work around compatibility issues (can't just keep reconnecting and trying the same if it results in an error!).
Any sane client will instead use UIDs for everything
Yes! Since last year there's the experimental UIDONLY extension that allows clients & servers to operate entirely without message sequence numbers. Saves quite a bit of accounting and possibly memory (for large mailboxes). It's a bit surprising the RFC so recent.
[... thick vs thin clients ...]
For some programmatic email access, IMAP seems quite easy to use. Just write a programmer-readable line of text as command (eg fetch/search/store/etc) and parse the response lines (that's a bit trickier in many cases, probably needing a library, but you may be able to get away without it some of the time) and you're done.
About thick clients: Storage capacity is growing much harder than my email, also on mobile. I would be fine with thick clients that sync all messages. Allows for simpler protocols and simpler implementations. An email access protocol is then not much more than a two-way sync of email message files and associated "dynamic data" like flags/keywords.
But IMAP and JMAP are doing many things at once: synchronization for thick clients, and online access for thin clients. JMAP is specifically targeting the web (thin clients), so what was old is new again (although base IMAP isn't too helpful to (web-based) thin clients either).
You can send lots of requests to a server and you have to tag them so you can match them up with responses later
Yes, you can match the final OK/NO/BAD responses with the original command based on the tag. The annoying thing is that each command typically sends most of its data in "untagged responses". And IMAP servers can send unsolicited untagged responses at any time too. It's quite tricky to handle all those responses correctly in email clients. Indeed, normally you just want to send a command, and get all the data for that command back until the finishing response. IMAP clients typically open multiple connections to isolate commands.
Most of mox is written with acme (also some vim)!
multiple separate components
Btw, I don't think it's better to have separate _components_ as in separate software packages. Integrating this functionality into one software package prevents all kinds of complexity that would otherwise arise in the integration points. Integrated software also allows for new/user-friendlier functionality.
Yes, you can add domains, add accounts (which contain the mailboxes and messages), and configure addresses for the domains with accounts. So one account can have many addresses, at one or more domains, including catchalls.
because the updates and security fixes are managed by Debian. Once things are configured, I don't need to do anything using unattended upgrades
This is a good point. It would be great to have mox packaged in more distributions. I spoke with a package maintainer about this. They understandably need to be able to upgrade unattended from old versions to a new version. In the past year, admins have had to run an upgrade command here and there (e.g. to reparse all the messages after the parsing code changed). I hope to make all this more automatic this year. That should make it more appealing for packagers (and for all non-distro-using admins too!).
I think a new debian LTS release will be coming up soonish, we probably won't make that.
(which may already exist) - I'd love to be able to use my external spamassassin with it instead of (or even in addition to) the built in one
This isn't possible yet. For me, the builtin filtering has been enough. But it's worth investigating what it takes to ask spamassassin for a classification. Could you open an issue at github for this?
the documentation/instructions could be clearer for non-typical use cases, for instance catch-all emails
Agreed, documentation is in need of improvement. So far I'm often pointing people at https://www.xmox.nl/config/. Searching there typically pops up a config option. But it's not the easiest to find functionality that way. The admin web interface also needs to be made less spartan.
The catchall is possible, by configuring an address "@$yourdomain" with an account.
because it just seems to work
This is certainly the goal. And I think we'll only get better over time!
incoming emails didn't work from Microsoft but they fixed that in 0.13
Yeah, this one was interesting. It looks like microsoft updated their TLS stack to TLS 1.3, but incorrectly, breaking TLS connections to Go TLS servers. I don't know how to contact Microsoft about it, but others have raised issues with Microsoft. Mox got a workaround (disabling session tickets for SMTP) so Microsofts TLS stack wouldn't abort the connection anymore. This is a downside of being a small guy: You have to work around the bugs of the big guys.
No, that won't work. The webmail uses a simple custom protocol.
Perhaps someone can rewrite it using JMAP in the future...
this allows those spam checks which will still work to benefit from the normal delivery path.
It's not exactly the same. When a backup MX has accepted the message, it takes responsibility of the message, and will have to send a DSN when it is rejected for being spam. Mox never "delivers" messages to a spam mailbox (it's that behaviour from the bigmail providers I don't like and undermines trust in email!). Mox either accepts a message, or rejects it at the SMTP level. When the backup sends to the primary, and the primary wants to reject, the backup would have to send a DSN to the potential spammer. Not great, and not something we have to do now.
But still, if it's only needed for emergencies, when the primary is down, it probably isn't too problematic. And the backup mx (with primary offline) can always be more strict, requiring dmarc-like alignment before accepting (to prevent backscatter if the primary rejects later on).
I didn't find anything about sub-addressing in the features list. Is it a supported feature?
Yes, assuming you mean addresses like user+<anything>@domain. The "+" is configured by default when you add a new domain. See https://www.xmox.nl/config/#cfg-domains-conf-Domains-x-Local....
Also, with a version number starting with 0.0. I'm left wondering if Mox is already stable enough to be entrusted with my precious email.
It's been suggested to just increase the version number since it's more stable than a 0.0.X might suggest. I'm currently considering mox at release number 14. I'm still on the fence about it. Ideally people make the decision on the merits of stability, not based on the looks of the version number. But I understand it's used as a signal for how stable software is (but mileage will vary!).
At least I'm trying hard not to break anything, so upgrades will work for all installations.
From a security perspective, it is better to have separate & isolated processes (but written in modern languages that provide safety).
Mox is currently a single process handling all connections, including deliveries over smtp, imap connections, and webmail and other http requests, which isn't great. User connections should probably be in a separate process. I'm not too afraid of the mox process being taken over (by a bug being abused, I don't think that's easy/common in software written in Go), but of course it will be a good line of defense against that. Resource limit enforcement of separate processes would perhaps be even nicer to get.
I haven't gotten around to really designing privilege separation, but I'm forseeing some complications around handling http requests (of the webmail, pass each request on to the user process? Have to figure out how to do that with the http library), and message database access (the database files can only be open by a single process, need to do quite some back and forth to the user process in various places).
For performance, I imagine it only helps to have an integrated server. Performance isn't really top of mind, I don't think mail servers are commonly highly loaded, at least not for the smallish scale servers. Btw, mox does not require a lot of resource (eg RAM) to run.
Hi Bron! Thanks, JMAP will come at some point too! (:
Someone has already been working on JMAP support in mox. I'm currently in a refactor of the storage layer, keeping history of (deleted) mailboxes too. Should address storage requirements for JMAP.
The looks match the intended audience. (:
I'm focusing on functionality/protocol support now. User/admin-friendliness and making it more attractive will come later. Mox will become irresistible to the masses then!
Seems reasonable. I have been thinking about schemes for backup mx'es. When the primary is online, the backup would just forward the smtp connections to the primary directly. The backup mx only has to do their own work when the primary is down. I was/am concerned about the backup mx accepting spam that you don't really want to bounce later on. But that should be an exception.
I am also thinking about synchronizing all the data to another machine. It would allow a manual failover procedure. And it's nice to have another machine (IP) for outgoing email in case the primary IP gets on a block list. But this is all future work.
I'm hoping to make this easier in the future, more often automatically taking care of updates. In the past, you've had to run a command/script here or there to fix up date, but that should all be done automatically.
My talk at FOSDEM was about this for a good part, https://fosdem.org/2025/schedule/event/fosdem-2025-5364-mox-....
If you have suggestions on how to make it less choreful to maintain, I'm interested in hearing it! Also if you had specific issues about maintenance/updates.
Does mox support antivirus addition
No, not currently possible. I think it needs milter-like functionality in the smtp server. Would be good to have eventually.
There is some more information about spam filtering at the features page:
https://www.xmox.nl/features/#hdr-junk-filtering
I'm very happy with how the filtering works for me. Most email gets classified because of being a known sender. The first-time senders will go through the bayesian classifier, which keeps most spam out. For me, 1 spam message gets through every 2 days. If ham is incorrectly rejected as spam, the sender will hear about it, because mox will keep soft-rejecting the email, eventually resulting in a bounce.
I assume that the web service can be fully disabled and Mox can be run with no httpd but that is also not specifically called out ... can it ?
You can run without the web interfaces. I think you can set it up without a public web server, but the admin interfaces are pretty convenient (though still spartan!), you could keep those internal. The webserver is needed for ACME, for MTA-STS, and for autoconfig. Btw, mox can also serve static files and do reverse proxying. The mox website is hosted by mox. I added webserver functionality (relatively tiny functionality/code compared with the email code!) so people wouldn't have to run another webserver, which greatly complicates the setup (with reverse proxying).
1. no 2fa in the webmail yet. work is currently underway at the ietf for standardizing chained SASL (auth) mechanisms, and passkeys. i want to look at implementing passkeys already for the web interfaces, but there is much more on the todo-list... 2. i as shown by yamrzou, i don't think so. SASL auth really just uses 1 auth mechanism at the moment. i think there is also standardiziation work underway for password+totp sasl authentication. but clients (like thunderbird) would still have to implement it before it's useful. there may be a trick to get 2fa-like authentication now, using both TLS client cert authentication (mox supports this based on public key identification, no other properties of certs) and a IMAP/SMTP-level SASL authentication. 3. no, but this is interesting. what kind of rules would you set? rules to match specific message headers/content that identify a message a phishing and reject it? for when attackers send the same message to many employees? do you need to remove messages from their inboxes after it has been delivered (assuming all employees would get the email at around the same time)? 4. no, but i've considered adding it. it should be very simple to add. and it's much better than mail servers modifying the message content to add messages like that.
I browsed through the article, but it's not clear to me if they're only encrypting data at rest (that you open up with a login session, but then: their referenced docs mention alice and bob exchanging messages, so that can't be it), or that they're encrypting messages and sending them out (i.e. it is similar to openpgp, but then their own custom thing? how would that interoperate with anyone else?).
Perhaps it makes more sense if you already know how they operate technically. There's a chance I browsed too quickly and missed the explanation... The article reads a bit confusing with the mixing of (a)symmetric concepts.
I'm not so sure it's expensive (in general at least, not sure about their case). I think the typical approach for encrypting data is: Use asymmetric crypto to protect a master symmetric key. Then use that master key to get per-data (eg per file) symmetric keys. Then encrypt all the data with the data symmetric keys.
You can just replace the non-pq asymmetric protection with pq asymmetric protection.
fwiw, i recently had a need for checking the registration date of domains (to find the "age", for reputation purposes), and getting the information from rdap was pretty simple: a few http calls and parsing the response as json. i'll admit i didn't look at implementing whois (since it seems to be on the way out).
it works well, except that some cctlds (eg .io) don't provide an rdap service yet. i think the reason being that icann doesn't authority over cctlds.
i don't know how cctlds are run. i can imagine they would want to provide this service, it seems pretty core to their business. but perhaps there are reasons why rdap is hard for them to implement?
(aside: i'm wondering why the article was posted. it isn't recent, and is light on information).
for transparency of reproducible builds of go applications, i made https://beta.gobuilds.org/. it compiles any publicly available go application on-demand, with a toolchain version of your choice (latest stable by default), for a platform of your choice. all (pure) go applications are reproducible by default, including when cross-compiled, and go toolchains run nothing provided by the go module (awesome properties!). the source code is verified through the go sum database (a transparency log containing go modules). the hash of the resulting binary is added to gobuild's own transparency log. so it can be publicly verified. the gobuilds service builds the binary itself, and has another instance (on a different platform & config) build the binary too, to ensure the binary is really reproducible (i'ld like other instances that i don't run myself as secondaries too). i no longer publish binaries for my applications (that i write in go). i just point to the "latest"-build link for the go module at gobuilds. also makes it easy for users (including myself) to get new builds for new go toolchains (which may include fixes to the (relatively large, and often used) standard library).
you still may not trust the public gobuilds instance. my hope is that people (eg software projects themselves, or distros, or other kinds of communities) will run & use their own gobuild instances and verify their builds against the public gobuilds service. win-win: gives them assurance their builds are really reproducible, and builds trust in the public gobuilds (keeping it honest, if someone sees a hash mismatch, they will speak up).
i usually don't get much enthusiasm for it though. (:
If I understand the notifications flow correctly: a device (typically mobile phone) will get a "registration" with a "push url" from its platform/provider (eg android/google or iphone/apple), which it hands to an application server (eg IMAP server), which then uses that to send notifications to the push url, "authenticating" with vapid. And due to vapid, no special account/preregistration is required for the application server to talk to the provider, hence decentralized (good!). The platform/provider behind the push url makes the notification appear at the device. It is quite a complicated way to get a message from server to device...
The post says it is about Android. But I'm online searches turns up documents about VAPID at apple/ios. Will it work there too? What about other platforms (eg non-google android-likes)?
what if microsoft decides they not only want to load the URL in messages, but also click links and click buttons? presumably this is to detect bad/dangerous content. bad people will also just put that dangerous stuff behind a link or button if it's that easy to evade their checking.
or why exactly are they following those links again? perhaps it is for previews instead of "security"?
from the article:
Over time, it also became OK for software to visit links in email to find out what was behind them.
why would that be OK? if i email a secret link to someone, i fully expect it to stay between the recipient and me. not some company reading along. but that's why i don't have accounts with these types of companies...