Dieses Premium Script ist exklusiv für unsere Newsletter Abonnenten!
Gebe deine eMail Adresse zum kostenlosen Freischalten ein!
Dieses PHP-Script ermöglicht die Analyse von SPF-Records für beliebige Domains. Es prüft die DNS-Einträge einer Domain, extrahiert den SPF-Record und zerlegt ihn in einzelne Mechanismen, wie a
, mx
, ip4
, include
und all
. Das Script bietet außerdem Warnungen bei fehlerhaften oder unvollständigen SPF-Einträgen und unterstützt eine Opt-out-Option für Datenschutz.
Funktionen im Detail:
- Domain-Eingabe und Validierung:
- Prüft, ob eine Domain eingegeben wurde
- Validiert die Domain auf korrektes Format
- Live-DNS-Abfrage:
- Ruft die TXT-Einträge der angegebenen Domain über
dns_get_record
ab - Filtert den SPF-Record (
v=spf1
)
- Ruft die TXT-Einträge der angegebenen Domain über
- SPF-Parsing:
- Zerlegt den SPF-Record in einzelne Mechanismen
- Erfasst Qualifier (
+
,-
,~
,?
) - Extrahiert Werte von Mechanismen (
ip4:
,include:
, etc.) - Fügt Tooltips für Mechanismen zur Erklärung hinzu
- Warnungen:
- Fehlender
all
-Mechanismus - Zu viele
ip4
-Einträge - Kein SPF-Record vorhanden
- Opt-out aktiviert
- Fehlender
- JSON-Ausgabe:
- Liefert die Daten als JSON, sodass Frontend-AJAX sie direkt verarbeiten kann
- Enthält SPF-Record, Mechanismen und Warnungen
- Frontend-Kompatibilität:
- Das Script kann mit AJAX-Requests verbunden werden
- Unterstützt sofortige Anzeige von Ergebnissen, ohne die Seite neu zu laden
Verwendungszweck:
Das Script eignet sich für IT-Administratoren, E-Mail-Sicherheitsbeauftragte oder Entwickler, die die SPF-Konfiguration einer Domain überprüfen wollen. Es kann direkt in Webanwendungen eingebunden werden, inklusive Tooltips, Warnungen und Live-Abfrage.
<?php
if(isset($_POST['action']) && $_POST['action']=='analyze') {
header('Content-Type: application/json');
$domain = trim($_POST['domain'] ?? '');
$opt_out = isset($_POST['opt_out']);
// Grundvalidierung der Domain
if($domain==='') {
echo json_encode(['error'=>'Bitte eine Domain eingeben']);
exit;
}
if(!preg_match('/^(?!\-)([a-zA-Z0-9\-]{1,63}\.)+[a-zA-Z]{2,}$/', $domain)) {
echo json_encode(['error'=>'Ungültige Domain']);
exit;
}
// Live SPF-Record abfragen
$spfRecord = '';
$dnsRecords = @dns_get_record($domain, DNS_TXT);
if($dnsRecords) {
foreach($dnsRecords as $rec) {
if(strpos($rec['txt'], 'v=spf1')===0) {
$spfRecord = $rec['txt'];
break;
}
}
}
if(!$spfRecord) {
$spfRecord = 'Kein SPF-Record gefunden';
}
function parseSPF($spfString) {
$mechanisms = [];
$warnings = [];
if($spfString==='Kein SPF-Record gefunden') {
$warnings[]=['text'=>'Kein SPF-Record vorhanden','info'=>'Die Domain hat keinen SPF-Eintrag.'];
return ['mechanisms'=>$mechanisms,'warnings'=>$warnings];
}
$parts = preg_split('/\s+/', trim($spfString));
foreach ($parts as $part) {
$qualifier = '+';
if (preg_match('/^([+\-~?])?(.*)$/', $part, $matches)) {
if(!empty($matches[1])) $qualifier=$matches[1];
$mechanism=$matches[2];
if(strpos($mechanism, ':')!==false) {
list($kind,$value)=explode(':',$mechanism,2);
} else {
$kind=$mechanism;
$value='';
}
$tooltips=[
'v=spf1'=>'Version des SPF-Records',
'a'=>'Erlaubt alle IPs des A-Records',
'mx'=>'Erlaubt alle IPs der MX-Records',
'ip4'=>'IPv4-Adresse erlaubt',
'ip6'=>'IPv6-Adresse erlaubt',
'include'=>'Fügt SPF-Record einer anderen Domain ein',
'all'=>'Trifft auf alle anderen Sender zu',
'ptr'=>'Erlaubt Domains, deren PTR auf diese Domain zeigt',
'exists'=>'Erlaubt wenn DNS-Abfrage erfolgreich',
'redirect'=>'Leitet SPF-Prüfung auf andere Domain',
'exp'=>'Spezifiziert Erklärung für SPF-Fehler'
];
$mechanisms[]=['kind'=>$kind,'qualifier'=>$qualifier,'value'=>$value,'tooltip'=>$tooltips[$kind]??''];
}
}
if(!preg_match('/all$/',$spfString)) {
$warnings[]=['text'=>'Kein "all"-Mechanismus gefunden','info'=>'SPF sollte mit all enden.'];
}
if(substr_count($spfString,'ip4:')>10) {
$warnings[]=['text'=>'Viele IP4-Einträge','info'=>'Zu viele IP4-Einträge können SPF-Checks verlangsamen.'];
}
return ['mechanisms'=>$mechanisms,'warnings'=>$warnings];
}
$result=parseSPF($spfRecord);
if($opt_out) {
$result['warnings'][]=['text'=>'Opt-out aktiviert','info'=>'Keine zusätzlichen Daten werden gesammelt.'];
}
$result['spfRecord']=$spfRecord;
echo json_encode($result);
exit;
}
?>
<!DOCTYPE html>
<html lang="de">
<head>
<meta charset="UTF-8">
<title>Dreamcodes.net SPF Analyzer</title>
<style>
body {font-family: Verdana, Geneva, sans-serif; background-color: #e6f2ff; color: #003366; margin:0; padding:0; font-size:14px;}
.container {max-width:850px; margin:40px auto; padding:25px 35px; background-color:#f0f9ff; border-radius:8px; box-shadow:0 0 12px rgba(0,0,0,0.1);}
h1 {color:#004080; margin-bottom:25px; text-align:center; font-size:24px;}
form {margin-bottom:30px; text-align:center;}
input[type=text] {width:65%; padding:10px; margin-right:10px; border-radius:4px; border:1px solid #99c; font-size:14px; transition: border-color 0.3s;}
input[type=text]:focus {border-color:#0073e6; outline:none;}
input[type=checkbox] {margin-left:10px; transform:scale(1.1);}
button {padding:10px 20px; border:none; background-color:#0073e6; color:white; border-radius:4px; cursor:pointer; font-size:14px; transition:background-color 0.3s;}
button:hover {background-color:#005bb5;}
#loading div {width:40px; height:40px; border:5px solid #cce6ff; border-top:5px solid #0073e6; border-radius:50%; animation:spin 1s linear infinite; margin:15px auto;}
@keyframes spin {0% { transform: rotate(0deg); } 100% { transform: rotate(360deg); }}
table {width:100%; border-collapse: collapse; margin-top:20px; font-size:14px;}
th, td {padding:10px 12px; border:1px solid #99c; text-align:left;}
th {background-color:#cce6ff; font-weight:bold;}
tr:hover {background-color:#d9f0ff;}
.tooltip {position:relative; display:inline-block; cursor:pointer; color:#004080; font-weight:bold;}
.tooltip .tooltiptext {visibility:hidden; width:220px; background-color:#0073e6; color:#fff; text-align:center; border-radius:6px; padding:6px; position:absolute; z-index:1; bottom:125%; left:50%; margin-left:-110px; opacity:0; transition:opacity 0.3s; font-size:12px;}
.tooltip:hover .tooltiptext {visibility:visible; opacity:1;}
.warning {color:red; margin-top:10px; font-size:13px;}
.spf-record {background-color:#cce6ff; padding:12px; border-radius:4px; margin-bottom:20px; font-family:monospace; color:#003366; font-size:14px;}
@media (max-width:600px){
input[type=text]{width:90%; margin-bottom:10px;}
button{width:90%;}
}
</style>
</head>
<body>
<div class="container">
<h1>SPF Analyzer</h1>
<form id="spfForm">
<div style="display:flex; gap:5px; align-items:center;">
<input type="text" name="domain" id="domain" placeholder="Domain eingeben" style="flex:1; padding:5px;">
<button type="submit" style="padding:6px 12px;">Analysieren</button>
</div>
<label>
<input type="checkbox" name="opt_out"> Opt-out aktivieren
</label>
</form>
<div id="loading" style="display:none; margin-bottom:20px;">
<div style="width:40px; height:40px; border:5px solid #cce6ff; border-top:5px solid #0073e6; border-radius:50%; animation: spin 1s linear infinite; margin:auto;"></div>
</div>
<div id="results"></div>
</div>
<style>
@keyframes spin {
0% { transform: rotate(0deg); }
100% { transform: rotate(360deg); }
}
</style>
<script>
document.getElementById('spfForm').addEventListener('submit', function(e){
e.preventDefault();
document.getElementById('results').innerHTML='';
document.getElementById('loading').style.display='block';
let formData=new FormData(this);
formData.append('action','analyze');
fetch('',{method:'POST',body:formData})
.then(r=>r.json())
.then(data=>{
document.getElementById('loading').style.display='none';
let html='';
if(data.error){
html='<div class="warning">'+data.error+'</div>';
} else {
html='<div class="spf-record">SPF-Record: <code>'+data.spfRecord+'</code></div>';
html+='<h2>Mechanismen</h2><table><tr><th>Mechanismus</th><th>Details</th></tr>';
data.mechanisms.forEach(m=>{
html+='<tr><td class="tooltip">'+m.kind+'<span class="tooltiptext">'+m.tooltip+'</span></td>'+
'<td>Qualifier: <strong>'+m.qualifier+'</strong>, Wert: <code>'+m.value+'</code></td></tr>';
});
html+='</table>';
if(data.warnings.length>0){
html+='<h2>Warnungen</h2>';
data.warnings.forEach(w=>{
html+='<div class="warning tooltip">'+w.text+'<span class="tooltiptext">'+w.info+'</span></div>';
});
}
}
document.getElementById('results').innerHTML=html;
});
});
</script>
</body>
</html>