When I got this domain I ended up getting a Fastmail account based on the recommendation of a coworker. I hadn’t done any meaningful custom email outside of G-suite, well, maybe ever. Anyways, my quicksand.tech mail was pretty under utilized, and there wasn’t very much interesting for me to do with the platform.
Meanwhile, as evidenced here, and maybe through a cursory glance at my Twitter, I spend most of my workday in Office 365/Azure AD. But, because certain tasks aren’t able to be properly delegated (*cough* MFA *cough*) there is a lot of global admin stuff I have to rely on documentation or the kindness and availability of my co-workers in that space to show me what all is available. For a while now, I’ve said I’d just go ahead and get my own tenant set up but haven’t had the motivation…
Last night, I did it. Boring details below.
The first thing to do, obviously, was to get plan info.
I knew I wanted access to mail, Office 365 Advanced Threat Protection, and some of the Azure P1 features like Conditional Access.
First things first: I purchased Exchange Online Plan 1 ($4.00/mo). Checking out from the details page, I had to create a new onmicrosoft.com subdomain and initial account.
Initial setup is easy enough–before you’re even able to provide payment information, Microsoft makes sure you can verify your custom domain first. I cleared out all the existing MX and TXT records associated with Fastmail, and after a few minutes to allow the changes to replicate, I was good to go. After everything was verified, I was able to purchase my Exchange Online license and was granted access to the Office Admin portal.
The next step was to add the additional features I needed. From the Billing > Purchase Services portal I added Office 365 ATP Plan 1 ($2.00/mo), Exchange Online Protection ($1.00/mo), and Azure AD P1 ($6.00/mo). Altogether, this is a bit more than the $5/mo I was paying at Fastmail, but this is getting myself a lot closer to a test environment I can use to test new policies, particularly when it comes to Powershell and Graph API (a topic in which I’m severely lacking).
By verifying my domain, I was set to add my quicksand.tech as an alias to the global admin account that was created in the first step of this process…however, with the single license and default configuration, I wasn’t able to log in with my alias at quicksand.tech, just my onmicrosoft.com account. Mail was working, as an alias–I could email to my custom domain, but the account wasn’t real. The global admin onmicrosoft.com account had all the access.
To fix this, I went to Azure AD, created my new user with my email address for quicksand.tech. I then removed the EXO license from my global admin onmicrosoft.com account, and applied the EXO, O365 ATP, and AAD P1 licenses to the new account created with my custom domain.
I confirmed I was able to log into the new account and the mailbox existed–great!
I got a little ahead of myself, due to my prior experience with O365 ATP, and immediately jumped into the Security and Compliance Center. I added my account to the Anti-Spoofing policy, configured Anti-Spam, configured Safe Links, and configured Safe Attachments. (Do you see where this is going yet?)
I went to make sure that everything was working with the new account I created and assigned licenses too. I was able to log in, view the mailbox, configure MFA…but for some reason, I wasn’t receiving messages. I was able to send to my personal Gmail account, but receiving wasn’t working. My new O365 account could send to itself, however??? I checked the health status in my Office Admin Center and everything checked out. My MX records were fine. By all means, I should have been receiving email?
The Exchange Admin Center’s Mail Flow tool helped solve the puzzle. When I checked for inbound messages, they were hitting O365 then getting quarantined thanks to the lovely Anti-Spoofing policies I set up earlier. My display name on the quicksand.tech account matched the display name on my Gmail account. ATP thought it could have been an impersonation attempt, and sent the messages to quarantine. A quick trip to quarantine in Security and Compliance cleared it up–I released the messages and they popped up on my phone instantly…so I went back to my anti-spoofing policy and added a few of my personal accounts as trusted senders to ensure I don’t get caught up in that mistake again.
The initial setup handles the MX record as well as the SPF record for the custom domain. The next step for things I really wanted my email to serve as a testing grounds for was DKIM and DMARC.
DMARC was easy–only my O365 account should be sending on my behalf. In addition to the SPF hard fail (-all) setting, I set my DMARC policy to “reject” and send reports to my new address…I don’t anticipate getting many of these reports, so I don’t really mind if they drop in my inbox. I can filter them out later.
DKIM, surprisingly, was a little trickier. I think the issue was I was setting this all up too quickly, and O365 didn’t have enough time to catch up to all the changes I was making. Initially, going to the DKIM settings in EAC or Security and Compliance showed “No DKIM keys saved for this domain” without the ability to enable DKIM.
Using the New-DKIMSigningConfig with the -enabled $true flag for my onmicrosoft.com domain generated my DKIM keys and got the process rolling. I added the two required selector CNAMES to the DNS on quicksand.tech to point to the DKIM keys managed by Office365.
I could resolve the DNS names on Microsoft’s DNS to confirm the DKIM records were there. I could even resolve the CNAME on my own custom domain and verify that it pulled up the appropriate DKIM records from Microsoft. Checking the domain dashboard in the Office portal, I confirm the records existed as I needed them to. Despite all this, trying to enable DKIM for my custom domain continued to result in an error that “CNAME record does not exist for this config.” Resolving the record explicitly showed it was configured correctly, so I assumed it was just a latency thing. I gave up on it for the night and checked back in the morning…Still didn’t help. For some reason it seems Microsoft was not checking for the record even when you ask it to. Must have been determining something was not “changed” from their initial check and refused to proceed. Perhaps I got a little out of order when I created my records (though as a CNAME it SHOULDN’T matter).
While I checked multiple times, and I am almost assured I’m not crazy–I ended up deleting the CNAMEs at my DNS and trying again. After removing and re-adding them, EAC allowed me to enable DKIM signing. Go figure.
The last thing I did was go to the Azure Portal and configure Conditional Access to ensure I was prompted for MFA when logging into the new account and to ensure that legacy protocols could not be leveraged to access the account (I used the new, baseline policy for legacy blocks). That about rounds up my daily experience with the tools, so I’m excited to dive deeper into some of the capabilities and options.
Anyways, that just about does it. After all that, I’ve got mail hosted in O365, I have MFA enabled for my account; legacy access denied; ATP policies configured; and SPF, DKIM, and DMARC set up. As I start exploring more I’d love to write more about what I’m figuring out. I got my first DMARC report from Gmail this morning. I took a cursory glance at migrating my site to Azure and that is definitely not cost effective today for the hassle of maintaining static pages…Next goals are to use the free edition of conditional access (since I only have a single P1 license) to enforce MFA for my gloabl admin, create a break-glass account that is exempt from MFA for emergencies, and potentially look at JIT admin roles (I can’t remember if I have the appropriate licenses to do so).