Stopping bounce spam with SPF records

For about a year, I have been receiving bounce messages from email servers. These bounce messages were sent as a result of a spammer sending messages with my domain, apparentetch.com, in the From field of the messages.

spam bounce

Example of a spam bounce.

I received about upwards of 100 bounce messages daily. Not all servers are nice enough to send bounce messages nor did all of the emails go to nonexistent addresses so the number of forged emails sent in my name was probably much higher.

Sender Policy Framework (SPF) is an experimental protocol for validating email messages. The official spec, can be found here.

Through analysis for another project, the relevancy of SPF for stopping bounce spam became readily apparent. Even though it is still a specification, the SPF spec is widely implemented. As in my case, a domain with poorly configured or nonexistent SPF records is passing up effective spam prevention.

In Apparent Etch’s setup, inbound mail is routed to Google Apps and outgoing mail is sent from both Google Apps and the domain server.

No changes affect inbound mail as MX records have a separate purpose from SPF records.

SPF records currently exist as TXT records in DNS.
To mark Google Apps and the domain server as allowed mail senders, I added two records whose syntax is explained farther down:
v=spf1 a:apparentetch.com
v=spf1 include:_spf.google.com ~all

How SPF records work:

SPF diagramed

  • Domain owner of example.com adds allowed entry of IP addresses to domains’ SPF records.
    v=spf1 a:example.com
    • This TXT record denotes that IP address of example.com is allowed to send messages for example.com.
    • v=spf1 specifies protocol of SPFv1.
    • a: requests A record look up of example.com: domain.
  • SMTP Server 1 receives MAIL FROM and HELO from** SMTP Server 2**.
  • SMTP Server 1 performs a DNS lookup on TXT records for example.com.
    • DNS server returns v=spf1 a:example.com as a TXT record for example.com to** SMTP Server 1**
      • v=spf1 a:example.com means that allowed IP addresses for this record can be found in the A records of example.com.
  • SMTP Server 1 performs DNS lookup on A records for example.com.
    • DNS server returns example.com. IN A 1.1.1.1 as an A record for example.com to** SMTP Server 1**
      • example.com. IN A 1.1.1.1 means that* 1.1.1.1* is a valid IP address for example.com. Additional SPF record syntax info can be found here.
      • SMTP Server 1 now knows that 1.1.1.1 is allowed to send mail for example.com
  • SMTP Server 1 checks to if SMTP Server 2‘s IP address matches 1.1.1.1.
    • If SMTP Server 2‘s IP address matches 1.1.1.1:
      • SMTP Server 2 is allowed to send messages for example.com.
      • SMTP Server 1 processes the message.
    • If SMTP Server 2‘s IP address does not match 1.1.1.1:
      • SMTP Server 2 is not allowed to send messages for example.com.
      • SMTP Server 1 replies with a bounce message to the Return-Path address of the rejected message. The From address is used if no Return-Path is provided. SMTP Server 1 does not send the message.

According to the SPF spec, v=spf1 a ~all should also be added as the last TXT record to operate as a catch-all to designate all hosts not caught by previous SPF records as “NOT being allowed to send” on behalf of the domain. Through additional testing and lookups, it appears that v=spf1 a ~all is assumed to be the last record if no catch-all record is found as the last record. I’m not sure if this is due to my management of DNS records through Rackspace, but hopefully someone can confirm.

Almost immediately after I added SPF records under my domain’s SPF records, the bounce emails ceased.

Hooray, no spam here!

Hooray, no spam here!

Still, servers somewhere from Romania to Peru are sending emails pretending to come from @apparentetch.com.
SPF records won’t stop these servers from sending out messages, but they will prevent these messages from reaching the inboxes of random users whom I’d rather not hear [spam] complaints from.

Anson Liu