Courtnix Blog

Migrating My Email to Stalwart



I have been self hosting my own email for quite some time now on OpenBSD. In the beginning, I had a little trouble with getting out of peoples spam boxes, but eventually my mail server became my least troublesome server since there has only been 2 people on the server, not much room to get on a spam list.

My configuration has been to use OpenSMTPd, dovecot, and rspamd to handle everything. My server was never quite complete, admittedly, since I never got spam filtering right. I never got spam though until I put one alias out on a website. I expected spam, and never got much. The amount was so little that when I did get spam to that recipient, I just marked it as spam (which did nothing) and moved on. Maybe I was getting hit with spam a lot, but I had some basic filters already with OpenSMTPd and I imagine that handled a lot of the real crud. It was smooth sailing.

Why The Switch?

My real pain points were with getting my spam filter set, which, I just needed to add spam headers at the right place. I also was seeing that Dovecot has been in the works of removing features from their open source version and putting them behind a "Pro" plan. When I saw that dovecot is in the market of ensh**ification, I knew it was time to move on. I don’t mind the FOSS core, proprietary extensions model. I don’t like when a project starts rug pulling features. Looking for an alternative made me realize some of these alternatives also support CalDAV/CardDAV, which I am interested in, and will touch on that later as a side bar.

Stalwart was an option I stumbled upon some time ago and forgot about. I think because there was no OpenBSD support. It did land in ports earlier this year, then again when I was ready to kick the tires I saw it got updated to the latest (at the time) v0.14.1. What got me interested was the CalDAV/CardDAV support, JMAP, and all the batteries included to do email. Bonus points to OIDC, which I very crappily have set up but it would be really cool to integrate. I also really like the admin UI. I am not much of a point and click guy, but this is nice. I also like that there are all sorts of backends to scale up a Stalwart mail cluster. I don’t have that need right now though, so I am just using RocksDB.

The Switch

I wanted to detach my email domain from my daily sending domains. So, I created a new domain name and spun up my server under that. I really wanted to try out the Enterprise features, mostly because I like pretty graphs and metrics and wanted to look into the tenant feature. So, I created tenants, domains, user accounts, groups, etc. I tried to get close to what I had on my previous server, but with changes to make up for bad decisions.

I also had all the DNS records and such figured out for my sending domain. Stalwart has a very handy page under domains that shows you all the DNS records you will ever want. I let that run for a while but with no real email being sent. None of my daily accounts had been moved, but I was ready to start getting things moved over.

The Rush

So, I only thought I would start with one domain today, and figured I would start with the email accounts for the previous sending domain. That wasn’t all that smart as I had my other domain pointing to that for the mail records. So heck, I was here now and just started the whole migration. Was this the right path? Probably not.

Migration Steps

Here are the steps I took. I have very few accounts, so only me and one other would notice the disruption, and I know they wouldn’t notice.

Note that prior to this, I lowered TTLs to 5 minutes on all necessary DNS records. That way stuff wouldn’t be going to the old server potentially for many days.

  1. Made sure all the DKIM, DMARC, SPF records and all were correct for each domain

  2. Updated MX records with priority to the old server and the new one (with lower priority)

  3. used imapsync to sync mailboxes between servers.

    1. This only worked because I had credentials to all the accounts

  4. Removed old MX record priority and kept only the new one

  5. Did a check with imapsync again to look for mail that went to the old server, this is what I wanted:

    1. "The sync looks good, all 1410 identified messages in host1 are on host2."

  6. Once all boxes were synced, I started bumping TTLs up higher on my DNS records

Looking Back

This was majorly a thought experiment as I have intentions on doing this on a larger deployment and with users that really, heavily rely on email. I think this is something that will take more user interaction to do neatly for each inbox in the environment I am in. I will also refine my steps and timing. I will cross that bridge when I get there. However, this was a very helpful test for me.

I am very happy with my switch. I like how it is easier to manage accounts and domains. I like the built-in features Stalwart has. I don’t mind touching other servers, but this is just a nice setup and I look forward to the 1.0 realease that is incoming. I think Stalwart has a bright future. Now I just hope the clients will catch up and we get some JMAP support coming along. ;)

Last thing I am working on is Sieve scripts. Dovecot would do INBOX.Example, but apparenty Stalwart does syntax INBOX/Example. Still trying to confirm that, but so far seemingly my inbox isn’t being sorted right..I’ll get there.

Final Thoughts (Sidebar)

Earlier I mentioned my interest in CalDAV/CardDAV. Since people rely on contact syncing a lot for sending email, it makes sense to make this a part of Stalwart. Also, I have entered into an environment where calendar sharing and invites is very heavily used. It is handy to do. So it also makes sense to have Stalwart handle calendar since invites are often sent via email. Nothing against Nextcloud, but I wouldn’t mind moving calendar and contacts off Nextcloud. Some combo of Apple and Nextcloud has issues with syncing contacts, and I would be okay with putting calendar/contacts in a more logical place.

One Problem

I was initially drafting up doing that, but I ran into a problem with calendar sharing. Stalwart DOES support sharing calendars via CalDAV for individual users, but practically no clients do that. Not on iOS (but I hear you can on macOS?), nor Thunderbird, anything really. There are a couple but it is just well out of the reach of the users I am targeting on my own server. I can do a shared calendar with groups and all, but because of lack of client support, my users cannot share without admin intervention. Nextcloud at least makes this easy to share calendars with other Nextcloud users. In my realm of use, this may not matter an inch. But at scale, this won’t work well. Since there’s word about more JMAP clients coming around, maybe we will see that change. JMAP is pretty new and not well adopted yet. It could provide for a better ecosystem, at least I hope.

For now, I will play with what I have, and hope I don’t cause too much trouble.