Setup DKIM Domain on Office 365 through PowerShell

Things you need to setup DKIM domain Office 365 is permission to edit DNS Management, admin to manage Microsoft365 Exchange Online and Azure Active Directory.

If you want to setup SPF, DMARC, and DKIM on Microsoft365 (formerly Office365) Exchange Online, read previous part about How to Setup SPF and DMARC with some simple explanation first.

On Microsoft365 with Exchange Online you can setup your own domain so it pointed to Exchange Online “MTA” in order to enable DKIM certificate of your mail server (Exchange Online) related to your domain.

To do this, make sure you are connected to internet on your Windows PC. Open PowerShell, you need to Run as Administrator.

WARNING! Do not close PowerShell until Disconnect command executed at the end of this setting guide.

STEP 1: Install Prerequisite

Install AzureAD, MSOnline, and ExchangeOnlineManagement on PowerShell with this command:

Install-Module -Name AzureAD
Install-Module -Name MSOnline
Install-Module -Name ExchangeOnlineManagement

STEP 2: Save Credential

Set execution policy and create $credential variable and its value with username and password of Microsoft365 with Administrator privilege. In this note I will use dummy username is [email protected] and password is 123456. My primary domain is primary.dom , but domain I want to sign DKIM is my secondary added domain on Microsoft365, let say additional.dom. you can add domain through Microsoft Admin Center on Settings, Domains, Add Domain. Change this username, password, primary.dom, and additional.dom with yours. Use this command to set execution policy and create $credential variable:

Set-ExecutionPolicy RemoteSigned
$credential = Get-Credential

A small window to input username and password should be appear, this is for credential. Input username [email protected] and password 123456.

STEP 3: Connect to Azure Active Directory, Microsoft Online Service, and Exchange Online

Connect to Azzure Active Directory with previously set variable $credential:

Connect-AzureAD -Credential $credential

Output generated should be as bellow:

Account            Environment  TenantId      TenantDomain   AccountType
-------            -----------  --------      ------------   -----------
[email protected]   AzureCloud   xxxx-xxxx-…   primary.dom    User

Connect to Microsoft Online Service and Exchange Online using previously saved variable $credential:

Connect-MsolService -Credential $credential
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -Credential $credential -ShowProgress $true

Output generated should be looks alike as follow:

The module allows access to all existing remote PowerShell (V1) cmdlets in addition to the 9 new, faster, and more reliable cmdlets.
|---------------------------------------------------------------------------|
| Old Cmdlets                         | New/Reliable/Faster Cmdlets         |
|---------------------------------------------------------------------------|
| Get-CASMailbox                      | Get-EXOCASMailbox                   |
| Get-Mailbox                         | Get-EXOMailbox                      |
| Get-MailboxFolderPermission         | Get-EXOMailboxFolderPermission      |
| Get-MailboxFolderStatistics         | Get-EXOMailboxFolderStatistics      |
| Get-MailboxPermission               | Get-EXOMailboxPermission            |
| Get-MailboxStatistics               | Get-EXOMailboxStatistics            |
| Get-MobileDeviceStatistics          | Get-EXOMobileDeviceStatistics       |
| Get-Recipient                       | Get-EXORecipient                    |
| Get-RecipientPermission             | Get-EXORecipientPermission          |
|---------------------------------------------------------------------------|
To get additional information, run: Get-Help Connect-ExchangeOnline or check https://aka.ms/exops-docs
Send your product improvement suggestions and feedback to [email protected]. For issues related to the module, contact Microsoft support. Don't use the feedback alias for problems or support issues.

If any difference showed, don’t worry. This output just an explanation ‘changelog’ of updated ExchangeOnline PowerShell Module.

Since you want to sign DKIM for your additional domain –additional.dom-. Make sure you are have privilege to modify DNS record of your additional.dom. Some of domain registrar or hosting provider has its own DNS management system. In this case, I use Cloudflare for my DNS Management. I assume you know how to add DNS Record on your registrar, hosting provider, or DNS provider. It is quietly similar procedure when you add additional domain to Microsoft365, you also add some DNS record of your domain. Microsoft also provide DNS Management on their Microsoft365 service. In this case your NS record pointed to Microsoft DNS management, autoconfiguration may apply.

STEP 4: Generate New DKIM Configuration

Continue on your PowerShell, create new DKIM Configuration by using this command:

New-DkimSigningConfig -DomainName additional.dom -KeySize 2048 -Enabled $True

You should get output on your PS like this one,

WARNING: The config was created but can't be enabled because the CNAME records aren't published. Publish the following two CNAME records, and then enable the config by using Set-Dkim SigningConfig.

selector1-additional-dom._domainkey.XXX***.onmicrosoft.com
selector2-additional-dom._domainkey.XXX***.onmicrosoft.com

Domain          Enabled
------          -------
additional.dom  False

It means your DNS record has no CNAME Record with DomainKey selector pointed to your Microsoft365 DomainKey.

STEP 5: Add CNAME Record to your additional.dom DNS Management

Type in PowerShell this command to know what kind of record should you add to your DNS management.

Get-DkimSigningConfig -Identity additional.dom | Format-List Selector1CNAME, Selector2CNAME

Result:

Selector1CNAME : selector1-additional-dom._domainkey.XXX***.onmicrosoft.com
Selector2CNAME : selector2-additional-dom._domainkey.XXX***.onmicrosoft.com

Add CNAME Record to your DNS management. In case you are using Clouflare, login to dash.cloudflare.com with additional.dom registered, select your additional.dom, and go to DNS. Click +Add record.
Choose Type with CNAME, fill in Name with “selector1._domainkey” and Target with Selector1CNAME result from above “selector1-additional-dom._domainkey.XXX***.onmicrosoft.com“, Leave TTL to Auto and change Proxy status to DNS only by clicking on orange-cloud logo next to Proxied text until it grayed, then click Save.

Repeat this step for selector2._domainkey. So, now you have 2 new CNAME Record as below:

Other than Cloudflare, key point of this step is add CNAME Record to your DNS management as follow:

selector1._domainkey.additional.dom IN CNAME selector1-additional-dom._domainkey.XXX***.onmicrosoft.com
selector2._domainkey.additional.dom IN CNAME selector2-additional-dom._domainkey.XXX***.onmicrosoft.com

If you still confuse on add CNAME Record, leave comment on this post, I will reply as soon as possible after read your comment. Do not hesitate to bother me.

STEP 6: Apply New DKIM Configuration

After additional CNAME Record saved, wait for minutes and leaves DNS Resolver to update this change. In my case while using Cloudflare, Microsoft DNS Resolver takes around 5-10 minutes to update. Meanwhile, you can try to apply new DKIM through PowerShell as follow:

Set-DkimSigningConfig -Identity additional.dom -Enabled $true

If Microsoft DNS Resolver not yet updated (automatically), you will get error message as follow:

CNAME record does not exist for this config. Please publish the following two CNAME records first.
{0}
{1}
+ CategoryInfo : InvalidOperation: (:) [Set-DkimSigningConfig], ValidationException
+ FullyQualifiedErrorId : [Server=XYZ***,RequestId=xxxxxx-xxxx-…,TimeStamp=MM/DD/YYY HH:MM:SS AM] [FailureCategory=Cmdlet-ValidationException] XXXXXX,Microsoft.Exchange.Management.SystemConfigurationTasks.SetDkimSigningConfig
+ PSComputerName : outlook.office365.com

You can wait in minutes (again) and apply this new DKIM (again) until error disapear .

Set-DkimSigningConfig -Identity additional.dom -Enabled $true

If no more error appeared, it means your new DKIM config already applied.

NOTE: You can config another domain on your Microsoft365 by following STEP 4 – STEP 6 with your additional2.dom, additional3.dom, etc., without relogin to AzureAD and ExchangeOnline.

After finish configure DKIM to all your domain, don’t forget to close connection.

STEP 7: Close Connection

After all process above, remember to disconnect from AzureAD and ExchangeOnline through this command:

Disconnect-ExchangeOnline
Disconnect-AzureAD

Now you can safely close PowerShell.

STEP 8: Check DKIM Status Through Security & Compliance

If anything is set, you can check through Office 365 Security & Compliance. On Threat Management > Policy > DKIM, select your domain additional.dom, make sure that Sign message for this domain with DKIM signatures status is set Enabled.

That is all you need to do to Configure DKIM for your domain on Microsoft 365 Online with ExchangeOnline.

Some suggestion would be appreciate….

Image Source:
DKIM Envelope Sign and Seal from Purple Envelope with Gold Sealing Wax | Sending fancy mail. | sk | Flickr

Setting SPF, DMARC, and DKIM Exchange Online

Most common way to increase mail reputation is using SPF Record, DMARC record, and create DKIM. How to setup on Microsoft 365, formerly Office 365 Exchange Online?

There are so many method to increase your mail delivery reputation. Better reputation means smaller chance your mail marked as spam or rejected by mail-filter server or by MTA during mail transfer. Most common way to increase mail reputation is using SPF Record, DMARC record, and create DKIM. How to setup on Microsoft365 (formerly Office365) Exchange Online? SPF Record and DMARC record way more easy since SPF and DMARC setup mostly “only” need you to configure TXT record on your DNS Record. Different way, DKIM a bit more complicated since DKIM need “DomainKey” and add some digital signature in your mail so other MTA can verify that your mail is authorized by domain owner.

A letter from you to your friend

Most easy explanation about how this triple-combo work is analogue with you send a letter from your home to your friend far away.

SPF state through your DNS Record that your home (your.mail.server) address is A. Something like, “Hello everyone. If you receive letter from sender with my name (X, your.domain) from my address (A, your.mail.server), then that is from me. Else, do not trust these mail”. So your friend address (B, your.friend.server) can easily check a letter he/she received should be trusted or rejected by checking sender (X, your.domain) and from address (A, your.mail.server), if both of them match, then mail should be trusted and forward this mail to your friend (Y, your.friend.inbox).

DKIM is more advance. Everytime you (X, your.domain) send a letter from your home (your.mail.server) there is a secret stamp to seal the envelope. If any of your friends receive a mail with your name (X, your.domain), they can check and verify your seal and stamp by match-checking stamp with secret DomainKey to make sure that this mail is come from you and unaltered. In thid DKIM scenario, there is some action should executed by your mail server (signing, stamp, and seal).

DMARC is different story. It is something like a suggestion to your friend server based on SPF and DKIM check result. So, you can give some suggestion options:

  1. If SPF is verified (pass) and DKIM is verified (pass), then I suggest mail should be trusted.
  2. If only SPF is verified (pass), then I suggest mail should be trusted.
  3. If only SPF is verified (pass), then I suggest mail should be rejected.
  4. If only DKIM is verified (pass), then I suggest mail should be trusted.
  5. If only DKIM is verified (pass), then I suggest mail should be rejected.
  6. If only one of them is verified (pass), then I suggest mail should be trusted.
  7. If only one of them is verified (pass), then I suggest mail should be rejected.
  8. If none of them verified (all fail), then I suggest mail should be trusted.
  9. If none of them verified (all fail), then I suggest mail should be rejected.

Did you think that 1st and 7th suggestion is best options? Me too.

All of this possible scenario is reported periodically to some pool server to build database (ex: agari) and create report. This report somehow periodically used by spam-filter or firewall application.

So, you need to setup this triple-combo to achieve this best suggestion scenario. You can setup SPF and DMARC by only add some TXT on your DNS Record. Since Microsoft365 use spf.protection.outlook.com for their MTA, then you only add this full domain name on your SPF record. Also, this DMARC use 1st and 7th suggestion as mentioned above.

yourdomain.com. IN TXT "v=spf1 include:spf.protection.outlook.com -all"
_dmarc.yourdomain.com. IN TXT "v=DMARC1; p=quarantine; sp=quarantine; adkim=s; aspf=s; fo=1; pct=80; ri=86400; rua=mailto:[email protected]; ruf=mailto:[email protected];"

That is how to add SPF and DMARC record. Next post will be covering about DKIM on Microsoft365 (previously Office365) ExchangeOnline.

Continue… Setup DKIM On Microsoft365 Through PowerShell

Image source:
Letter Envelope Address from How to address an envelope (today.com)

To dear our director…

On December 11th, 2020, director of company I worked at, who stand for this company from the first departed this world for another.

On December 11th, 2020, director of company I worked at, who stand for this company from the first departed this world for another. “It was way too sudden…” I thought to myself, as I am still in disbelief.

The news came in on the afternoon of December 11th. I received a message from Alfian through company’s chat group. Alfian is my closest working partner who also worked closely with our director during work from home due to COVID-19 soaring across entire world. I just so happened to be took a break for fresh air after online meeting with client, I was picking on my phone, and open some news feed. Because of that, I noticed the messenger app notification right away, and the moment I saw the first text line, a heavy “hah…” audibly slipped out of my mouth.

Couple hours before, Mas Agus also send some snap on our company’s group, inform us that our director need an intensive care in hospital.

The last time I spoke with our director through phone call was December 9th, so only few days passed since then. When he told me “my signal is poor” and told “unable to work within next couple days and so on” because of this. I responded and give some advice to get wireless extender from online market or connect through cable. Earlier, he told me that some office applications on their MacBook Pro troubled and request password to log in. He want to send it to me within couple days for repair.

I first came to know him six years ago, on early of July 2014. I had been interviewed as technical support for company by him. He is a director from the first and made a statement “it would be good if you can join us next week”. It only means I officially joined company starting next couple days after that.

As long as I know, he was the kind of person who liked to find the good in any situation and wanted to be kind to as many of the people in the office, even with far adrift difference generations. In some moment years ago, he told a joke that wasn’t funny for me and others (age or generation difference matter) but all of us was laugh loudly. Not because of joke matter but the way he said to us. Because of this and that, all personnel in our company so close to each other even to director. I clearly remember a moment right before November this year, he told us to keep in contact and if we need anything from him, just call and come to him, do not hesitate to bother him.

I can remember this as if it just yesterday, but I am not able to see him anymore.

Come to think of it, I never received the Mac from him, unable to repair it for him, and send it back to him.

Once time passes, he will find me with some handy tools on my bag, saying: “Oh, you must be a late person! I don’t need to repair my Mac again, all of my account passwordless, and everything is well here”. In a place with good weather, nice folks, nice scene, and everything.

Rest in peace, pak Ismu. You did really well.