Publish SPF, DKIM and DMARC and check they agree
Task
Publish the three records for a domain you control in your own lab DNS, then evaluate messages against them and find the alignment failure that SPF alone cannot see.
Steps
- In your local resolver, create a zone for
lab.exampleand publish an SPF TXT record naming your Linux VM's address as the only permitted sender. - Generate a DKIM key pair and publish the public key as a TXT record at a selector you choose.
- Publish a DMARC record at
_dmarc.lab.examplewithp=noneand anruaaddress — the position every deployment starts from. - Write
/tmp/evaluate.py: given a message file and the zone, it checks whether the sending address is permitted by SPF, whether the DKIM signature verifies, and — the part that matters — whether either passing domain ALIGNS with theFrom:header domain. Have it print one line per result,spf=pass|fail,dkim=pass|failanddmarc=pass|fail-- the Verify reads thedmarc=line. - Evaluate three messages: one fully aligned, one where SPF passes for a different domain than the
From:header, and one with a broken DKIM signature. - Record in
/tmp/email-auth.mdwhich of the three would be delivered underp=none,p=quarantineandp=reject, and why the second message is the one SPF alone cannot catch.
Files the Verify reads
The Verify block reads these by name, so save them exactly here:
-
/tmp/msg-aligned.eml-- the fully aligned message from step 5. -
/tmp/msg-misaligned.eml-- the message where SPF passes for a different domain than theFrom:header.
Verify
dig +short TXT lab.example @127.0.0.1 | grep -c "v=spf1"
dig +short TXT _dmarc.lab.example @127.0.0.1 | grep -c "v=DMARC1"
python3 /tmp/evaluate.py /tmp/msg-aligned.eml | grep -ci "dmarc=pass"
python3 /tmp/evaluate.py /tmp/msg-misaligned.eml | grep -ci "dmarc=fail"
All four must be non-zero. The fourth is the one that teaches: the misaligned message passes SPF — genuinely, for the attacker's own domain — and fails DMARC, because DMARC is the only one of the three that requires the passing domain to match what the recipient actually sees in the From: line.
Notes
One detail worth knowing if you publish these for real: a single string inside a DNS TXT record is limited to 255 characters, and a 2048-bit DKIM public key is longer than that. It is published by splitting the value into several quoted strings in one record, which receivers join back together; many DNS providers do the split for you. Shortening the key to fit is not the answer.
This is an independent study companion for CompTIA Security+ SY0-701 and is not produced by or endorsed by CompTIA.