To let a third-party mail using your own domain as sender and having properly implemented DKIM yourself you may come to realize that Plesk isn't helping you.
Some third-party mailers tell you to add a TXT-record containing their public key in your DNS.
This is not really the way to do it.
This way they will not be able to rekey their selector.
On top of never re-keying their selector these third-party mailers often have a 1024-bits key as they fit nicer into DNS. It becomes even more ugly than that. These mass-mailers will often also use that 1 key with its infinite lifetime to secure all their clients....
All these combinations suddenly doesn't make it that far fetched that some spammer or spearfisher takes the time to use bruteforce to find out that mass-mailer's key.
Luckily these mass-mailers are upping their game and they now are starting to use CNAMEs to distribute their public key. That's not enough as most do not have different cnames for each client. They are also, most probably, never changing their key either as this would need 2 selectors instead of one.
Microsoft is doing all this properly with their Office365. Check that out!!
All I've written thus far is just an introduction to make clear for which problem I have a solution.
When trying to implement, for instance, the CNAME that mass mailer Mailchimp is using you will notice that it's impossible to add that to your DNS.

That's because the Plesk webdeveloper decided to forbid the underscore character in the target.
The underscore character is already some time a valid one to use in domain names.
It was at the time when he needed to correct his other mistake when he added the _TCP / _UDP restriction to SRV-records.
Luckily this restriction is only made by Plesk's web developer and the CLI is working fine.
Somehow it takes them several years to correct their mistake. He added a restriction no-one asked for and somehow it isn't given any priority to take that out. I can't wait for that.
Although Microsoft is using an underscore in the CNAMEs they provide, they don't have to. I noticed that mailchimp isn't using it. Anyhow, I wanted to create a script that would not let me have to use the flexible CLI DNS tool and make those changes for me.
The result is this script.
The script takes a domain name as a parameter on the CLI.
The 2nd parameter is provided by the symbolic link.
The script's name is add_dkimspf
If you want to add the DKIM-record and SPF for mailchimp you need to create a symbolic link called "mailchimp" and point that to add_dkimspf
Then create a file called /usr/local/sbin/mailchimp.records and add the DKIM-record and selector.
ln -s add_dkimspf /usr/local/sbin/mailchimp
cat /usr/local/sbin/mailchimp.records
Adding the Mailchimp's DKIM-record and SPF-record to the domain yourclient.com becomes as easy as:
Adding another service is as easy now as creating the *.records file with that service's records and a symbolic link to /usr/local/sbin/add_dkimspf
An example for another service:
ln -s add_dkimspf /usr/local/sbin/efactuur
cat /usr/local/sbin/efactuur.records
Note that the script can also take DKIM2 and SELECTOR2 in the file.
Ironically this script does not work for Microsoft's DKIM as they have a different DKIM-key for each client. I have created a separate script for that.
The record for Mailchimp does not contain underscores and would therefore not be a problem. Other services may be tempted to use an underscore in their records. I have no other examples than Microsoft.
The script is much easier than firing up the Plesk interface anyhow and also prevents you from making a mistake.
Do take care that your SPF-record doesn't need more than 10 resolves to decypher. If it does, it may get discarded by the recipient.
[EDIT]
Noticed that script contained remnants of another script that I took as a template for this one.
Deleted those... (they weren't doing anything)
cat /usr/local/sbin/add_dkimspf
Some third-party mailers tell you to add a TXT-record containing their public key in your DNS.
This is not really the way to do it.
This way they will not be able to rekey their selector.
On top of never re-keying their selector these third-party mailers often have a 1024-bits key as they fit nicer into DNS. It becomes even more ugly than that. These mass-mailers will often also use that 1 key with its infinite lifetime to secure all their clients....
All these combinations suddenly doesn't make it that far fetched that some spammer or spearfisher takes the time to use bruteforce to find out that mass-mailer's key.
Luckily these mass-mailers are upping their game and they now are starting to use CNAMEs to distribute their public key. That's not enough as most do not have different cnames for each client. They are also, most probably, never changing their key either as this would need 2 selectors instead of one.
Microsoft is doing all this properly with their Office365. Check that out!!
All I've written thus far is just an introduction to make clear for which problem I have a solution.
When trying to implement, for instance, the CNAME that mass mailer Mailchimp is using you will notice that it's impossible to add that to your DNS.

That's because the Plesk webdeveloper decided to forbid the underscore character in the target.
The underscore character is already some time a valid one to use in domain names.
It was at the time when he needed to correct his other mistake when he added the _TCP / _UDP restriction to SRV-records.
Luckily this restriction is only made by Plesk's web developer and the CLI is working fine.
Somehow it takes them several years to correct their mistake. He added a restriction no-one asked for and somehow it isn't given any priority to take that out. I can't wait for that.
Although Microsoft is using an underscore in the CNAMEs they provide, they don't have to. I noticed that mailchimp isn't using it. Anyhow, I wanted to create a script that would not let me have to use the flexible CLI DNS tool and make those changes for me.
The result is this script.
The script takes a domain name as a parameter on the CLI.
The 2nd parameter is provided by the symbolic link.
The script's name is add_dkimspf
If you want to add the DKIM-record and SPF for mailchimp you need to create a symbolic link called "mailchimp" and point that to add_dkimspf
Code:
ls -altr /usr/local/sbin/mailchimp
lrwxrwxrwx 1 root root 27 Jul 26 12:40 /usr/local/sbin/mailchimp -> /usr/local/sbin/add_dkimspf
Then create a file called /usr/local/sbin/mailchimp.records and add the DKIM-record and selector.
ln -s add_dkimspf /usr/local/sbin/mailchimp
cat /usr/local/sbin/mailchimp.records
Code:
SELECTOR1=k1
DKIM1=dkim.mcsv.net
INCLUDE=servers.mcsv.net
Adding the Mailchimp's DKIM-record and SPF-record to the domain yourclient.com becomes as easy as:
Code:
mailchimp yourclient.com
Adding another service is as easy now as creating the *.records file with that service's records and a symbolic link to /usr/local/sbin/add_dkimspf
An example for another service:
ln -s add_dkimspf /usr/local/sbin/efactuur
cat /usr/local/sbin/efactuur.records
Code:
SELECTOR1=efactuur
DKIM1=dkim.efactuurdirect.nl
INCLUDE=_spf.efactuurdirect.nl
Note that the script can also take DKIM2 and SELECTOR2 in the file.
Ironically this script does not work for Microsoft's DKIM as they have a different DKIM-key for each client. I have created a separate script for that.
The record for Mailchimp does not contain underscores and would therefore not be a problem. Other services may be tempted to use an underscore in their records. I have no other examples than Microsoft.
The script is much easier than firing up the Plesk interface anyhow and also prevents you from making a mistake.
Do take care that your SPF-record doesn't need more than 10 resolves to decypher. If it does, it may get discarded by the recipient.
[EDIT]
Noticed that script contained remnants of another script that I took as a template for this one.
Deleted those... (they weren't doing anything)
cat /usr/local/sbin/add_dkimspf
Code:
#!/bin/bash
HEADLESS=
tty >/dev/null || HEADLESS=true
THISSCRIPT="`readlink -f $0`"
SCRIPTNAME=${THISSCRIPT##*/}
BASE=${THISSCRIPT##*/}
[ -z "${BASE}" ] && BASE=${0##*/}
RECORDS=${0}.records
LOG=/var/log/${SCRIPTNAME}.log
SELECTOR1=
SELECTOR2=
DKIM1=
DKIM2=
INCLUDE=
DOMAIN="`echo $1 | egrep '^[a-z0-9-]+\.[a-z0-9-]+$'`"
if [ -z "${DOMAIN}" ] ; then
echo "I need a valid domain" >&2
exit 1
fi
if ! grep -q "^DKIM1=" ${RECORDS} 2>/dev/null ; then
echo "There's no file called ${RECORDS} containing SELECTOR1=, DKIM1= and INCLUDE=" >&2
exit 1
fi
. ${RECORDS}
if [ -z "${DKIM1}" ] || [ -z "${SELECTOR1}" ] || [ -z "${INCLUDE}" ] ; then
echo "One of the parameters (DKIM1, SELECTOR1, or INCLUDE) is empty"
exit 1
fi
# Clean up some parameters
echo "${DKIM1}" | grep -q "\.$" || DKIM1="${DKIM1}." # Add a dot to the domain
echo "${INCLUDE}" | grep -q "^include:" || INCLUDE="include:${INCLUDE}" # Precede include: if it's not there
TMPDIR=`mktemp -t -d ${0//*\/}.XXXXXXXXXX`
TMPLOG=${TMPDIR}/log
date >${TMPLOG}
# Collect all the Plesk domains
mysql --skip-column-names -uadmin -p`cat /etc/psa/.psa.shadow` psa -e "SELECT domains.name FROM domains ORDER BY domains.name ASC; " 2>/dev/null | egrep -v '\..+\.' | tr 'A-Z' 'a-z' | sort -uo ${TMPDIR}/plesk_domains
if ! grep -q "^${DOMAIN}$" ${TMPDIR}/plesk_domains ; then
echo "The domain ${DOMAIN} does not exist on this server" >&2
echo "These exist:"
grep "^`echo ${DOMAIN} | cut -b1`" ${TMPDIR}/plesk_domains | sed 's/.*/\t&/g'
else
SPF_FOUND="`host -t txt ${DOMAIN} localhost 2>/dev/null | grep -o "v=spf1.*all"`"
DKIM1_FOUND="`host ${SELECTOR1}._domainkey.${DOMAIN} localhost 2>/dev/null | grep -o "is an alias for .*"`"
if [ -z "${DKIM1_FOUND}" ] ; then
echo "Add DKIM ${SELECTOR1}._domainkey.${DOMAIN} to ${DKIM1}" | tee -a ${TMPLOG}
/usr/local/psa/bin/dns --add ${DOMAIN} -cname ${SELECTOR1}._domainkey -canonical ${DKIM1} | tee -a ${TMPLOG}
else
DKIM1_TARGET="`echo ${DKIM1_FOUND} | awk '{print $5}'`"
if [ "${DKIM1_TARGET}" == "${DKIM1}" ] ; then
echo "DKIM ${SELECTOR1}._domainkey.${DOMAIN} pointing to ${DKIM1} is already added"
else
echo "error!! DKIM ${SELECTOR1}._domainkey.${DOMAIN} points to ${DKIM1_TARGET} not ${DKIM1}"
fi
fi
# If the 3rd party mailer is using 2 keys
# They should really, this is an indication that their keys are never rotated
if [ -n "${DKIM2}" ] && [ -n "${SELECTOR2}" ] ; then
echo "${DKIM2}" | grep -q "\.$" || DKIM2="${DKIM2}." # Add a dot to the domain
DKIM2_FOUND="`host ${SELECTOR2}._domainkey.${DOMAIN} localhost 2>/dev/null | grep -o "is an alias for .*"`"
if [ -z "${DKIM2_FOUND}" ] ; then
echo "Add DKIM ${SELECTOR2}._domainkey.${DOMAIN} to ${DKIM2}" | tee -a ${TMPLOG}
/usr/local/psa/bin/dns --add ${DOMAIN} -cname ${SELECTOR2}._domainkey -canonical ${DKIM2} | tee -a ${TMPLOG}
else
DKIM1_TARGET="`echo ${DKIM2_FOUND} | awk '{print $5}'`"
if [ "${DKIM2_TARGET}" == "${DKIM2}" ] ; then
echo "DKIM ${SELECTOR2}._domainkey.${DOMAIN} pointing to ${DKIM2} is already added"
else
echo "error!! DKIM ${SELECTOR2}._domainkey.${DOMAIN} points to ${DKIM2_TARGET} not ${DKIM2}"
fi
fi
fi
if [ -z "${SPF_FOUND}" ] ; then
echo "Totally no SPF for ${DOMAIN} is found, I will not make one then"
else
if echo "${SPF_FOUND}" | grep -q " ${INCLUDE} " ; then
echo "The SPF-record already contains ${INCLUDE} (${SPF_FOUND})"
else
NEW_SPF="`echo "${SPF_FOUND}" | sed "s/ .all$/ ${INCLUDE}&/g"`"
echo "Remove SPF for ${DOMAIN} containing \"${SPF_FOUND}\"" | tee -a ${TMPLOG}
/usr/local/psa/bin/dns --del ${DOMAIN} -domain "" -txt "${SPF_FOUND}" | tee -a ${TMPLOG}
echo "Add SPF for ${DOMAIN} containing \"${NEW_SPF}\"" | tee -a ${TMPLOG}
/usr/local/psa/bin/dns --add ${DOMAIN} -domain "" -txt "${NEW_SPF}" | tee -a ${TMPLOG}
fi
fi
cat ${TMPLOG} >>${LOG}
fi
rm -r ${TMPDIR}
Last edited: