Im ersten Teil dieses Beitrags ging es um die Anforderungen und die möglicherweise damit verbunden Probleme. Im zweiten Teil geht es nun um die Verwaltung der SPF Einträge. In einer relativ kleinen und statischen Umgebung wird man recht wenig Berührungspunkte mit dem Sender Policy Framework bekommen. In der Regel findet man in kleinen Umgebungen im SPF DNS Eintrag nur 2 bis 3 Einträge, welche sich auch meistens nicht verändern. Wenn wie im ersten Artikel beschrieben aber viele Einträge vorhanden sind und auch abgeflachte / geglättete SPF Einträge zum Einsatz kommen, muss man sich aber Gedanken machen, wie man diese organisiert.
Sender Policy Framework (SPF) als Managed Service
Der wohl einfachste Weg um die SPF Einträge aktuell und auch den Anforderungen entsprechend zu verwalten, ist SPF als Managed Service einzukaufen. Ich nenne einfach mal wahllos drei Anbieter, welche ich so gefunden habe:
Getestet habe ich davon noch keinen. Die Anbieter arbeiten da alle recht ähnlich: Die Domain wird in einem Portal autorisiert und die DNS Einträge für Sender Policy Framework werden dann beim Anbieter verwaltet. Die Anbieter unterstützen meist mehrere Dienste wie DMARC, MTA-STS und SPF.
Script zum Erzeugen der SPF Einträge
Eine weitere Möglichkeit seine SPF Einträge im Blick zu erzeugen und zu Verwalten ist ein Script. Manche Anbieter ermöglichen es DNS Einträge via API zu erstellen oder zu aktualisieren. Hier könnte man also ein kleines Script nutzen, welches bei Bedarf die DNS Einträge aktualisiert. Hier mal ein Beispiel für die PowerShell wie dies aussehen könnte:
# Definiere SPF Einträge
$SPFPrefix = "_spf"
$Domain = "frankysweb.de"
$SPFEntries = @(
"ip4:185.3.235.230",
"include:secure-mailgate.com",
"include:spf.protection.outlook.com"
)
$Policy = "~all"
# Funktion zum Auflösen von SPF-Einträgen
function Resolve-SPF {
param (
[string[]]$SPFRecords
)
$resolvedIPs = @()
foreach ($entry in $SPFRecords) {
if ($entry -like "ip4:*") {
# Direkt IP-Adressen
$ip = $entry -replace "ip4:", ""
$resolvedIPs += $ip
} elseif ($entry -like "include:*") {
# Auflösen von DNS SPF Include-Einträgen
$domain = $entry -replace "include:", ""
$spfTxtRecords = (Resolve-DnsName -Type TXT -Name $domain).Strings -match "v=spf1"
foreach ($record in $spfTxtRecords) {
$tokens = $record -split "\s+"
foreach ($token in $tokens) {
if ($token -like "ip4:*") {
$ip = $token -replace "ip4:", ""
$resolvedIPs += $ip
}
}
}
}
}
return $resolvedIPs
}
# Funktion zum Aufteilen von SPF Einträgen in 255 Zeichen lange Teile
function Split-SPF {
param (
[string]$SPFString,
[string]$Policy,
[int]$MaxLength = 255
)
$spfParts = @()
$currentPart = ""
$tokens = $SPFString -split "\s+"
foreach ($token in $tokens) {
# Prüfen, ob das Hinzufügen des Tokens und der Policy die Länge überschreitet
if (($currentPart.Length + $token.Length + $Policy.Length + 1) -le $MaxLength) {
$currentPart += $token + " "
} else {
# Wenn die Länge überschritten wird, den aktuellen Teil speichern und neuen anfangen
$spfParts += ($currentPart.TrimEnd() + " " + $Policy)
$currentPart = $token + " "
}
}
# Den letzten Teil hinzufügen
if ($currentPart.TrimEnd().Length -gt 0) {
$spfParts += ($currentPart.TrimEnd() + " " + $Policy)
}
return $spfParts
}
# Funktion zum Erstellen der flachen SPF Einträge und Aufteilen
function Create-SPF {
param (
[string[]]$ResolvedIPs,
[string]$Policy
)
# Erstellen des vollständigen SPF-Eintrags
$FlatSPF = ""
foreach ($IP in $ResolvedIPs) {
$entry = "ip4:" + $IP + " "
$FlatSPF = $FlatSPF + $entry
}
# Aufteilen des SPF-Eintrags, falls er zu lang ist
return Split-SPF -SPFString $FlatSPF -Policy $Policy
}
# Beispielhafte Nutzung
$resolvedIPs = Resolve-SPF -SPFRecords $SPFEntries
$SPFEntries = Create-SPF -ResolvedIPs $resolvedIPs -Policy $Policy
# Haupt SPF für die Domain erzeugen
$Counter = 1
$MainDNS = "IN TXT `"v=spf1 "
$SubDNS = @()
foreach ($SPFEntry in $SPFEntries) {
# Erstellen des Haupt SPF Eintrags mit Includes für Sub-SPF-Einträge
$MainDNS = $MainDNS + "include:" + "$SPFPrefix" + $Counter + "." + $Domain + " "
# Sub-SPF-Einträge ohne 'v=spf1' hinzufügen, da es bereits im Haupt-SPF steht
$SubDNS += "$SPFPrefix" + $Counter + "." + $Domain + " IN TXT " + '"' + "v=spf1 " + $SPFEntry + '"'
$Counter++
}
$MainDNS = $MainDNS + $Policy + '"'
# Ausgabe des Haupt SPF Eintrags
Write-Host "Main SPF Entry for Domain $Domain`:" -foregroundcolor green
write-host "$MainDNS"
# Ausgabe der Sub SPF Einträge
foreach ($entry in $SubDNS) {
write-host "Sub SPF Entry:" -foregroundcolor green
Write-Host $entry
}
In den ersten Zeilen des Scripts werden die normalen lesbaren SPF Einträge angegeben. Aus den Angaben werden dann abgeflachte SPFs erzeugt und angezeigt. Der Teil mit dem aktualisieren der DNS Einträge fehlt hier natürlich, da die APIs der Anbieter unterschiedlich sind, daher muss man bei Bedarf hier noch selbst tätig werden.
Einfacher ist es aber wahrscheinlich einen Managed Service zu nutzen, da man dort auch meist weitere Features wie DMARC Reporting, Hostet MTA-STS usw bekommt.