How to Implement DKIM and SPF for Email Authentication on Subdomains When Using External DNS


6 views

When your VPS host (like Linode) doesn't control your domain's DNS nameservers, email authentication becomes tricky. The fundamental issue is that SPF and DKIM records must be published in the authoritative DNS zone for your domain, while you only have access to your hosting provider's DNS management interface.

For a subdomain like subdomain.example.com, there are two approaches to implement authentication records:

; Option 1: Place records directly in parent zone
subdomain.example.com. IN TXT "v=spf1 a ~all"
_domainkey.subdomain.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGf..."

; Option 2: Delegate subdomain DNS
subdomain.example.com. IN NS ns1.linode.com.
subdomain.example.com. IN NS ns2.linode.com.

The SPF record for your subdomain should explicitly reference its own A record, not the parent domain's:

; Correct subdomain SPF
subdomain.example.com. IN TXT "v=spf1 a:subdomain.example.com -all"

; Common mistake (references parent domain)
subdomain.example.com. IN TXT "v=spf1 a:example.com -all"

DKIM requires two key components for subdomains:

  1. The selector record in your subdomain's zone
  2. Proper configuration in your mail server (like Postfix)
# Example Postfix DKIM configuration (subdomain-specific)
smtpd_milters = inet:localhost:8891
non_smtpd_milters = inet:localhost:8891
milter_default_action = accept
milter_protocol = 6

Here's the exact sequence I follow when setting up email authentication for subdomains:

1. Generate DKIM keys using opendkim:
   opendkim-genkey -b 2048 -s mail -d subdomain.example.com

2. Request these DNS records from domain administrator:
   mail._domainkey.subdomain.example.com. IN TXT "v=DKIM1; k=rsa; p=MIGf..."
   subdomain.example.com. IN TXT "v=spf1 a mx -all"

3. Verify configuration with:
   dig TXT subdomain.example.com
   dig TXT mail._domainkey.subdomain.example.com

When debugging subdomain email authentication, watch for these gotchas:

  • Incorrect record propagation (always check with dig +trace)
  • Parent domain SPF policies overriding subdomain
  • DKIM selector naming conflicts

For automated testing, I recommend this Python snippet to validate your setup:

import dns.resolver

def check_spf(subdomain):
    try:
        answers = dns.resolver.resolve(subdomain, 'TXT')
        return any('v=spf1' in str(r) for r in answers)
    except dns.resolver.NoAnswer:
        return False

When managing email delivery from a subdomain (e.g., subdomain.example.com) where your VPS infrastructure (like Linode) doesn't control the parent domain's DNS, you face unique authentication challenges. The critical difference from root domain configuration lies in record naming conventions and delegation requirements.

For subdomains, SPF records follow the same syntax but require explicit declaration at the subdomain level. Example SPF record for subdomain.example.com:

v=spf1 ip4:192.0.2.1 ip6:2001:db8::1 include:_spf.google.com ~all

Key considerations:

  • Must be created as a TXT record specifically for the subdomain
  • Doesn't inherit from the parent domain's SPF policy
  • Requires separate IPv4/IPv6 declarations for your mail server

DKIM for subdomains introduces selector naming requirements. A typical DKIM record for subdomain.example.com with selector "linode2023":

linode2023._domainkey.subdomain.example.com. IN TXT "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA..."

Critical DKIM aspects:

  • Selector prefix becomes part of the DNS record name
  • Public key must be generated specifically for the subdomain
  • Requires proper signing configuration in your MTA (Postfix/Sendmail)

When parent domain DNS is managed elsewhere, you'll need to request these specific records:

; SPF Record
subdomain.example.com. IN TXT "v=spf1 include:_spf.example.com ~all"

; DKIM Record
selector._domainkey.subdomain.example.com. IN TXT "v=DKIM1; k=rsa; p=MII..."

For Postfix configuration on your Linode VPS:

# In main.cf
smtpd_milters = inet:localhost:8891
non_smtpd_milters = $smtpd_milters
milter_default_action = accept
milter_protocol = 6

# In opendkim.conf
Domain                  subdomain.example.com
KeyFile                 /etc/opendkim/keys/subdomain.example.com/selector.private
Selector                selector

Essential commands to validate your setup:

dig TXT subdomain.example.com
dig TXT selector._domainkey.subdomain.example.com

telnet subdomain.example.com 25
EHLO example.com
MAIL FROM: <user@subdomain.example.com>

Third-party validation tools like MXToolbox can verify both SPF and DKIM configurations for your subdomain.