Skip to main content
All CollectionsThreat Protection & Compliance
Implementing SPF, DKIM, and DMARC Programmatically for Email Security
Implementing SPF, DKIM, and DMARC Programmatically for Email Security

Learn how to programmatically implement and verify SPF, DKIM, and DMARC for email security.

Updated over a month ago

Overview:

In this article, we will explore how to implement SPF, DKIM, and DMARC authentication programmatically using DNS management tools and server-side scripting. The goal is to ensure email security by authenticating senders, validating email content, and enforcing domain policies using these protocols.

1. Programmatically Creating SPF Records with DNS Management API

SPF (Sender Policy Framework) records are added to your DNS settings as a TXT record. Here’s how to programmatically add an SPF record using a DNS management API.

Step 1: Define Your SPF Record

Let’s say you want to allow a mail server (e.g., smtp.mailserver.com) to send emails on behalf of your domain, and reject emails from unauthorized IP addresses.

plaintextCopy codev=spf1 ip4:203.0.113.0/24 include:smtp.mailserver.com -all

This SPF record:

  • ip4:203.0.113.0/24: Allows emails from the IP address range 203.0.113.0/24.

  • include:smtp.mailserver.com: Allows emails from a third-party email service.

  • -all: Rejects all other mail sources.

Step 2: Add the SPF Record Using a DNS API

Using a DNS management API (such as AWS Route 53 or Cloudflare), you can add this record dynamically.

Example: Using Python with the Boto3 Library for AWS Route 53

pythonCopy codeimport boto3 # Create Route 53 client route53 = boto3.client('route53') # Define the SPF record spf_record = { 'Action': 'UPSERT', 'ResourceRecordSet': { 'Name': 'example.com.', 'Type': 'TXT', 'TTL': 300, 'ResourceRecords': [{'Value': '"v=spf1 ip4:203.0.113.0/24 include:smtp.mailserver.com -all"'}], } } # Update the DNS record set response = route53.change_resource_record_sets( HostedZoneId='YOUR_HOSTED_ZONE_ID', ChangeBatch={'Changes': [spf_record]} ) print(response)

This code will create or update the SPF TXT record for example.com.


2. Programmatically Signing Emails with DKIM (DomainKeys Identified Mail)

DKIM adds a digital signature to outgoing emails. To implement DKIM programmatically, we need to generate a private/public key pair, sign the email header with the private key, and add the public key to DNS.

Step 1: Generate DKIM Keys

You can generate a key pair using OpenSSL or a DKIM tool. Here’s how to generate keys with OpenSSL:

bashCopy code# Generate private key openssl genpkey -algorithm RSA -out private.key -pkeyopt rsa_keygen_bits:2048 # Generate public key from private key openssl rsa -pubout -in private.key -out public.key

Step 2: Add DKIM Public Key to DNS

Publish the public key in your DNS as a TXT record. Here’s an example DKIM TXT record:

plaintextCopy codedefault._domainkey.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnCt3h9fE2RJg4lPflf0xRuC..."

Use the following code to dynamically add this DKIM record to your DNS using a Cloudflare API (as an example).

Example: Using Python with Cloudflare API

pythonCopy codeimport requests # Cloudflare API credentials zone_id = "YOUR_ZONE_ID" email = "YOUR_EMAIL" api_key = "YOUR_API_KEY" # DKIM public key record dkim_record = { "type": "TXT", "name": "default._domainkey", "content": "v=DKIM1; k=rsa; p=MIGfMA0GCSqGSIb3DQEBAQUAA4GNADCBiQKBgQCnCt3h9fE2RJg4lPflf0xRuC...", "ttl": 3600 } # Add DKIM record via Cloudflare API headers = { "X-Auth-Email": email, "X-Auth-Key": api_key, "Content-Type": "application/json" } response = requests.post( f"https://api.cloudflare.com/client/v4/zones/{zone_id}/dns_records", json=dkim_record, headers=headers ) print(response.json())


3. Programmatically Setting Up DMARC Record for Domain Compliance

DMARC allows domain owners to specify how emails failing SPF and DKIM checks should be handled (e.g., reject, quarantine, or none).

Step 1: Define the DMARC Policy

Here’s an example of a DMARC record that requests emails failing SPF and DKIM checks to be quarantined:

plaintextCopy codev=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; pct=100

This record:

  • v=DMARC1: Specifies the version.

  • p=quarantine: Emails failing checks will be sent to the spam/junk folder.

  • rua and ruf: Specifies email addresses to receive aggregate and failure reports.

  • pct=100: Applies the policy to 100% of emails.

Step 2: Add the DMARC Record Using DNS Management API

Use a DNS API to add the DMARC TXT record. Here’s how to add a DMARC record to your DNS with AWS Route 53 using Python:

pythonCopy code# Define the DMARC record dmarc_record = { 'Action': 'UPSERT', 'ResourceRecordSet': { 'Name': '_dmarc.example.com.', 'Type': 'TXT', 'TTL': 300, 'ResourceRecords': [{'Value': '"v=DMARC1; p=quarantine; rua=mailto:[email protected]; ruf=mailto:[email protected]; pct=100"'}], } } # Update the DNS record set for DMARC response = route53.change_resource_record_sets( HostedZoneId='YOUR_HOSTED_ZONE_ID', ChangeBatch={'Changes': [dmarc_record]} ) print(response)

4. Testing and Verifying SPF, DKIM, and DMARC Configuration

After implementing SPF, DKIM, and DMARC, it’s essential to verify that your records are configured correctly. Here’s how to test each of them programmatically:

a. Test SPF Record

Use an HTTP request to check if an SPF record is published:

pythonCopy codeimport dns.resolver def check_spf(domain): try: result = dns.resolver.resolve(domain, 'TXT') for txt in result: if txt.to_text().startswith('v=spf1'): return f"SPF Record for {domain}: {txt.to_text()}" return "No SPF record found" except Exception as e: return str(e) print(check_spf('example.com'))

b. Test DKIM Record

You can also verify DKIM records using DNS resolution:

pythonCopy codedef check_dkim(domain, selector): try: result = dns.resolver.resolve(f"{selector}._domainkey.{domain}", 'TXT') return f"DKIM Record for {domain}: {result[0].to_text()}" except Exception as e: return str(e) print(check_dkim('example.com', 'default'))

c. Test DMARC Record

Verify your DMARC record using the following:

pythonCopy codedef check_dmarc(domain): try: result = dns.resolver.resolve(f"_dmarc.{domain}", 'TXT') return f"DMARC Record for {domain}: {result[0].to_text()}" except Exception as e: return str(e) print(check_dmarc('example.com'))

Conclusion

Implementing SPF, DKIM, and DMARC programmatically using DNS management APIs ensures that your email system is protected from spoofing and phishing attacks. By adding SPF records to authorize your mail servers, signing emails with DKIM, and defining DMARC policies, you can maintain a high level of email security. Additionally, automating the verification process ensures that your configurations are always correct and up-to-date.

Did this answer your question?