BIND, the venerable DNS server, can be a surprisingly tricky beast when it comes to email authentication. You’re not just adding records; you’re layering security that tells the world your mail is legitimate and not some phishing scam.
Let’s see this in action. Imagine you’ve got a domain, example.com, and you want to send emails from user@example.com. We’ll add the necessary DNS records to BIND.
First, the SPF record. This tells receiving mail servers which IP addresses are authorized to send email on behalf of example.com. In your BIND zone file for example.com, you’d add a TXT record.
$ORIGIN example.com.
@ IN TXT "v=spf1 mx ip4:192.168.1.100 -all"
Here, v=spf1 declares it’s an SPF record. mx means any mail server listed in your MX records is authorized. ip4:192.168.1.100 explicitly authorizes that IP address. -all is the crucial part: it means any other sender is not authorized and should be rejected. The @ symbol signifies the root of the domain (example.com itself).
Next, DKIM. This is where things get a bit more involved because it requires a cryptographic signature. You’ll generate a public/private key pair. The private key stays with your mail server, and the public key goes into DNS.
First, generate the key pair. On your mail server (or anywhere, really), use opendkim-genkey:
sudo opendkim-genkey -D /etc/opendkim/keys/example.com/ -d example.com -s mail
This creates two files in /etc/opendkim/keys/example.com/: mail.private (your private key) and mail.txt (the public key in DNS format). The -s mail part means your selector is mail.
Now, add the public key to your BIND zone file. The record type is TXT, and the name is selector._domainkey.yourdomain.com.
$ORIGIN example.com.
mail._domainkey IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA0p9z..."
The p= part is your public key. The v=DKIM1 and k=rsa specify the version and algorithm. The actual key string is long and will be provided in the mail.txt file you generated. You’ll need to ensure your mail server is configured to use this private key for signing outgoing mail and that BIND is serving this TXT record.
Finally, DMARC. This record tells receiving servers what to do if SPF or DKIM checks fail, and where to send reports. It’s also a TXT record, but it’s placed at _dmarc.yourdomain.com.
$ORIGIN example.com.
_dmarc IN TXT "v=DMARC1; p=quarantine; rua=mailto:dmarc-reports@example.com; fo=1"
v=DMARC1 is the version. p=quarantine tells receivers to put suspicious emails into the spam folder. p=reject would be stronger, outright rejecting them. rua=mailto:dmarc-reports@example.com specifies an address to send aggregate reports to. fo=1 means generate a failure report if any of the underlying SPF or DKIM checks fail.
The most surprising thing about these records is how simple they are to add to BIND, yet how complex the underlying cryptographic and policy mechanisms are. It’s a facade of simplicity for a robust system.
The problem most people don’t realize is that BIND itself doesn’t do the SPF checking or DKIM signing. BIND just serves the DNS records. You need separate mail server software (like Postfix, Sendmail, Exim) configured to perform the signing (using DKIM libraries) and enforce the SPF policy. Receiving mail servers then query your BIND server for these records to validate incoming mail.
Once you’ve got these records in place and your mail server is configured to use them, the next immediate challenge is often analyzing the DMARC reports to fine-tune your policy and ensure legitimate mail isn’t being caught by your quarantine or reject rules.