Shav Vimalendiran
BlogWiki ↗
  • The Last MoatsJul 7, 2026
  • The Tech FrontierJul 6, 2026
  • The Trust BarrierJul 4, 2026
  • I Open-Sourced My Coding Agents' MemoryJun 24, 2026
  • How I Gave My Coding Agents Persistent MemoryMar 12, 2026
  • Multi‑Agent Web Exploration with Shared Graph MemoryFeb 19, 2026
  • Our Lessons from Building Production Voice AIJan 11, 2026
  • Reinforcement Learning, Memory and LawDec 10, 2025
  • Automating Secret ManagementOct 23, 2025
  • The Knowledge LayerOct 5, 2025
  • OTel Sidecars on FargateSep 11, 2025
  • Git Disasters and Process DebtSep 7, 2025
  • Is Code Rotting Due To AI?Sep 3, 2025
  • The Integration IllusionAug 30, 2025
  • When MCP FailsAug 26, 2025
  • Context EngineeringAug 22, 2025
  • ›Stop Email Spoofing with DMARCAug 5, 2025
  • SOTA Embedding Retrieval: Gemini + pgvector for Production ChatJul 21, 2025
  • Agentic Design PatternsJun 21, 2025
  • Building AI Agents for Automated PodcastsJan 1, 2025
  • Rediscovering CursorDec 2, 2024
  • GraphRAG > Traditional Vector RAGAug 8, 2024
  • Cultural Bias in LLMsJul 20, 2024
  • Mapping out the AI Landscape with Topic ModellingJul 7, 2024
  • Sustainable Cloud Computing: Carbon-Aware AIJun 27, 2024
  • Defensive Technology for the Next Decade of AIJun 24, 2024
  • Situational Awareness: The Decade AheadJun 13, 2024
  • Mechanistic Interpretability: A SurveyJun 7, 2024
  • Why I Left UbuntuMay 24, 2024
  • Multi-Agent CollaborationApr 16, 2024
  • Building Better Retrieval SystemsMar 28, 2024
  • Building an Automated Newsletter-to-Summary Pipeline with Zapier AI Actions vs AWS SES & LambdaFeb 3, 2024
  • Local AI Image GenerationDec 15, 2023
  • Deploying a Distributed Ray Python Server with Kubernetes, EKS & KubeRayNov 15, 2023
  • Making the Switch to Linux for DevelopmentOct 24, 2023
  • Scaling Options Pricing with RayOct 1, 2023
  • The Async Worker PoolSep 23, 2023
  • Browser Fingerprinting: Introducing My First NPM PackageSep 8, 2023
  • Reading Data from @socket.io/redis-emitter without Using a Socket.io ClientJul 6, 2023
  • Socket.io Middleware for Redux Store IntegrationJul 1, 2023
  • Sharing TypeScript Code Between Microservices: A Guide Using Git SubmodulesApr 21, 2023
  • Efficient Dataset Storage: Beyond CSVsFeb 3, 2023
  • Why I switched from Plain React to Next.js 13Nov 8, 2022
  • Deploy & Scale Socket.io Containers in ECS with ElasticacheNov 3, 2022
  • Implementing TOTP Authentication in Python using PyOTPSep 13, 2022
  • Simplifying Lambda Layer ARNs and Creating Custom Layers in AWSSep 9, 2022
  • TimeScaleDB Deployment: Docker Containers and EC2 SetupJun 23, 2022
  • How to SSH into an EC2 Instance Using PuTTYDec 16, 2021
Loading post…

In This Post

Why Email Is BrokenThe Three-Part FixSPF (Sender Policy Framework)DKIM (DomainKeys Identified Mail)DMARC (Domain-based Message Authentication, Reporting, and Conformance)Setting This Up with GmailStep 1: Add SPF RecordStep 2: Set Up DKIMStep 3: Add DMARC PolicyWhat That DMARC Record MeansDon't Go Straight to RejectCheck Your WorkReading DMARC ReportsMistakes you can make hereWrap Up
Published: August 5, 2025
PreviousNext

Stop Email Spoofing with DMARC

Email spoofing is ridiculously easy. Anyone can connect to a mail server and pretend to send from your domain. No authentication needed. This design flaw has led to decades of phishing and business email attacks.

DMARC stops people from forging emails that look like they came from you.

A security researcher recently showed me how broken this was by sending me a forged email that looked like it came from my own contact address.

DMARC missing record

Why Email Is Broken

Email was built in the 1980s, before anyone thought about spam or phishing. SMTP has no way to check if someone is actually allowed to send from your domain.

So anyone can:

  • Forge the "From" field in any email
  • Impersonate your business to fool customers or employees
  • Damage your reputation with spoofed messages

The fix needs three pieces: SPF, DKIM, and DMARC.

The Three-Part Fix

SPF (Sender Policy Framework)

SPF is a DNS record that says which servers can send email for your domain. When someone gets an email from you, their server checks this list.

v=spf1 include:_spf.google.com -all

Translation: Only Google can send email for my domain. Block everything else.

DKIM (DomainKeys Identified Mail)

DKIM works like a wax seal on old letters:

  • Gmail signs your emails with a private key
  • You put the public key in DNS
  • Recipients check the signature to make sure nobody messed with the message

The DNS record looks like:

google._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjANBg..."

DMARC (Domain-based Message Authentication, Reporting, and Conformance)

DMARC combines SPF and DKIM with a policy that says what to do when emails fail the checks:

  • p=none - Monitor only, don't block anything
  • p=quarantine - Send failing messages to spam
  • p=reject - Block failing messages entirely

Plus DMARC sends you reports showing who's trying to fake your domain.

Setting This Up with Gmail

If you use Google Workspace, here's how to lock down your domain:

Step 1: Add SPF Record

  1. Go to AWS Console → Route 53 → Hosted zones → your-domain.com
  2. Create a TXT record:
    • Name: Leave blank (root domain)
    • Type: TXT
    • Value: "v=spf1 include:_spf.google.com -all"
    • TTL: 300

Step 2: Set Up DKIM

  1. Go to Google Admin Console at admin.google.com
  2. Navigate to Apps → Google Workspace → Gmail → Authenticate Email
  3. Select your domain and click Generate New Record (use 2048-bit)
  4. Google gives you a TXT record like:
    google._domainkey.yourdomain.com TXT "v=DKIM1; k=rsa; p=MIIBIjAN..."
  5. Add this to Route 53 with TTL 300
  6. Back in Admin Console, click Start Authentication
⚠️

If Route 53 says CharacterStringTooLong, split the DKIM key into chunks under 255 characters

Step 3: Add DMARC Policy

Create one more TXT record:

  • Name: _dmarc
  • Type: TXT
  • Value: "v=DMARC1; p=none; rua=mailto:dmarc-reports@yourdomain.com; ruf=mailto:dmarc-fail@yourdomain.com; fo=1; pct=100; aspf=r; adkim=r; sp=none"
  • TTL: 300

This starts in monitor mode (p=none) so you can check reports before blocking anything.

What That DMARC Record Means

Here's what each part does:

  • v=DMARC1 - Protocol version
  • p=none - Policy for main domain (none/quarantine/reject)
  • rua=mailto:... - Where to send daily aggregate reports
  • ruf=mailto:... - Where to send individual failure reports
  • fo=1 - Send forensic reports for any authentication failure
  • pct=100 - Apply policy to 100% of mail
  • aspf=r - SPF alignment mode (relaxed)
  • adkim=r - DKIM alignment mode (relaxed)
  • sp=none - Subdomain policy

Don't Go Straight to Reject

Roll this out slowly:

  1. Week 1-2: Monitor with p=none and review aggregate reports
  2. Week 3-4: Move to p=quarantine with pct=25 (25% of failing mail)
  3. Week 5-6: Increase to pct=100 quarantine
  4. Final: Enforce with p=reject once confident all legitimate mail passes

Your final "block everything" record:

v=DMARC1; p=reject; rua=mailto:dmarc-reports@yourdomain.com; fo=1; aspf=s; adkim=s; sp=reject

Check Your Work

Make sure everything's set up right:

dig +short TXT yourdomain.com                    # SPF
dig +short TXT google._domainkey.yourdomain.com  # DKIM
dig +short TXT _dmarc.yourdomain.com             # DMARC

Or use Google's Check MX tool if you prefer clicking buttons.

Reading DMARC Reports

Reports come as zipped XML files with:

  • Who's trying to send as your domain
  • Whether they passed SPF/DKIM checks
  • How much mail each sender attempted
  • What happened to failed messages

These show you:

  • Legit senders you forgot about
  • Bad actors trying to spoof you
  • Stuff you misconfigured

Mistakes you can make here

  • Incomplete SPF: Forget to include your marketing platform or CRM? Your emails won't deliver.
  • Going Too Fast: Jump straight to p=reject and you'll block legit mail you didn't know about.
  • Ignoring Reports: Those XML files aren't just noise - they show real attacks and config problems.
  • Forgetting Subdomains: Skip sp=reject and attackers can spoof mail.yourdomain.com all day.

Wrap Up

Email authentication isn't optional anymore. SPF, DKIM, and DMARC together stop domain spoofing and show you who's trying to fake your emails.

Start slow with monitoring, read those reports, then gradually get stricter. Your customers and brand will thank you.

That researcher who showed me the vulnerability was right - no DMARC means anyone can spoof you. But set this up properly and you'll close that hole while getting useful intel on your email traffic.


Loading comments...
PreviousContext EngineeringNextSOTA Embedding Retrieval: Gemini + pgvector for Production Chat

Be the first to share your thoughts!