Enabling Inbound SMTP DANE with DNSSEC in Exchange Online Using PowerShell

By default, SMTP mail transport across the internet uses Opportunistic TLS (STARTTLS). While opportunistic TLS encrypts mail in transit when both servers agree, it is vulnerable to active TLS downgrade (STRIPTLS) and Adversary-in-the-Middle (AitM) attacks: if an attacker intercepts the DNS lookup for your MX record or strips the 250-STARTTLS capability advertisement during the SMTP handshake, sending servers silently fall back to cleartext delivery or connect to a rogue mail server.

To eliminate this vulnerability, Microsoft Exchange Online supports Inbound SMTP DANE (DNS-based Authentication of Named Entities, RFC 7672) with DNSSEC.

In this guide, we compare Opportunistic TLS, MTA-STS, and DANE with DNSSEC, visualize the deployment sequence, and walk through the exact Exchange Online PowerShell commands (Enable-DnssecForVerifiedDomain and Enable-SmtpDaneInbound) to cryptographically lock down inbound mail delivery.


Opportunistic TLS vs. MTA-STS vs. SMTP DANE

FeatureOpportunistic TLSMTA-STS (RFC 8461)DANE with DNSSEC (RFC 7672)
Downgrade Protection❌ None (vulnerable to STRIPTLS)✅ Yes (via HTTPS policy file)✅ Yes (cryptographic DNS chain)
MX Spoofing Protection❌ None✅ Yes (pins MX hostnames)✅ Yes (DNSSEC signs MX & TLSA)
Certificate Authority TrustPublic CA requiredPublic CA requiredPinning via TLSA record (eliminates rogue CA risk)
External Web Hosting Required?NoYes (https://mta-sts.domain.com/.well-known/mta-sts.txt)No (100% hosted by Exchange Online DNS infrastructure)
[!TIP] Because Exchange Online hosts the DNSSEC-signed MX and TLSA records directly on Microsoft's .mx.microsoft infrastructure, DANE requires zero external web servers—unlike MTA-STS, which requires you to maintain an external HTTPS static web host for every domain.

How Exchange Online Inbound DANE Works

When you enable DNSSEC and Inbound DANE for a verified domain in Exchange Online, Microsoft transitions your domain from the legacy .mail.protection.outlook.com MX endpoint to a dedicated, **DNSSEC-signed *.mx.microsoft MX endpoint with Microsoft-managed TLSA records:

Exchange Online DNSSEC + Inbound SMTP DANE Rollout Flow
Phase 1: Domain DNS
Enable DNSSEC at Registrar
Sign your primary zone (`lab365.in`) & publish DS record at TLD
Phase 2: EXO PowerShell
Enable-DnssecForVerifiedDomain
Generates new DNSSEC-signed `*.mx.microsoft` MX value
Phase 3: Activate DANE
Enable-SmtpDaneInbound
Publishes `_25._tcp` TLSA records & enforces DANE

Step-by-Step Implementation Runbook

Prerequisites

1.
DNSSEC Must Be Enabled on Your Domain: Your DNS provider (Cloudflare, Azure DNS, AWS Route 53, GoDaddy, etc.) must have DNSSEC enabled for your domain, and the DS (Delegation Signer) record must be published at your domain registrar. 2. Direct MX to Exchange Online: Inbound DANE in Exchange Online applies when your domain's MX record points directly to Exchange Online (not to a third-party gateway). 3. Exchange Online PowerShell: Connect as Exchange Administrator or Global Administrator:
POWERSHELL
Import-Module ExchangeOnlineManagement
Connect-ExchangeOnline -UserPrincipalName admin@lab365.in

Step 1: Enable DNSSEC for Your Verified Domain in Exchange Online

Run Enable-DnssecForVerifiedDomain to provision a DNSSEC-signed MX endpoint for your domain under the .mx.microsoft namespace:

POWERSHELL
$domain = "lab365.in"

$dnssecResult = Enable-DnssecForVerifiedDomain -DomainName $domain
$dnssecResult | Format-List DomainName, DnssecFeatureStatus, ExpectedMxRecord

Sample output:

TEXT
DomainName          : lab365.in
DnssecFeatureStatus : Enabled
ExpectedMxRecord    : @{Name=lab365-in.v1.mx.microsoft; Preference=0; TTL=3600}

[!IMPORTANT] Do not delete your old MX record yet!** First add the new .mx.microsoft MX record with a lower priority (higher preference number, e.g., 20 or 30) alongside your existing .mail.protection.outlook.com (priority 0 or 10) MX record so you can test it safely.

Step 2: Update Your Public MX Record

1. In your DNS provider portal, add the new MX record returned by ExpectedMxRecord (e.g., lab365-in.v1.mx.microsoft) at priority 30. 2. Wait 15–30 minutes for DNS TTL propagation. 3. Once verified, change the priority of lab365-in.v1.mx.microsoft to 0 and remove the legacy lab365-in.mail.protection.outlook.com MX record.

Verify the DNSSEC status in Exchange Online:

POWERSHELL
Get-DnssecStatusForVerifiedDomain -DomainName "lab365.in" | Format-List

Step 3: Enable Inbound SMTP DANE (Enable-SmtpDaneInbound)

Once your domain's MX record points exclusively to the new .mx.microsoft endpoint and Get-DnssecStatusForVerifiedDomain reports healthy, activate Inbound DANE using Enable-SmtpDaneInbound:

POWERSHELL
Enable-SmtpDaneInbound -DomainName "lab365.in" -NotifyEmail "[email protected]"

Exchange Online immediately provisions and signs the _25._tcp.<your-mx>.mx.microsoft TLSA records in DNS.


Step 4: Verify Inbound DANE & TLSA Posture

Run Get-SmtpDaneInboundStatus to confirm that DANE is operational and inspect the active TLSA records:

POWERSHELL
Get-SmtpDaneInboundStatus -DomainName "lab365.in" | Format-List

Production PowerShell Script: Multi-Domain DNSSEC & DANE Readiness Auditor

If you manage dozens of custom domains in your tenant, run this diagnostic script to audit which domains are still on legacy .mail.protection.outlook.com MX records and which have DNSSEC and Inbound DANE active.

POWERSHELL
<#
.SYNOPSIS
    Audits all verified domains in Exchange Online for DNSSEC and Inbound SMTP DANE status.
.DESCRIPTION
    Checks MX records, DNSSEC status (Get-DnssecStatusForVerifiedDomain), and
    SMTP DANE status (Get-SmtpDaneInboundStatus) across all accepted domains.
.NOTES
    Author: Sunil Chauhan (https://www.lab365.in)
    Requirements: ExchangeOnlineManagement
#>

[CmdletBinding()]
param (
    [string]$ExportPath = ".\EXO_DANE_DNSSEC_Audit_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
)

Write-Host "==========================================================" -ForegroundColor Cyan
Write-Host "  Exchange Online: DNSSEC & Inbound SMTP DANE Auditor     " -ForegroundColor Cyan
Write-Host "==========================================================" -ForegroundColor Cyan

$acceptedDomains = Get-AcceptedDomain | Where-Object { $_.DomainName -notlike "*.onmicrosoft.com" }
$report = [System.Collections.Generic.List[PSCustomObject]]::new()

foreach ($d in $acceptedDomains) {
    $domainName = $d.DomainName
    Write-Host "[*] Checking domain: $domainName..." -ForegroundColor Yellow

    # Resolve public MX
    $mxRecords = Resolve-DnsName -Name $domainName -Type MX -ErrorAction SilentlyContinue |
                 Where-Object { $_.QueryType -eq 'MX' } |
                 Sort-Object Preference
    $primaryMx = if ($mxRecords) { $mxRecords[0].NameExchange } else { "No MX Found" }
    $usesModernMx = $primaryMx -like "*.mx.microsoft"

    # Query EXO DNSSEC & DANE status
    $dnssec = Get-DnssecStatusForVerifiedDomain -DomainName $domainName -ErrorAction SilentlyContinue
    $dane   = Get-SmtpDaneInboundStatus -DomainName $domainName -ErrorAction SilentlyContinue

    $dnssecState = if ($dnssec) { [string]$dnssec.DnssecFeatureStatus } else { "NotConfigured" }
    $daneState   = if ($dane)   { [string]$dane.SmtpDaneStatus }        else { "Disabled" }

    $recommendation = if ($daneState -eq "Enabled") {
        "Compliant: DNSSEC + Inbound DANE Active"
    } elseif ($usesModernMx -and $dnssecState -eq "Enabled") {
        "Ready for DANE: Run Enable-SmtpDaneInbound"
    } elseif ($primaryMx -like "*.mail.protection.outlook.com") {
        "Legacy MX: Run Enable-DnssecForVerifiedDomain & migrate to *.mx.microsoft"
    } else {
        "3rd-Party MX or Unconfigured ($primaryMx)"
    }

    $report.Add([PSCustomObject]@{
        DomainName        = $domainName
        DomainType        = $d.DomainType
        PrimaryMX         = $primaryMx
        UsesModernMx      = $usesModernMx
        ExoDnssecStatus   = $dnssecState
        InboundDaneStatus = $daneState
        Recommendation    = $recommendation
    })
}

$report | Format-Table DomainName, PrimaryMX, ExoDnssecStatus, InboundDaneStatus, Recommendation -AutoSize
$report | Export-Csv -Path $ExportPath -NoTypeInformation -Encoding utf8
Write-Host "[+] Audit report saved to: $ExportPath" -ForegroundColor Green

Summary Checklist

  • [ ] Enable DNSSEC signing on your DNS zone and publish the DS record at your domain registrar.
  • [ ] Run Enable-DnssecForVerifiedDomain -DomainName <domain> in Exchange Online PowerShell.
  • [ ] Transition your domain's MX record from .mail.protection.outlook.com to the new *.mx.microsoft endpoint.
  • [ ] Run Enable-SmtpDaneInbound -DomainName <domain> to publish _25._tcp TLSA records.
  • [ ] Configure TLS-RPT (_smtp._tls.<domain> TXT record) to receive daily reports on TLS and DANE negotiation failures.

Related reading: Configuring Trusted ARC Sealers in Exchange Online (Set-ArcConfig) · Multi-Domain SPF, DKIM, and DMARC Audit Script for Microsoft 365