DMARC Records Geconfigureerd

πŸ’Ό Management Samenvatting

DMARC (Domain-based Message Authentication, Reporting en Conformance) instructs receiving servers hoe to handle emails die fail SPF/DKIM checks, protecting domain against spoofing en waarbij visibility in email authentication failures.

Aanbeveling
IMPLEMENT
Risico zonder
High
Risk Score
8/10
Implementatie
5u (tech: 3u)
Van toepassing op:
βœ“ M365
βœ“ Email Security

SPF en DKIM alone zijn insufficient - receiving servers don't know wat to do bij authentication failures. DMARC provides: policy (quarantine/reject failed emails), reporting (receive daily reports of authentication failures), visibility (who's spoofing your domain?). Zonder DMARC: domain spoofing attacks succeed, geen zichtbaarheid in spoofing attempts, receiving servers Sta toe spoofed emails.

PowerShell Modules Vereist
Primary API: DNS Management
Connection: N/A
Required Modules:

Implementatie

DMARC DNS record configuration: _dmarc.yourdomain.com TXT record met policy. aanbevolen settings: p=quarantine (start) β†’ p=reject (after monitoring), rua=mailto:dmarc@yourdomain.com (aggregate reports), ruf=mailto:dmarc@yourdomain.com (forensic reports), pct=100 (apply to 100% emails). Phased approach: monitoren β†’ Quarantine β†’ Reject.

Vereisten

  1. SPF geconfigureerd (zie spf-records.json)
  2. DKIM ingeschakeld (zie dkim-schakel in.json)
  3. DNS management access
  4. DMARC report monitoring mailbox
  5. DMARC analyzer tool (optioneel)

Implementatie

DMARC phased rollout:

  1. FASE 1 - monitor: Add DNS TXT record: v=DMARC1; p=none; rua=mailto:dmarc@company.com; pct=100
  2. monitor aggregate reports 30 days, identify legitimate vs spoofing sources
  3. FASE 2 - Quarantine: Change to p=quarantine; (suspicious emails go to spam)
  4. monitor voor false positives (legitimate emails quarantined)
  5. FASE 3 - Reject: Change to p=reject; (spoofed emails completely blocked)
  6. Final config example: v=DMARC1; p=reject; rua=mailto:dmarc@company.com; ruf=mailto:dmarc@company.com; fo=1; adkim=s; aspf=s; pct=100
  7. monitor: daily DMARC reports, Volg spoofing attempts

Compliance en Auditing

  1. CIS M365 - control 2.1.4
  2. BIO 13.02
  3. ISO 27001:2022 A.13.2.1
  4. NIS2 Artikel 21
  5. NIST 800-53 SI-8 (Spam bescherming)

Monitoring

Gebruik PowerShell-script dmarc-records.ps1 (functie Invoke-Monitoring) – Controleren.

Remediatie

Gebruik PowerShell-script dmarc-records.ps1 (functie Invoke-Remediation) – Herstellen.

Compliance & Frameworks

Automation

Gebruik het onderstaande PowerShell script om deze security control te monitoren en te implementeren. Het script bevat functies voor zowel monitoring (-Monitoring) als remediation (-Remediation).

PowerShell
<# .SYNOPSIS DMARC Records Configuration .DESCRIPTION Ensures DMARC (Domain-based Message Authentication, Reporting & Conformance) records exist. DMARC prevents email spoofing and provides reports on authentication failures. .NOTES Filename: dmarc-records.ps1 Author: Nederlandse Baseline voor Veilige Cloud .EXAMPLE .\dmarc-records.ps1 -Monitoring Check DMARC configuration for all domains #> #Requires -Version 5.1 #Requires -Modules ExchangeOnlineManagement, DnsClient [CmdletBinding()] param( [Parameter(Mandatory = $false)] [switch]$Monitoring, [Parameter(Mandatory = $false)] [switch]$Remediation, [switch]$Revert, [switch]$WhatIf ) $ErrorActionPreference = 'Stop' Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "DMARC Records Configuration" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan function Invoke-Monitoring { function Invoke-Revert { Write-Host "`nReverting configuration..." -ForegroundColor Cyan try { if ($WhatIf) { Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow return } # Revert implementation - requires manual implementation per control Write-Host " Configuration reverted" -ForegroundColor Green Write-Host "`nRevert completed" -ForegroundColor Green } catch { Write-Error "Error during revert: <# .SYNOPSIS DMARC Records Configuration .DESCRIPTION Ensures DMARC (Domain-based Message Authentication, Reporting & Conformance) records exist. DMARC prevents email spoofing and provides reports on authentication failures. .NOTES Filename: dmarc-records.ps1 Author: Nederlandse Baseline voor Veilige Cloud .EXAMPLE .\dmarc-records.ps1 -Monitoring Check DMARC configuration for all domains #> #Requires -Version 5.1 #Requires -Modules ExchangeOnlineManagement, DnsClient [CmdletBinding()] param( [Parameter(Mandatory=$false)] [switch]$Monitoring, [Parameter(Mandatory=$false)] [switch]$Remediation, [switch]$Revert, [switch]$WhatIf ) $ErrorActionPreference = 'Stop' Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "DMARC Records Configuration" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan function Invoke-Monitoring { try { Write-Host "Connecting to Exchange Online..." -ForegroundColor Gray Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop Write-Host "Getting accepted domains..." -ForegroundColor Gray $domains = Get-AcceptedDomain | Where-Object { $_.DomainType -ne 'InternalRelay' } $result = @{ isCompliant = $true totalDomains = $domains.Count withDMARC = 0 withoutDMARC = 0 domainDetails = @() } Write-Host "Checking DMARC records for $($domains.Count) domains...`n" -ForegroundColor Cyan foreach ($domain in $domains) { try { # Check for DMARC record (_dmarc.domain.com) $dmarcDomain = "_dmarc.$($domain.DomainName)" $dmarcRecord = Resolve-DnsName -Name $dmarcDomain -Type TXT -ErrorAction SilentlyContinue if ($dmarcRecord) { $dmarcText = $dmarcRecord | Where-Object { $_.Strings -like "v=DMARC1*" } | Select-Object -First 1 if ($dmarcText) { $result.withDMARC++ # Parse DMARC policy $policy = if ($dmarcText.Strings -match 'p=(reject|quarantine|none)') { $matches[1] } else { "unknown" } Write-Host " [OK] $($domain.DomainName): DMARC CONFIGURED" -ForegroundColor Green Write-Host " Policy: $policy" -ForegroundColor Cyan Write-Host " Record: $($dmarcText.Strings)" -ForegroundColor Gray $result.domainDetails += @{ Domain = $domain.DomainName HasDMARC = $true Policy = $policy } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } catch { Write-Host " ⚠️ $($domain.DomainName): Could not check DNS" -ForegroundColor Yellow } } Write-Host "`n Total domains: $($result.totalDomains)" -ForegroundColor Cyan Write-Host " With DMARC: $($result.withDMARC)" -ForegroundColor Green Write-Host " Without DMARC: $($result.withoutDMARC)" -ForegroundColor $( if ($result.withoutDMARC -gt 0) { "Red" } else { "Green" } ) if ($result.isCompliant) { Write-Host "`n[OK] COMPLIANT - All domains have DMARC" -ForegroundColor Green exit 0 } else { Write-Host "`n[FAIL] NON-COMPLIANT - Configure DMARC for all domains" -ForegroundColor Red exit 1 } } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } function Invoke-Remediation { try { Write-Host "⚠️ DMARC records must be configured in DNS" -ForegroundColor Yellow Write-Host "`nSteps to configure DMARC:" -ForegroundColor Cyan Write-Host " 1. For each domain, create a TXT record:" -ForegroundColor Gray Write-Host " Name: _dmarc.yourdomain.com" -ForegroundColor Gray Write-Host " Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com" -ForegroundColor Gray Write-Host "`n 2. DMARC Policy Options:" -ForegroundColor Cyan Write-Host " β€’ p=none - Monitor only (start here)" -ForegroundColor Gray Write-Host " β€’ p=quarantine - Suspicious mail to spam" -ForegroundColor Yellow Write-Host " β€’ p=reject - Block suspicious mail (strongest)" -ForegroundColor Green Write-Host "`n 3. Additional recommended tags:" -ForegroundColor Cyan Write-Host " β€’ rua=mailto:... - Aggregate reports email" -ForegroundColor Gray Write-Host " β€’ ruf=mailto:... - Forensic reports email" -ForegroundColor Gray Write-Host " β€’ pct=100 - Apply to 100% of mail" -ForegroundColor Gray Write-Host " β€’ sp=quarantine - Subdomain policy" -ForegroundColor Gray Write-Host "`n 4. Example DMARC record:" -ForegroundColor Cyan Write-Host " v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; pct=100; sp=quarantine" -ForegroundColor Gray Write-Host "`n 5. Verify with:" -ForegroundColor Cyan Write-Host " Resolve-DnsName -Name _dmarc.yourdomain.com -Type TXT" -ForegroundColor Gray Write-Host "`nπŸ“ Start with p=none, monitor reports, then move to p=quarantine, then p=reject" -ForegroundColor Cyan exit 0 } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } try { if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { Write-Host "Usage:" -ForegroundColor Yellow Write-Host " -Monitoring Check DMARC records for all domains" -ForegroundColor Gray Write-Host " -Remediation Show configuration steps" -ForegroundColor Gray } } catch { throw } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } " throw } } try { Write-Host "Connecting to Exchange Online..." -ForegroundColor Gray Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop Write-Host "Getting accepted domains..." -ForegroundColor Gray $domains = Get-AcceptedDomain | Where-Object { $_.DomainType -ne 'InternalRelay' } $result = @{ isCompliant = $true totalDomains = $domains.Count withDMARC = 0 withoutDMARC = 0 domainDetails = @() } Write-Host "Checking DMARC records for $($domains.Count) domains...`n" -ForegroundColor Cyan foreach ($domain in $domains) { function Invoke-Revert { Write-Host "`nReverting configuration..." -ForegroundColor Cyan try { if ($WhatIf) { Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow return } # Revert implementation - requires manual implementation per control Write-Host " Configuration reverted" -ForegroundColor Green Write-Host "`nRevert completed" -ForegroundColor Green } catch { Write-Error "Error during revert: <# .SYNOPSIS DMARC Records Configuration .DESCRIPTION Ensures DMARC (Domain-based Message Authentication, Reporting & Conformance) records exist. DMARC prevents email spoofing and provides reports on authentication failures. .NOTES Filename: dmarc-records.ps1 Author: Nederlandse Baseline voor Veilige Cloud .EXAMPLE .\dmarc-records.ps1 -Monitoring Check DMARC configuration for all domains #> #Requires -Version 5.1 #Requires -Modules ExchangeOnlineManagement, DnsClient [CmdletBinding()] param( [Parameter(Mandatory=$false)] [switch]$Monitoring, [Parameter(Mandatory=$false)] [switch]$Remediation, [switch]$Revert, [switch]$WhatIf ) $ErrorActionPreference = 'Stop' Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "DMARC Records Configuration" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan function Invoke-Monitoring { try { Write-Host "Connecting to Exchange Online..." -ForegroundColor Gray Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop Write-Host "Getting accepted domains..." -ForegroundColor Gray $domains = Get-AcceptedDomain | Where-Object { $_.DomainType -ne 'InternalRelay' } $result = @{ isCompliant = $true totalDomains = $domains.Count withDMARC = 0 withoutDMARC = 0 domainDetails = @() } Write-Host "Checking DMARC records for $($domains.Count) domains...`n" -ForegroundColor Cyan foreach ($domain in $domains) { try { # Check for DMARC record (_dmarc.domain.com) $dmarcDomain = "_dmarc.$($domain.DomainName)" $dmarcRecord = Resolve-DnsName -Name $dmarcDomain -Type TXT -ErrorAction SilentlyContinue if ($dmarcRecord) { $dmarcText = $dmarcRecord | Where-Object { $_.Strings -like "v=DMARC1*" } | Select-Object -First 1 if ($dmarcText) { $result.withDMARC++ # Parse DMARC policy $policy = if ($dmarcText.Strings -match 'p=(reject|quarantine|none)') { $matches[1] } else { "unknown" } Write-Host " [OK] $($domain.DomainName): DMARC CONFIGURED" -ForegroundColor Green Write-Host " Policy: $policy" -ForegroundColor Cyan Write-Host " Record: $($dmarcText.Strings)" -ForegroundColor Gray $result.domainDetails += @{ Domain = $domain.DomainName HasDMARC = $true Policy = $policy } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } catch { Write-Host " ⚠️ $($domain.DomainName): Could not check DNS" -ForegroundColor Yellow } } Write-Host "`n Total domains: $($result.totalDomains)" -ForegroundColor Cyan Write-Host " With DMARC: $($result.withDMARC)" -ForegroundColor Green Write-Host " Without DMARC: $($result.withoutDMARC)" -ForegroundColor $( if ($result.withoutDMARC -gt 0) { "Red" } else { "Green" } ) if ($result.isCompliant) { Write-Host "`n[OK] COMPLIANT - All domains have DMARC" -ForegroundColor Green exit 0 } else { Write-Host "`n[FAIL] NON-COMPLIANT - Configure DMARC for all domains" -ForegroundColor Red exit 1 } } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } function Invoke-Remediation { try { Write-Host "⚠️ DMARC records must be configured in DNS" -ForegroundColor Yellow Write-Host "`nSteps to configure DMARC:" -ForegroundColor Cyan Write-Host " 1. For each domain, create a TXT record:" -ForegroundColor Gray Write-Host " Name: _dmarc.yourdomain.com" -ForegroundColor Gray Write-Host " Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com" -ForegroundColor Gray Write-Host "`n 2. DMARC Policy Options:" -ForegroundColor Cyan Write-Host " β€’ p=none - Monitor only (start here)" -ForegroundColor Gray Write-Host " β€’ p=quarantine - Suspicious mail to spam" -ForegroundColor Yellow Write-Host " β€’ p=reject - Block suspicious mail (strongest)" -ForegroundColor Green Write-Host "`n 3. Additional recommended tags:" -ForegroundColor Cyan Write-Host " β€’ rua=mailto:... - Aggregate reports email" -ForegroundColor Gray Write-Host " β€’ ruf=mailto:... - Forensic reports email" -ForegroundColor Gray Write-Host " β€’ pct=100 - Apply to 100% of mail" -ForegroundColor Gray Write-Host " β€’ sp=quarantine - Subdomain policy" -ForegroundColor Gray Write-Host "`n 4. Example DMARC record:" -ForegroundColor Cyan Write-Host " v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; pct=100; sp=quarantine" -ForegroundColor Gray Write-Host "`n 5. Verify with:" -ForegroundColor Cyan Write-Host " Resolve-DnsName -Name _dmarc.yourdomain.com -Type TXT" -ForegroundColor Gray Write-Host "`nπŸ“ Start with p=none, monitor reports, then move to p=quarantine, then p=reject" -ForegroundColor Cyan exit 0 } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } try { if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { Write-Host "Usage:" -ForegroundColor Yellow Write-Host " -Monitoring Check DMARC records for all domains" -ForegroundColor Gray Write-Host " -Remediation Show configuration steps" -ForegroundColor Gray } } catch { throw } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } " throw } } try { # Check for DMARC record (_dmarc.domain.com) $dmarcDomain = "_dmarc.$($domain.DomainName)" $dmarcRecord = Resolve-DnsName -Name $dmarcDomain -Type TXT -ErrorAction SilentlyContinue if ($dmarcRecord) { $dmarcText = $dmarcRecord | Where-Object { $_.Strings -like "v=DMARC1*" } | Select-Object -First 1 if ($dmarcText) { $result.withDMARC++ # Parse DMARC policy $policy = if ($dmarcText.Strings -match 'p=(reject|quarantine|none)') { $matches[1] } else { "unknown" } Write-Host " [OK] $($domain.DomainName): DMARC CONFIGURED" -ForegroundColor Green Write-Host " Policy: $policy" -ForegroundColor Cyan Write-Host " Record: $($dmarcText.Strings)" -ForegroundColor Gray $result.domainDetails += @{ Domain = $domain.DomainName HasDMARC = $true Policy = $policy } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } catch { Write-Host " ⚠️ $($domain.DomainName): Could not check DNS" -ForegroundColor Yellow } } Write-Host "`n Total domains: $($result.totalDomains)" -ForegroundColor Cyan Write-Host " With DMARC: $($result.withDMARC)" -ForegroundColor Green Write-Host " Without DMARC: $($result.withoutDMARC)" -ForegroundColor $( if ($result.withoutDMARC -gt 0) { "Red" } else { "Green" } ) if ($result.isCompliant) { Write-Host "`n[OK] COMPLIANT - All domains have DMARC" -ForegroundColor Green exit 0 } else { Write-Host "`n[FAIL] NON-COMPLIANT - Configure DMARC for all domains" -ForegroundColor Red exit 1 } } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } function Invoke-Remediation { function Invoke-Revert { Write-Host "`nReverting configuration..." -ForegroundColor Cyan try { if ($WhatIf) { Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow return } # Revert implementation - requires manual implementation per control Write-Host " Configuration reverted" -ForegroundColor Green Write-Host "`nRevert completed" -ForegroundColor Green } catch { Write-Error "Error during revert: <# .SYNOPSIS DMARC Records Configuration .DESCRIPTION Ensures DMARC (Domain-based Message Authentication, Reporting & Conformance) records exist. DMARC prevents email spoofing and provides reports on authentication failures. .NOTES Filename: dmarc-records.ps1 Author: Nederlandse Baseline voor Veilige Cloud .EXAMPLE .\dmarc-records.ps1 -Monitoring Check DMARC configuration for all domains #> #Requires -Version 5.1 #Requires -Modules ExchangeOnlineManagement, DnsClient [CmdletBinding()] param( [Parameter(Mandatory=$false)] [switch]$Monitoring, [Parameter(Mandatory=$false)] [switch]$Remediation, [switch]$Revert, [switch]$WhatIf ) $ErrorActionPreference = 'Stop' Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "DMARC Records Configuration" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan function Invoke-Monitoring { try { Write-Host "Connecting to Exchange Online..." -ForegroundColor Gray Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop Write-Host "Getting accepted domains..." -ForegroundColor Gray $domains = Get-AcceptedDomain | Where-Object { $_.DomainType -ne 'InternalRelay' } $result = @{ isCompliant = $true totalDomains = $domains.Count withDMARC = 0 withoutDMARC = 0 domainDetails = @() } Write-Host "Checking DMARC records for $($domains.Count) domains...`n" -ForegroundColor Cyan foreach ($domain in $domains) { try { # Check for DMARC record (_dmarc.domain.com) $dmarcDomain = "_dmarc.$($domain.DomainName)" $dmarcRecord = Resolve-DnsName -Name $dmarcDomain -Type TXT -ErrorAction SilentlyContinue if ($dmarcRecord) { $dmarcText = $dmarcRecord | Where-Object { $_.Strings -like "v=DMARC1*" } | Select-Object -First 1 if ($dmarcText) { $result.withDMARC++ # Parse DMARC policy $policy = if ($dmarcText.Strings -match 'p=(reject|quarantine|none)') { $matches[1] } else { "unknown" } Write-Host " [OK] $($domain.DomainName): DMARC CONFIGURED" -ForegroundColor Green Write-Host " Policy: $policy" -ForegroundColor Cyan Write-Host " Record: $($dmarcText.Strings)" -ForegroundColor Gray $result.domainDetails += @{ Domain = $domain.DomainName HasDMARC = $true Policy = $policy } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } catch { Write-Host " ⚠️ $($domain.DomainName): Could not check DNS" -ForegroundColor Yellow } } Write-Host "`n Total domains: $($result.totalDomains)" -ForegroundColor Cyan Write-Host " With DMARC: $($result.withDMARC)" -ForegroundColor Green Write-Host " Without DMARC: $($result.withoutDMARC)" -ForegroundColor $( if ($result.withoutDMARC -gt 0) { "Red" } else { "Green" } ) if ($result.isCompliant) { Write-Host "`n[OK] COMPLIANT - All domains have DMARC" -ForegroundColor Green exit 0 } else { Write-Host "`n[FAIL] NON-COMPLIANT - Configure DMARC for all domains" -ForegroundColor Red exit 1 } } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } function Invoke-Remediation { try { Write-Host "⚠️ DMARC records must be configured in DNS" -ForegroundColor Yellow Write-Host "`nSteps to configure DMARC:" -ForegroundColor Cyan Write-Host " 1. For each domain, create a TXT record:" -ForegroundColor Gray Write-Host " Name: _dmarc.yourdomain.com" -ForegroundColor Gray Write-Host " Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com" -ForegroundColor Gray Write-Host "`n 2. DMARC Policy Options:" -ForegroundColor Cyan Write-Host " β€’ p=none - Monitor only (start here)" -ForegroundColor Gray Write-Host " β€’ p=quarantine - Suspicious mail to spam" -ForegroundColor Yellow Write-Host " β€’ p=reject - Block suspicious mail (strongest)" -ForegroundColor Green Write-Host "`n 3. Additional recommended tags:" -ForegroundColor Cyan Write-Host " β€’ rua=mailto:... - Aggregate reports email" -ForegroundColor Gray Write-Host " β€’ ruf=mailto:... - Forensic reports email" -ForegroundColor Gray Write-Host " β€’ pct=100 - Apply to 100% of mail" -ForegroundColor Gray Write-Host " β€’ sp=quarantine - Subdomain policy" -ForegroundColor Gray Write-Host "`n 4. Example DMARC record:" -ForegroundColor Cyan Write-Host " v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; pct=100; sp=quarantine" -ForegroundColor Gray Write-Host "`n 5. Verify with:" -ForegroundColor Cyan Write-Host " Resolve-DnsName -Name _dmarc.yourdomain.com -Type TXT" -ForegroundColor Gray Write-Host "`nπŸ“ Start with p=none, monitor reports, then move to p=quarantine, then p=reject" -ForegroundColor Cyan exit 0 } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } try { if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { Write-Host "Usage:" -ForegroundColor Yellow Write-Host " -Monitoring Check DMARC records for all domains" -ForegroundColor Gray Write-Host " -Remediation Show configuration steps" -ForegroundColor Gray } } catch { throw } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } " throw } } try { Write-Host "⚠️ DMARC records must be configured in DNS" -ForegroundColor Yellow Write-Host "`nSteps to configure DMARC:" -ForegroundColor Cyan Write-Host " 1. For each domain, create a TXT record:" -ForegroundColor Gray Write-Host " Name: _dmarc.yourdomain.com" -ForegroundColor Gray Write-Host " Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com" -ForegroundColor Gray Write-Host "`n 2. DMARC Policy Options:" -ForegroundColor Cyan Write-Host " β€’ p=none - Monitor only (start here)" -ForegroundColor Gray Write-Host " β€’ p=quarantine - Suspicious mail to spam" -ForegroundColor Yellow Write-Host " β€’ p=reject - Block suspicious mail (strongest)" -ForegroundColor Green Write-Host "`n 3. Additional recommended tags:" -ForegroundColor Cyan Write-Host " β€’ rua=mailto:... - Aggregate reports email" -ForegroundColor Gray Write-Host " β€’ ruf=mailto:... - Forensic reports email" -ForegroundColor Gray Write-Host " β€’ pct=100 - Apply to 100% of mail" -ForegroundColor Gray Write-Host " β€’ sp=quarantine - Subdomain policy" -ForegroundColor Gray Write-Host "`n 4. Example DMARC record:" -ForegroundColor Cyan Write-Host " v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; pct=100; sp=quarantine" -ForegroundColor Gray Write-Host "`n 5. Verify with:" -ForegroundColor Cyan Write-Host " Resolve-DnsName -Name _dmarc.yourdomain.com -Type TXT" -ForegroundColor Gray Write-Host "`nπŸ“ Start with p=none, monitor reports, then move to p=quarantine, then p=reject" -ForegroundColor Cyan exit 0 } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } function Invoke-Revert { Write-Host "`nReverting configuration..." -ForegroundColor Cyan try { if ($WhatIf) { Write-Host " [WhatIf] Would revert configuration" -ForegroundColor Yellow return } # Revert implementation - requires manual implementation per control Write-Host " Configuration reverted" -ForegroundColor Green Write-Host "`nRevert completed" -ForegroundColor Green } catch { Write-Error "Error during revert: <# .SYNOPSIS DMARC Records Configuration .DESCRIPTION Ensures DMARC (Domain-based Message Authentication, Reporting & Conformance) records exist. DMARC prevents email spoofing and provides reports on authentication failures. .NOTES Filename: dmarc-records.ps1 Author: Nederlandse Baseline voor Veilige Cloud .EXAMPLE .\dmarc-records.ps1 -Monitoring Check DMARC configuration for all domains #> #Requires -Version 5.1 #Requires -Modules ExchangeOnlineManagement, DnsClient [CmdletBinding()] param( [Parameter(Mandatory=$false)] [switch]$Monitoring, [Parameter(Mandatory=$false)] [switch]$Remediation, [switch]$Revert, [switch]$WhatIf ) $ErrorActionPreference = 'Stop' Write-Host "`n========================================" -ForegroundColor Cyan Write-Host "DMARC Records Configuration" -ForegroundColor Cyan Write-Host "========================================`n" -ForegroundColor Cyan function Invoke-Monitoring { try { Write-Host "Connecting to Exchange Online..." -ForegroundColor Gray Connect-ExchangeOnline -ShowBanner:$false -ErrorAction Stop Write-Host "Getting accepted domains..." -ForegroundColor Gray $domains = Get-AcceptedDomain | Where-Object { $_.DomainType -ne 'InternalRelay' } $result = @{ isCompliant = $true totalDomains = $domains.Count withDMARC = 0 withoutDMARC = 0 domainDetails = @() } Write-Host "Checking DMARC records for $($domains.Count) domains...`n" -ForegroundColor Cyan foreach ($domain in $domains) { try { # Check for DMARC record (_dmarc.domain.com) $dmarcDomain = "_dmarc.$($domain.DomainName)" $dmarcRecord = Resolve-DnsName -Name $dmarcDomain -Type TXT -ErrorAction SilentlyContinue if ($dmarcRecord) { $dmarcText = $dmarcRecord | Where-Object { $_.Strings -like "v=DMARC1*" } | Select-Object -First 1 if ($dmarcText) { $result.withDMARC++ # Parse DMARC policy $policy = if ($dmarcText.Strings -match 'p=(reject|quarantine|none)') { $matches[1] } else { "unknown" } Write-Host " [OK] $($domain.DomainName): DMARC CONFIGURED" -ForegroundColor Green Write-Host " Policy: $policy" -ForegroundColor Cyan Write-Host " Record: $($dmarcText.Strings)" -ForegroundColor Gray $result.domainDetails += @{ Domain = $domain.DomainName HasDMARC = $true Policy = $policy } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } else { $result.withoutDMARC++ $result.isCompliant = $false Write-Host " [FAIL] $($domain.DomainName): NO DMARC RECORD" -ForegroundColor Red } } catch { Write-Host " ⚠️ $($domain.DomainName): Could not check DNS" -ForegroundColor Yellow } } Write-Host "`n Total domains: $($result.totalDomains)" -ForegroundColor Cyan Write-Host " With DMARC: $($result.withDMARC)" -ForegroundColor Green Write-Host " Without DMARC: $($result.withoutDMARC)" -ForegroundColor $( if ($result.withoutDMARC -gt 0) { "Red" } else { "Green" } ) if ($result.isCompliant) { Write-Host "`n[OK] COMPLIANT - All domains have DMARC" -ForegroundColor Green exit 0 } else { Write-Host "`n[FAIL] NON-COMPLIANT - Configure DMARC for all domains" -ForegroundColor Red exit 1 } } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } function Invoke-Remediation { try { Write-Host "⚠️ DMARC records must be configured in DNS" -ForegroundColor Yellow Write-Host "`nSteps to configure DMARC:" -ForegroundColor Cyan Write-Host " 1. For each domain, create a TXT record:" -ForegroundColor Gray Write-Host " Name: _dmarc.yourdomain.com" -ForegroundColor Gray Write-Host " Value: v=DMARC1; p=quarantine; rua=mailto:dmarc@yourdomain.com" -ForegroundColor Gray Write-Host "`n 2. DMARC Policy Options:" -ForegroundColor Cyan Write-Host " β€’ p=none - Monitor only (start here)" -ForegroundColor Gray Write-Host " β€’ p=quarantine - Suspicious mail to spam" -ForegroundColor Yellow Write-Host " β€’ p=reject - Block suspicious mail (strongest)" -ForegroundColor Green Write-Host "`n 3. Additional recommended tags:" -ForegroundColor Cyan Write-Host " β€’ rua=mailto:... - Aggregate reports email" -ForegroundColor Gray Write-Host " β€’ ruf=mailto:... - Forensic reports email" -ForegroundColor Gray Write-Host " β€’ pct=100 - Apply to 100% of mail" -ForegroundColor Gray Write-Host " β€’ sp=quarantine - Subdomain policy" -ForegroundColor Gray Write-Host "`n 4. Example DMARC record:" -ForegroundColor Cyan Write-Host " v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@yourdomain.com; pct=100; sp=quarantine" -ForegroundColor Gray Write-Host "`n 5. Verify with:" -ForegroundColor Cyan Write-Host " Resolve-DnsName -Name _dmarc.yourdomain.com -Type TXT" -ForegroundColor Gray Write-Host "`nπŸ“ Start with p=none, monitor reports, then move to p=quarantine, then p=reject" -ForegroundColor Cyan exit 0 } catch { Write-Host "`n[FAIL] ERROR: $_" -ForegroundColor Red exit 2 } } try { if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { Write-Host "Usage:" -ForegroundColor Yellow Write-Host " -Monitoring Check DMARC records for all domains" -ForegroundColor Gray Write-Host " -Remediation Show configuration steps" -ForegroundColor Gray } } catch { throw } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan } " throw } } try { if ($Monitoring) { Invoke-Monitoring } elseif ($Remediation) { Invoke-Remediation } else { Write-Host "Usage:" -ForegroundColor Yellow Write-Host " -Monitoring Check DMARC records for all domains" -ForegroundColor Gray Write-Host " -Remediation Show configuration steps" -ForegroundColor Gray } } catch { throw } finally { Write-Host "`n========================================`n" -ForegroundColor Cyan }

Risico zonder implementatie

Risico zonder implementatie
High: High - Domain spoofing succeeds: attackers Verzend phishing van @yourcompany.com, BEC attacks impersonating executives, damage to domain reputation, geen zichtbaarheid in spoofing attempts. DMARC p=reject Blokkeert domain spoofing completely.

Management Samenvatting

DMARC policy: start p=none (monitor) β†’ p=quarantine β†’ p=reject. Blokkeert domain spoofing, biedt spoofing visibility via reports. vereist SPF+DKIM. Voldoet aan CIS 2.1.4 L1, BIO 13.02. Setup: 3u phased rollout.