I've had this domain since 2006. Around 2008 I decided to use Google Suite to manage its e-mail. At the time they were giving free accounts for personal use. Isn't free good? Of course, as time passed I began understanding that is wasn't free as in free beer, but as in you don't see money flowing out of your checking account. Of course, you see other things.

I have been thinking about moving away from Google since a few months ago, at least for everything regarding e-mail and the like. After the latest AMP for e-mail announcement, I read Fastmail's Email is your electronic memory and I couldn't agree more. So today I am moving my e-mail from Google to Fastmail. This article sums up all the steps I had to take to do so.

Current setup

Server side

My domain is hosted on Dreamhost, and they also handle everything regarding DNS entries. As the best way of setting up e-mail is via MX records, and not simply redirecting everything, the Google Suite delegation is made essentially like this:

  • MX.
$ host -t mx rinzewind.org
rinzewind.org mail is handled by 30 ASPMX3.GOOGLEMAIL.COM.
rinzewind.org mail is handled by 30 ASPMX5.GOOGLEMAIL.COM.
rinzewind.org mail is handled by 30 ASPMX4.GOOGLEMAIL.COM.
rinzewind.org mail is handled by 10 ASPMX.L.GOOGLE.COM.
rinzewind.org mail is handled by 20 ALT2.ASPMX.L.GOOGLE.COM.
rinzewind.org mail is handled by 30 ASPMX2.GOOGLEMAIL.COM.
rinzewind.org mail is handled by 20 ALT1.ASPMX.L.GOOGLE.COM.
  • SPF.
$ host -t txt rinzewind.org
rinzewind.org descriptive text "v=spf1 a include:dreamhost.com include:_spf.google.com -all"
  • DKIM keys.
$ host -t txt google._domainkey.rinzewind.org
google._domainkey.rinzewind.org descriptive text "v=DKIM1\; k=rsa\; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCn8aVdZ0nNbUNatu/jyEJd6CoLPvbxm2y4uXbsTCX5b2HtFbruARwLhMzgUZWlNZ+gnIO2z6d7v4tPjoRzPOGrdgn8KGHi7A+8O1w3OJh9/0tWMRPKCS9xNZS43SRlgb9MhCZ7GRPpa32/Ll15K25u5wtXjmMjp58AvAQi7XCkmwIDAQAB" 

This is all needed (apart from the Google Suite account) to make everything work. All e-mail for this domain gets automatically sent to Google's servers.

Client side

I check my e-mail from three different environments:

  • Locally, using mutt + offlineimap, and I couldn't be happier. All mail gets synchronized in local folders on maildir format. Mutt handles the local directories and also the SMTP connection to send e-mail. I have a script that runs offlineimap every minute using a cron job. I understand this is not for everybody, but just think that I am essentially using IMAP to read, SMTP to send.
  • Phone (Android Gmail's client)
  • Webmail.

That's pretty much everything. I use server-side filtering to keep all messages sorted and never used Gmail's tags in a way that wasn't purely folder-based.

As for calendars and other goodies, I don't use them much, so that's not a concern.

The migration

Server side

Fastmail offers a 30-day free trial, so that's what I'll use initially. After that, it's 5 USD a month to have a custom domain and 25 GB storage, or 50 USD if paid anually.

Immediately after the account creation I get an e-mail in Fastmail's inbox with instructions to set up my MX records. While they can host my DNS for me, I'd rather keep it in my current hosting, so I follow these instructions. On the Settings -> Domains page I click on Show DNS settings to see the config Fastmail would use if they were to fully host it. Then, on the Dreamhost control panel I add the MX records and a bunch of other ones, including all the SRV for service auto-discovery, CNAME for DKIM delegation and TXT for SPF.

$ host -t mx rinzewind.org
rinzewind.org mail is handled by 20 in2-smtp.messagingengine.com.
rinzewind.org mail is handled by 10 in1-smtp.messagingengine.com.

$ host -t txt rinzewind.org
rinzewind.org descriptive text "v=spf1 a include:dreamhost.com include:spf.messagingengine.com ?all"

The DKIM entries, as mentioned above are CNAMEs:

$ host fm1._domainkey.rinzewind.org
fm1._domainkey.rinzewind.org is an alias for fm1.rinzewind.org.dkim.fmhosted.com.

The same goes for fm2._domainkey.rinzewind.org, fm3._domainkey.rinzewind.org and mesmtp._domainkey.rinzewind.org. If you did everything alright, you will see two messages (DKIM is correctly configured and SPF is correctly configured) under Settings -> Domains after the records have been propagated.

While I am at it, I activate 2FA and generate an application password for the local mutt + offlineimap combo (I like that application passwords can be created with different permissions -- I only need IMAP and SMTP, so that's what I choose). While DNS will take a while to propagate everywhere, I see some e-mails start appearing on my inbox, so I begin filtering them while I create new folders. I also create a special folder to feed it spam. So far, everything has been quite painless, apart from the fact that I need to adapt to a different user interface, but that's expected. The only thing I've noticed is that Gmail's auto-detection of mailing lists is better. With Fastmail sometimes it works, sometimes I need to specify a specific header (List-Owner, typically) and filter on that. This normally happens when List-Id is missing. Not much of a hassle, anyway.

As I have mutt set up to not save any sent e-mail (Gmail takes care of that), on Settings -> Identities & Fetch I edit my e-mail address, then click on Show advanced preferences and mark the checkbox next to Save a copy when sending through 3rd party email clients to mimic that behavior.

Client side

offlineimap

My starting point is this config file. I moved my previous ~/Mail folder to ~/Mail_old and stop the old cron job so I don't get any conflicts.

This is the .offlineimaprc file I ended up with:

[general]
ui = ttyui
accounts = Fastmail

[Account Fastmail]
localrepository = Fastmail-Local
remoterepository = Fastmail-Remote

[Repository Fastmail-Local]
type = Maildir
localfolders = ~/Mail/

[Repository Fastmail-Remote]
type = IMAP
remoteuser = chema@rinzewind.org
remotehost = imap.fastmail.com
remotepassfile = ~/.creds/fastmail.pass
maxconnections = 3
ssl = yes
sslcacertfile = /etc/ssl/certs/ca-certificates.crt
folderfilter = lambda foldername: foldername not in ['Archive']
expunge = yes

After all the initial synchronizations, I reactivate the cron job.

Mutt

There's not much to change. The SMTP server, obviously, is different:

set smtp_url = 'smtps://chema@rinzewind.org@smtp.fastmail.com:465/'

Also, Gmail moved to the Trash folder all messages without any label on them. As here the system is different, we can tell mutt that instead of deleting messages (they're deleted for good with the standard config) they should be moved to the Trash folder. I used to have a macro for doing this, as I understood this functionality was missing from the original mutt, though there was a trash patch, but apparently there is already a proper option; I have a Ubuntu 14.04 and that option also shows up on the local documentation. So there:

set trash = "+Trash"

Also, I am not interested in certain folders. Plus, tell mutt to move spam where Fastmail is going to expect it:

mailboxes `find ~/Mail/ -type d -name cur -printf '%h\n'|sort|grep -v learnspam|grep -v Trash|grep -v Spam|tr "\n" " "`
macro index,pager S "<save-message>=learnspam<enter><enter><refresh>" "Spam Message"

Phone

I just installed the Fastmail app.

Wrapping up

Getting all old e-mail into the new account

Once I saw there was no more incoming email into the Gmail account, I clicked on the Import & Export option on Fastmail and filled in the IMAP credentials for the Google Suite account. I chose the Select folders to fetch option, as I was only interested in a bunch of them. This took almost an hour, and in the end I had all my old e-mail as subfolders of a new migrated folder. Then I just had to move stuff in place and delete that temporary placeholder.

Last, but not least: pay

Pay for stuff so stuff doesn't pay with you.


All in all, it's all been done in a morning. I still have to set up a few filters, but I think that's pretty much it.