An SPF record is a DNS record that works like a reverse MX record. MX records tell the internet what machines can receive mail for a domain, SPF records specify which machines can send mail for a domain. They aren’t required by any means, but they are a good idea to help mail pass spam filters.
There is no such thing as an SPF record in the DNS spec, they are just TXT records. There are several online tools to help you create the right TXT record for your specifications.
I used openspf.org. For example, for one of my servers, it generated the following SPF record:
"v=spf1 a ~all"
This basically means that only the A record for this domain is allowed to send mail. The ~all means to “soft” deny mail from all other hosts. Changing it to -all would make it a “hard” deny.
If you also use google apps for mail for a domain, you can also add include:aspmx.googlemail.com, so it will look like:
"v=spf1 a include:aspmx.googlemail.com ~all"
This means the A record server(s) can send mail for this domain as well as all the google servers.
If you use rails, you might have to do some other work. Say you have a domain mycoolapp.com and have setup up your SPF record correctly. A mail recipient will most likely look at the Return-Path header when validating the SPF record. I always use sendmail as the ActionMailer delivery method:
ActionMailer::Base.delivery_method = :sendmail
and by default, ActionMailer will send it as the user running the script or application.
So if a cron job is running under the runner account and the default hostname for your server is mistral.example.com (or mail.mycoolapp.com, but not mycoolapp.com), the Return-Path will end up being runner@mistral.example.com. Thus, even if with your correct SPF record, the mail recipient will be looking for an SPF record for mistral.example.com.
This is easy to fix by setting a header in the ActionMailer. For example:
def verify(subscription)
subject "Verify your subscription"
recipients subscription.email
from "Some Robot <nobody@mycoolapp.com>"
body :subscription => subscription
headers 'return-path' => 'nobody@mycoolapp.com'
end
This will cause ActionMailer to add -f nobody@mycoolapp.com when it calls sendmail and the return path will be set correctly.
To verify everything is working well, send an email to a gmail account and view the original message. If you see something like:
Received-SPF: pass (google.com: domain of nobody@mycoolapp.com designates 99.99.99.99 as permitted sender) client-ip=99.99.99.99;
Authentication-Results: mx.google.com; spf=pass (google.com: domain of nobody@mycoolapp.com designates 99.99.99.99 as permitted sender) smtp.mail=nobody@mycoolapp.com
Then everything is set up perfectly!