Small Python script to quick test DMARCDKIM and SPF records
Table of contents
DMARC, DKIM and SPF
For a given occasion I wrote Small Python script to test a domain for DMARC, DKIM and SPF records. Those records are managed in a DNS zone and are typically used in Anti-SPAM techniques.
DKIM requires a so-called DKIM Selector, which can be extracted from the header of an email sent to yourself (or of any other email).
It’s possible to use dig and query those records manually, but for repeating tests I prefer one simple command line tool which do those three test in one go.
Script banner
For Python, the nice toolkit dnspython exists to do all the DNS query work. I’m importing this toolkit and argparse in my script. The script gets a nice ASCII banner because ASCII banners are cool ;)
#!/usr/bin/python3
import argparse
import dns.resolver
print ("______ ___ ___ ___ ______ _____ ______ _ __ _____ ___ ___ _____ ______ ______ ")
print ("| _ \| \/ | / _ \ | ___ \/ __ \ | _ \| | / /|_ _|| \/ | / ___|| ___ \| ___|")
print ("| | | || . . |/ /_\ \| |_/ /| / \/ | | | || |/ / | | | . . | \ `--. | |_/ /| |_ ")
print ("| | | || |\/| || _ || / | | | | | || \ | | | |\/| | `--. \| __/ | _| ")
print ("| |/ / | | | || | | || |\ \ | \__/\ | |/ / | |\ \ _| |_ | | | | /\__/ /| | | | ")
print ("|___/ \_| |_/\_| |_/\_| \_| \____/ |___/ \_| \_/ \___/ \_| |_/ \____/ \_| \_| ")
print (" | _ ' _ | |_ _ ,_ |_ ")
print (" Copyright (C) 2021 Stefan Thierolf | (_| (_) | (_ |< |_ (/_ _\ |_ ")
print (" License GPLv3 | | ")
print ()
parser = argparse.ArgumentParser(description='Simple DMARC DKIM SPF quick test.')
parser.add_argument('domain', help='Domain name to test')
parser.add_argument('selector', help='DKIM Selector, can be extracted from email')
args = parser.parse_args()
domain = args.domain
selector = args.selector
DMARC test
This is the first test case which tests for the DMARC record. The test tries to resolve the _dmarc.domain.tldTXT record in DNS. In the returned DNS data the script looks for the string DMARC1. If the string exists, the test is PASSED, if not the test if FAILED.
#
# Testing DMARC
#
print()
print ("Testing domain", domain, "for DMARC record...")
try:
test_dmarc = dns.resolver.resolve('_dmarc.' + domain , 'TXT')
for dns_data in test_dmarc:
if 'DMARC1' in str(dns_data):
print (" [PASS] DMARC record found :",dns_data)
except:
print (" [FAIL] DMARC record not found.")
pass
DKIM Test
Similar like for DMARC the script tests for DKIM. The so-called DKIM Selector must be extracted from the email headers. This test tries to resolve [selector]._domainkey.domain.tld. The returned DNS data is then checked for the string DKIM1.
#
# Testing DKIM
#
print()
print ("Testing domain", domain, "for DKIM record with selector", selector, "...")
try:
test_dkim = dns.resolver.resolve(selector + '._domainkey.' + domain , 'TXT')
for dns_data in test_dkim:
if 'DKIM1' in str(dns_data):
print (" [PASS] DKIM record found :",dns_data)
except:
print (" [FAIL] DKIM record not found.")
pass
SPF test
The test for SPF record is performed in the same way. In the returned DNS data the script looks for the string spf1. If the string was found, the test is PASSED, if not the test is FAILED.
#
# Testing SPF
#
print()
print ("Testing domain", domain, "for SPF record...")
try:
test_spf = dns.resolver.resolve(domain , 'TXT')
for dns_data in test_spf:
if 'spf1' in str(dns_data):
print (" [PASS] SPF record found :",dns_data)
except:
print (" [FAIL] SPF record not found.")
pass
Test in Windows Subsystem for Linux
As test I checked if the script is running in Windows Subsystem for Linux. As domain I tested microsoft.com with their DKIM selector selector2. The result showed that all three testes are passed and the records are shown. A test against another domain showed failed for DKIM and DMARC, but passed for SPF.
Source code on Github
You will find the script on my GitHub repo published at dds-quick-test.py