Skip to content

Commit e42e92a

Browse files
committed
DNSHealth: bump to 1.1.2 and update providers/logic
Bump DNSHealth module to 1.1.2 and migrate MailProviders into the new version folder. Replace $PSScriptRoot usages with the module base ($MyInvocation.MyCommand.Module.ModuleBase) for MailProviders file access. Add DMARC-aware handling for SPF soft-fail (~all) in Read-SpfRecord (accept when DMARC p=reject at 100%, otherwise recommend -all). Remove Quad9 DNS-over-HTTPS resolver support from Resolve-DnsHttpsQuery and Set-DnsResolver. Update Microsoft365 MX pattern to include mail.eo.outlook.com. Rename and update Barracuda provider JSON (new name/links). Refresh PSGetModuleInfo metadata to reflect version, dates and file list.
1 parent 8d76ec6 commit e42e92a

18 files changed

Lines changed: 191 additions & 174 deletions

Modules/DNSHealth/1.1.0/MailProviders/BarracudaESS.json

Lines changed: 0 additions & 10 deletions
This file was deleted.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
RootModule = 'DNSHealth.psm1'
1313

1414
# Version number of this module.
15-
ModuleVersion = '1.1.0'
15+
ModuleVersion = '1.1.2'
1616

1717
# Supported PSEditions
1818
# CompatiblePSEditions = @()
Lines changed: 35 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1155,13 +1155,13 @@ function Read-MXRecord {
11551155
elseif ($Result.Status -ne 0 -or -not ($Result.Answer)) {
11561156
if ($Result.Status -eq 3) {
11571157
$ValidationFails.Add($NoMxValidation) | Out-Null
1158-
$MXResults.MailProvider = Get-Content "$PSScriptRoot\MailProviders\Null.json" | ConvertFrom-Json
1158+
$MXResults.MailProvider = Get-Content "$($MyInvocation.MyCommand.Module.ModuleBase)\MailProviders\Null.json" | ConvertFrom-Json
11591159
$MXResults.Selectors = $MXRecords.MailProvider.Selectors
11601160
}
11611161

11621162
else {
11631163
$ValidationFails.Add($NoMxValidation) | Out-Null
1164-
$MXResults.MailProvider = Get-Content "$PSScriptRoot\MailProviders\Null.json" | ConvertFrom-Json
1164+
$MXResults.MailProvider = Get-Content "$($MyInvocation.MyCommand.Module.ModuleBase)\MailProviders\Null.json" | ConvertFrom-Json
11651165
$MXResults.Selectors = $MXRecords.MailProvider.Selectors
11661166
}
11671167
$MXRecords = $null
@@ -1183,17 +1183,17 @@ function Read-MXRecord {
11831183
$MXRecords = $MXRecords | Sort-Object -Property Priority
11841184

11851185
# Attempt to identify mail provider based on MX record
1186-
if (Test-Path "$PSScriptRoot\MailProviders") {
1186+
if (Test-Path "$($MyInvocation.MyCommand.Module.ModuleBase)\MailProviders") {
11871187
$ReservedVariables = @{
11881188
'DomainNameDashNotation' = $Domain -replace '\.', '-'
11891189
}
11901190
if ($MXRecords.Hostname -eq '') {
11911191
$ValidationFails.Add($NoMxValidation) | Out-Null
1192-
$MXResults.MailProvider = Get-Content "$PSScriptRoot\MailProviders\Null.json" | ConvertFrom-Json
1192+
$MXResults.MailProvider = Get-Content "$($MyInvocation.MyCommand.Module.ModuleBase)\MailProviders\Null.json" | ConvertFrom-Json
11931193
}
11941194

11951195
else {
1196-
$ProviderList = Get-ChildItem "$PSScriptRoot\MailProviders" -Exclude '_template.json' | ForEach-Object {
1196+
$ProviderList = Get-ChildItem "$($MyInvocation.MyCommand.Module.ModuleBase)\MailProviders" -Exclude '_template.json' | ForEach-Object {
11971197
try { Get-Content $_ | ConvertFrom-Json -ErrorAction Stop }
11981198
catch { Write-Verbose $_.Exception.Message }
11991199
}
@@ -1345,7 +1345,7 @@ function Read-SpfRecord {
13451345
Author: John Duprey
13461346
#>
13471347
[CmdletBinding(DefaultParameterSetName = 'Lookup')]
1348-
Param(
1348+
param(
13491349
[Parameter(Mandatory = $true, ParameterSetName = 'Lookup')]
13501350
[Parameter(ParameterSetName = 'Manual')]
13511351
[string]$Domain,
@@ -1774,6 +1774,30 @@ function Read-SpfRecord {
17741774
$ValidationPasses.Add('The SPF record ends with a hard fail qualifier (-all). This is best practice and will instruct recipients to discard unauthorized senders.') | Out-Null
17751775
}
17761776

1777+
elseif ($AllMechanism -eq '~all') {
1778+
# Check DMARC policy for soft fail
1779+
$DmarcRejectPolicy = $false
1780+
try {
1781+
$DmarcPolicy = Read-DmarcPolicy -Domain $Domain -ErrorAction Stop
1782+
if ($DmarcPolicy.Policy -eq 'reject' -and ($DmarcPolicy.Percent -eq 100 -or $null -eq $DmarcPolicy.Percent)) {
1783+
$DmarcRejectPolicy = $true
1784+
}
1785+
} catch {
1786+
Write-Verbose "Unable to read DMARC policy: $($_.Exception.Message)"
1787+
}
1788+
1789+
if ($DmarcRejectPolicy) {
1790+
$ValidationPasses.Add('The SPF record ends with a soft fail qualifier (~all). With DMARC p=reject at 100%, this is acceptable as DMARC will enforce rejection.') | Out-Null
1791+
} else {
1792+
$ValidationFails.Add('The SPF record should end in -all to prevent spamming.') | Out-Null
1793+
$Recommendations.Add([PSCustomObject]@{
1794+
Message = "Replace '~all' with '-all' to make a SPF failure result in a hard fail."
1795+
Match = '~all'
1796+
Replace = '-all'
1797+
}) | Out-Null
1798+
}
1799+
}
1800+
17771801
elseif ($Record -ne '') {
17781802
$ValidationFails.Add('The SPF record should end in -all to prevent spamming.') | Out-Null
17791803
$Recommendations.Add([PSCustomObject]@{
@@ -1865,7 +1889,7 @@ function Read-SpfRecord {
18651889
# Output SpfResults object
18661890
$SpfResults
18671891
}
1868-
#EndRegion './Public/Records/Read-SPFRecord.ps1' 553
1892+
#EndRegion './Public/Records/Read-SPFRecord.ps1' 577
18691893
#Region './Public/Records/Read-TlsRptRecord.ps1' -1
18701894

18711895
function Read-TlsRptRecord {
@@ -2269,7 +2293,7 @@ function Resolve-DnsHttpsQuery {
22692293
if (!$Results) { throw 'Exception querying resolver {0}: {1}' -f $Resolver.Resolver, $Exception.Exception.Message }
22702294

22712295
if ($RecordType -eq 'txt' -and $Results.Answer) {
2272-
if ($Resolver -eq 'Cloudflare' -or $Resolver -eq 'Quad9') {
2296+
if ($Resolver -eq 'Cloudflare') {
22732297
$Results.Answer | ForEach-Object {
22742298
$_.data = $_.data -replace '" "' -replace '"', ''
22752299
}
@@ -2284,9 +2308,9 @@ function Resolve-DnsHttpsQuery {
22842308

22852309
function Set-DnsResolver {
22862310
[CmdletBinding(SupportsShouldProcess)]
2287-
Param(
2311+
param(
22882312
[Parameter()]
2289-
[ValidateSet('Google', 'Cloudflare', 'Quad9')]
2313+
[ValidateSet('Google', 'Cloudflare')]
22902314
[string]$Resolver = 'Google'
22912315
)
22922316

@@ -2306,17 +2330,10 @@ function Set-DnsResolver {
23062330
QueryTemplate = '{0}?name={1}&type={2}'
23072331
}
23082332
}
2309-
'Quad9' {
2310-
[PSCustomObject]@{
2311-
Resolver = $Resolver
2312-
BaseUri = 'https://dns.quad9.net:5053/dns-query'
2313-
QueryTemplate = '{0}?name={1}&type={2}'
2314-
}
2315-
}
23162333
}
23172334
}
23182335
}
2319-
#EndRegion './Public/Resolver/Set-DnsResolver.ps1' 35
2336+
#EndRegion './Public/Resolver/Set-DnsResolver.ps1' 28
23202337
#Region './Public/Tests/Test-DNSSEC.ps1' -1
23212338

23222339
function Test-DNSSEC {
File renamed without changes.
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"Name": "Barracuda Email Gateway Defense",
3+
"_MxComment": "https://campus.barracuda.com/product/emailgatewaydefense/doc/167976430/step-2-configure-microsoft-365-for-inbound-and-outbound-mail",
4+
"MxMatch": "ess(?<Country>.[a-z]{2})?.barracudanetworks.com",
5+
"_SpfComment": "https://campus.barracuda.com/product/emailgatewaydefense/doc/167976840/sender-policy-framework-for-outbound-mail",
6+
"SpfInclude": "spf.ess{0}.barracudanetworks.com",
7+
"SpfReplace": ["Country"],
8+
"_DkimComment": "No configuration found",
9+
"Selectors": [""]
10+
}
File renamed without changes.

Modules/DNSHealth/1.1.0/MailProviders/HornetSecurity.json renamed to Modules/DNSHealth/1.1.2/MailProviders/HornetSecurity.json

File renamed without changes.
File renamed without changes.

Modules/DNSHealth/1.1.0/MailProviders/Microsoft365.json renamed to Modules/DNSHealth/1.1.2/MailProviders/Microsoft365.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"Name": "Microsoft 365",
3-
"MxMatch": "mail.protection.outlook.com|mx.microsoft",
3+
"MxMatch": "mail.protection.outlook.com|mx.microsoft|mail.eo.outlook.com",
44
"SpfInclude": "spf.protection.outlook.com",
55
"Selectors": ["selector1", "selector2"],
66
"MinimumSelectorPass": 1,
File renamed without changes.

0 commit comments

Comments
 (0)