Quantcast
Channel: Terry Zink: Security Talk
Viewing all articles
Browse latest Browse all 243

A Powershell script to help you validate your DKIM config in Office 365

$
0
0

One of our support engineers (not me, so let’s give credit where credit is due) wrote a script to help you, as a customer of Office 365, validate for DKIM configuration once you have enabled it in the Admin Portal. We’ve added a few more checks to make it more clear, but you can also use this.

To verify your DKIM configuration:

1. Copy/paste the below script into a file, Validate-DkimConfig.ps1

2. Connect to Exchange Online using Powershell, making sure that the directory you are in is the same as where you saved the script above.

3. Type the following command in Powershell:

. .\Validate-DkimConfig.ps1.

4. To check the config for a single domain, run the following command:

Validate-DkimConfig <domain>

To show the full signing config, use the –showAll switch:

Validate-DkimConfig <domain> –showAll

To validate all domains for your organization, run the following command:

Validate-DkimConfig

You will be able to see if anything is wrong because the output is color coded.


function Validate-DkimConfig
{
    [cmdletbinding()]
    Param(
        [parameter(Mandatory=$false)]
        [string]$domain,
        [parameter(Mandatory=$false)]
        [switch]$showAll
    )

    if ($domain) {
        $config = Get-DkimSigningConfig -Identity $domain
        Validate-DkimConfigDomain $config -showAll:$showAll
    }
    else {
        $configs = Get-DkimSigningConfig
        foreach ($config in $configs) { Validate-DkimConfigDomain $config -showAll:$showAll}
    }

}

function Validate-DkimConfigDomain
{
    [cmdletbinding()]
    Param(
        [parameter(Mandatory=$true)]
        $config,
        [parameter(Mandatory=$false)]
        [switch]$showAll
    )

    # Display the configuration
    $domain = $config.Domain;
    $onmicrosoft = if ($domain.EndsWith("onmicrosoft.com")) { $true } else { $false }
    $actions = @()

    Write-Host "Config for $domain Found..." -ForegroundColor Yellow
    if ($showAll) {
        $config | fl
    }
    else {
        $config | Select Identity, Enabled, Status, Selector1CNAME, Selector2CNAME, KeyCreationTime, LastChecked, RotateOnDate, SelectorBeforeRotateonDate, SelectorAfterRotateonDate | fl
    }

    if (!$config.Enabled) {
        Write-Host "Config $($config.Name) Not Enabled" -ForegroundColor Yellow
        Write-Host
        $actions += "Config $($config.Name) needs to be Enabled"
    }

    # Get the DNS ENtries
    Write-Host "Locating DNS Entries..." -ForegroundColor Yellow
    $cname1 = "selector1._domainkey.$($domain)"
    $cname2 = "selector2._domainkey.$($domain)"
    $txt1 = $config.Selector1CNAME;
    $txt2 = $config.Selector2CNAME;

    $cname1Dns = Resolve-DnsName -Name $cname1 -Type CNAME -ErrorAction SilentlyContinue
    $cname2Dns = Resolve-DnsName -Name $cname2 -Type CNAME -ErrorAction SilentlyContinue
    $txt1Dns = Resolve-DnsName -Name $txt1 -Type TXT -ErrorAction SilentlyContinue
    $txt2Dns = Resolve-DnsName -Name $txt2 -Type TXT -ErrorAction SilentlyContinue

    # Validate Entries
    Write-Host "Validating DNS Entries..." -ForegroundColor Yellow   

    Write-Host   
    Write-Host "Config CNAME1 : $($config.Selector1CNAME)"
    if (!$onmicrosoft) {
        if ($cname1Dns) {
            Write-Host "DNS    CNAME1 : $($cname1Dns.NameHost)"
            Write-Host "TXT Hostname  : $($cname1)" 
            $match = if ($config.Selector1CNAME.Trim() -eq $cname1Dns.NameHost.Trim()) { $true } else { $false }
            if ($match) {
                write-host "Matched       : $($match)" -ForegroundColor Green
            } else {
                write-host "Matched       : $($match)" -ForegroundColor Red
                $actions += "Publish CNAME TXT Entry $($cname1) with value $($txt1)"
            }
        }
        else {
            write-host "DNS NotFound  : $($cname1)" -ForegroundColor Red
            $actions += "Publish DNS CNAME Entry $($cname1) with value $($txt1)"
        }             
    }

    Write-Host
    Write-Host "Config CNAME2 : $($config.Selector2CNAME)"
    if (!$onmicrosoft) {
        if ($cname2Dns) {
            Write-Host "DNS    CNAME2 : $($cname2Dns.NameHost)"
            Write-Host "TXT Hostname  : $($cname2)"
            $match = if ($config.Selector2CNAME.Trim() -eq $cname2Dns.NameHost.Trim()) { $true } else { $false }
            if ($match) {
                write-host "Matched       : $($match)" -ForegroundColor Green
            } else {
                write-host "Matched       : $($match)" -ForegroundColor Red
                $actions += "Publish DNS CNAME Entry $($cname2) with value $($txt2)"
            }
        }
        else {
            write-host "DNS NotFound  : $($cname2)" -ForegroundColor Red
            $actions += "Publish DNS CNAME Entry $($cname2) with value $($txt2)"
        }       
    }

    Write-Host
    Write-Host "Config   TXT1 : $($config.Selector1PublicKey)"
    if ($txt1Dns) {
        $key = $txt1Dns.Strings[0].Trim()
        Write-Host "DNS      TXT1 : $($key)"
        $match = if (Compare-PublicAndConfigKeys $key $config.Selector1PublicKey) { $true } else { $false }
        if ($match) {
            write-host "Key Match     : $($match)" -ForegroundColor Green
        } else {
            write-host "Key Match     : $($match)" -ForegroundColor Red
            $actions += "Public Key in TXT Entry $($txt1) needs to be republished..."
        }
    }
    else {
        write-host "DNS NotFound  : $($txt1)" -ForegroundColor Red
        $actions += "Microsoft TXT Entry $($txt1) not found so Signing Config needs to be recreated..."
    }

    Write-Host
    Write-Host "Config   TXT2 : $($config.Selector2PublicKey)"
    if ($txt2Dns) {
        $key = $txt2Dns.Strings[0].Trim()
        Write-Host "DNS      TXT2 : $($key)"
        $match = if (Compare-PublicAndConfigKeys $key $config.Selector2PublicKey) { $true } else { $false }
        if ($match) {
            write-host "Key Match     : $($match)" -ForegroundColor Green
        } else {
            write-host "Key Match     : $($match)" -ForegroundColor Red
            $actions += "Public Key in TXT Entry $($txt2) needs to be republished..."
        }       
    }
    else {
        write-host "DNS NotFound  : $($txt2)" -ForegroundColor Red
        $actions += "Microsoft TXT Entry $($txt2) not found so Signing Config needs to be recreated..."
    }

    # Write out neccessary Actions
    Write-Host
    if ($actions.Count -gt 0) {
        Write-Host "Required Actions..." -ForegroundColor Yellow
        foreach ($action in $actions) { write-host $action}
    }
}

function Compare-PublicAndConfigKeys([string] $publicKey, [string] $configKey)
{
    $match = $false;

    if (![string]::IsNullOrWhiteSpace($publicKey) -and ![string]::IsNullOrWhiteSpace($configKey))
    {    
        $regex = "p=(.*?);"
        $foundPublic = $publicKey -match $regex
        $publicValue = if ($foundPublic) { $matches[1] } else { $null }
        $foundConfig = $configKey -match $regex
        $configValue = if ($foundConfig) { $matches[1] } else { $null }

        if ($foundPublic -and $foundConfig)
        {
            if ($publicValue.Trim() -eq $configValue.Trim())
            {
                $match = $true;
            }
        }
    }

    $match;
}


I hope you find this useful.


Viewing all articles
Browse latest Browse all 243

Trending Articles



<script src="https://jsc.adskeeper.com/r/s/rssing.com.1596347.js" async> </script>