Install SPF records on a cPanel server
What is SPF?
Sender Policy Framework (SPF) is an attempt to control forged e-mail. SPF is not directly about stopping spam – junk email. It is about giving domain owners a way to say which mail sources are legitimate for their domain and which ones aren’t. While not all spam is forged, virtually all forgeries are spam. SPF was created in 2003 to help close loopholes in email delivery systems that allow spammers to “spoof” or steal your email address to send hundreds, thousands or even millions of emails illicitly.
More information about SPF can be found at http://www.openspf.org/Project_Overview
Why do I want to have SPF records for my domains?
Many mail servers are now testing for the presence of SPF records so if you don’t have one your email will probably not be delivered to that server. A good example is Hotmail that is testing for SPF records since 2004.
What syntax should I use?
Now that you have learnt what it is and why you should use it, it’s time to see what syntax you should use.
For SPF to work you have to add to each DNS zone a record similar to this:
domain.com. 14400 IN TXT “v=spf1 a mx -all”
Let’s try to explain the syntax:
We are telling the world that:
- v=spf1 - we are using spf version 1 (the only version really)
- for domain “domain.com” the fallowing IP’s are allowed to send email: the A record IP and the MX record IP’s.
- “-all” - no other IP’s are allowed to send emails
You can read all the options that you have by visiting: http://www.openspf.org/SPF_Record_Syntax
How to install SPF records?
Now that we know what they are and how to write them it’s time to install them.
I’ll divide my presentation in two sections.
In the first one I will teach you how to add a SPF record automatically to newly created accounts and in the second section how to add them to domains that are already setup and don’t have them.
If this is a new cPanel server or you want all the domains that you add on the server from now on to have a SPF record you have to do the fallowing:
- Login to WHM using root
- Click on Edit Zone Templates and then on “standard”
- Add at the end of file:
- Repeat step 2 and 3 for the “simple” zone template
%domain%. IN TXT “v=spf1 a mx -all”
You can replace “v=spf1 a mx -all” with the syntax that you decide it’s the best for you.
That’s it ! From now on all the accounts that you will create on the server will have a SPF record.
Now what do we do with all the accounts that are already created and don’t have a SPF record?
One option would be to edit manually all the zone files on the server and to add the TXT record. This is an easy solution if you have 10 accounts but what do you do if you have 1000 or 10.000 (on multiple servers) ?
I have the solution for you !
cPanel has built a script to install a SPF record for a given cPanel user. The script is located at: /usr/local/cpanel/bin/spf_installer
I was surprised to know how few people know about this script. In fact when I searched forums.cpanel.net for some threads about this I found none !
I can tell you that this script is scheduled to go into production in cPanel 12.x and it’s now in beta testing, this is why there no mention of it anywhere.
Unfortunately as with all the beta software out there this script has a big bug. The script will not add a SPF for the main domain but does work with your subdomains, addon or parked domanins.
After investigating for a few hours I found the problem. The script is trying to add to the DNS zone a record like this:
domain.com 14400 IN TXT “v=spf1 a mx -all”
The correct syntax would be:
domain.com. 14400 IN TXT “v=spf1 a mx -all”
Notice the extra dot (.) in the correct syntax !
How to fix this?
We have to edit one of cPanel’s source code. Here’s a step by step guide on how to do it:
- Login as root on the server using ssh
- We have to edit SPF.pm source file
- Locate the fallowing lines (should be at the end of the file)
- Replace this with:
- Now let’s test to see if it works. Run the fallowing
nano /usr/local/cpanel/Cpanel/SPF.pm
foreach my $domain (@DOMAINS) {
push @installlist , { match => ‘v=spf’,
domain => $domain,
record => $domain,
value => ‘v=spf1 a mx ?all’ };
}
foreach my $domain (@DOMAINS) {
push @installlist , { match => ‘v=spf’,
domain => $domain.”.”,
record => $domain.”.”,
value => ‘v=spf1 a mx ?all’ };
}
I’m not a perl expert but this should work. There might be a better way to do it and if you know one please leave a comment here.
Also please note that I have opened a bug report with cPanel and I hope that they will fix the bug themselves within a reasonable timeframe.
Please note that the default cPanel script will add the fallowing SPF record: ‘v=spf1 a mx ?all’ which means that for all the domains you will allow the A and MX records IP’s to send email and will be neutral to all the others (notice the ?all at the end of the record !). This is probably OK for all the situations and will cause little to no trouble, but you might want to change this if you want to have a special SPF record setup.
/usr/local/cpanel/bin/spf_installer USERNAME
Where USERNAME is the cPanel username.
Now check to see if the zone file has a SPF record.
If everything was ok we can now add a SPF to all the domains on the server.
I have created a simple bash script to do this for you.
Run as root the fallowing:
for i in `ls /var/cpanel/users` ;do /usr/local/cpanel/bin/spf_installer $i ;done
Wait for it to finish. (it might take a few minutes!).
That’s about it. Hope it helps a lot a people !
If you have any comments or questions don’t hesitate to leave a comment here.
If you enjoyed this post, make sure you subscribe to my RSS feed!
- December 27th


(8 votes, average: 4 out of 5)














Thanks for the informative article!
I took the SPF record one step further by adding the ip address of the server so that my customer accounts move from a neutral to a pass state on SPF record/RDNS checks.
Example: v=spf1 a mx ip4:xxx.xxx.xxx.xx ~all (where the X’s are your server ip)
Another mechanism that seems to be around the corner is DKIM. I don’t know where all this is going to end but someday this will all have to be ironed out or email will become history.
Thanks for this.
Any chance you could mirror the spf.pm file here? I seem to have screwed mine up.
cPanel it not a free software so I can’t publicly post all the contain of the file but if you email me at admin[{ at}]cpanelconfig.com I can email you a copy, or better yet you can run “/scripts/upcp –force” from ssh that should fix the problem for you.
The replacement should be:
foreach my $domain (@DOMAINS) {
push @installlist , { match => ‘v=spf’,
domain => $domain.’.',
record => $domain.’.',
value => ‘v=spf1 a mx ?all’ };
}
For some reasons the quotes here are replaced to the other signs, replace all the symbols similar to quotes to usual quotes in the code above.
Just as a tip, this is what my postwwwacct script looks like now. It handles the DK, SPF and one other EXIM chore.
#!/usr/bin/perl
print “\nStarting install of Domainkeys and SPF records\n”;
my %OPTS = @ARGV;
my $user = $OPTS{’user’};
system(”/usr/local/cpanel/bin/domain_keys_installer”, $user);
system(”/usr/local/cpanel/bin/spf_installer”, $user);
print “\nDone with install of Domainkeys and SPF records\n”;
print “\nAdding domains to EXIM reverse lookup table\n”;
system(”/bin/sed ’s/\(.*\)\(: \)\(.*\)/\3: \1/’ /etc/domainips_reverse”);
print “\nDone adding domains to EXIM revese lookup table\n”;
exit;
I couldn’t understand some parts of this article SPF records on a cPanel server | cPanelConfig - cPanel server configuration guide, but I guess I just need to check some more resources regarding this, because it sounds interesting.
Thanks Eric,
Worked like a charm!
John
This was a great tutorial and helped me create an SPF record through cPanel - WHM. Thanks yolau!
When can us poor victims who signed-up to Cpanel-using web hosting companies get the ability to change our own domains SPF records ????????????????
[...] Just found this: how to install SPF records on a cPanel server [...]
It seems that I do not have the script directory of file (spf.pm)Am I doing somthing wrong?
I tried to run the pico /usr/local/cpanel/Cpanel/SPF.pm
but it only created a new file….
I was running it logged in as root….
I manually looked for the /usr dir and didn’t see it…
Help! ed.kalk@bitwiselogic.com
I figured it out…..
RE:
It seems that I do not have the script directory of file (spf.pm)Am I doing somthing wrong?
I tried to run the pico /usr/local/cpanel/Cpanel/SPF.pm
but it only created a new file….
I was running it logged in as root….
I manually looked for the /usr dir and didn’t see it…
Just an FYI. You want to be extremely careful about implementing SPF as customers do not always use you as the outgoing gateway and they may well use their ISP’s outgoing mail server with a reply to set to be their hosted incoming email server. if you implement an SPF without knowing then you will find your customers can no longer send emails outgoing.
http://www.openspf.org/FAQ/Common_mistakes#dont-guess
“Don’t assume – especially if you are an ISP
If you host e-mail for others, do not just create an SPF record for a customer without researching what e-mail servers that customer uses. You may find you have blocked or hindered your customer’s outgoing mail delivery from their in-office mail server, for example, or from end users who send mail through their home ISP’s mail server. See the hints for ISPs for the safe include magic”
[...] ( $is_complete ? ‘-all’ : ‘?all’ ) }; } (la idea en principio la saqué de: acá , pero en vista de que esta página no está actualizada, les actualizo los [...]
It seems there may have been some changes can you update what we are supposed to do as I see your example but I see user “Dennis” has another example which one would be correct?
Plus this is what I see in mine
foreach my $domain (@DOMAINS) {
push @installlist,
{
‘match’ => ‘v=spf’,
‘removematch’ => ( ( $overwrite || !$spf_match ) ? ‘v=spf’ : $spf_match ),
‘domain’ => $domain,
‘record’ => $domain,
‘value’ => ‘v=spf1 a mx’ . $safekeys . ( $is_complete ? ‘-all’ : ‘?all’ )
};
}
Thanks much to everyone for all the work. Just made my life a LOT easier!
Thank you very much for this guide. I own a hosting company and will provide all of my users accounts with the SPF record so their E-mail gets to the hotmail inbox instead of the junk e-mail folder.