• Please be aware: Kaspersky Anti-Virus has been deprecated
    With the upgrade to Plesk Obsidian 18.0.64, "Kaspersky Anti-Virus for Servers" will be automatically removed from the servers it is installed on. We recommend that you migrate to Sophos Anti-Virus for Servers.
  • The Horde webmail has been deprecated. Its complete removal is scheduled for April 2025. For details and recommended actions, see the Feature and Deprecation Plan.
  • We’re working on enhancing the Monitoring feature in Plesk, and we could really use your expertise! If you’re open to sharing your experiences with server and website monitoring or providing feedback, we’d love to have a one-hour online meeting with you.

Input Add Office365 DKIM records to your Plesk's DNS

mr-wolf

Silver Pleskian
Plesk Guru
In another thread I already explained the difficulty of adding CNAME DNS-records with a target containing an underscore.

This is exactly what you need to do when you want to implement Microsoft's DKIM-solution.

For Microsoft you need to add 2 CNAMES and their names can be quite cryptic.
To ease all that out I created a script to do this for me.
You can't use the Plesk's GUI anyhow because of the bug, so let's crack some more if we're at it.

The script doesn't need parameters normally.
It will scan all the domains you're doing authorative DNS for and will only act upon domains with an MX containing "mail.protection.outlook"

For these domains it tries to guess the name that Microsoft gave it for internal usage.
They should have gone for "contoso.com" becomes "contoso-com.onmicrosoft.com", alas they went for something less strict.
My script will try to sort it out by trying several combinations.

If it is able to find out the name of the DKIM-target it will check it for validity and create the 2 needed selectors (selector1._domainkey & selector2._domainkey)

If the script is unable to resolve the internal name, you can give this as a parameter to the script.
The script will then try that as a last resort for each domain, but that will not be able to give any conflict.
When it comes to the appropriate domain it will be successful.

cat /usr/local/sbin/office365-dkim
Code:
#!/bin/sh

HEADLESS=
tty >/dev/null || HEADLESS=true
NAMED_FOLDER=/var/named/run-root/var
THISSCRIPT="`readlink -f $0`"
SCRIPTNAME=${THISSCRIPT##*/}
[ -z "${SCRIPTNAME}" ] && SCRIPTNAME=${0##*/}

LOG=/var/log/${SCRIPTNAME}.log
CONF=${THISSCRIPT}.conf
DOMAINS=${THISSCRIPT}.domains

ONMICROSOFT="`echo "$*" | tr 'A-Z' 'a-z]' | egrep -o "[a-z0-9-]+\.onmicrosoft\.com" | head -n1`"

if [ ! -d "${NAMED_FOLDER}" ] ; then
  echo "the folder ${NAMED_FOLDER} does not exist, quitting"
  exit 1
fi

TMP1=`mktemp`

# Extract all the authorative domains and filter out subdomain-, local- and arpa-records
grep 'SOA' ${NAMED_FOLDER}/* | awk -F: '{print $1}' | awk -F/ '{print $6}' | egrep -v '(local|arpa|.+\..+\..+)' | sort >${TMP1}

while read DOMAIN ; do

  MX="`host -t mx  ${DOMAIN}  localhost | grep -o 'is handled by .*' 2>/dev/null  | awk '{print $5}' | grep "protection.outlook.com" `"

  if [ -n "${MX}" ] ; then
    echo ${DOMAIN}


    SUBDOMAIN="`echo "${MX}" | sed 's/.mail.protection.outlook.*//g'`"
    TXT="`host -t txt selector1._domainkey.${DOMAIN} localhost 2>&1 | grep -o "descriptive text .*" | grep -o "v=DKIM" | sed 's/\\\//g' | head -n1`"

    if [ -n "${TXT}" ] ; then
      echo "${DOMAIN} already has an Office365 DKIM record"
    else

      FOUND_ONMICROSOFTCOM=
      SELECTOR="`echo "${MX}" | sed 's/.mail.protection.outlook.*//g'`"
      ONMICROSOFTCOM="`echo ${DOMAIN} | sed 's/\./-/g' | cut -b1-17`"
      N=1
      while [ $N -le 4 ] ; do
        TXTRECORD="selector1-${SELECTOR}._domainkey.${ONMICROSOFTCOM}.onmicrosoft.com"

        [ ${HEADLESS} ] || echo "$N. ${DOMAIN} Check ${TXTRECORD}"

        TXT="`host -t txt ${TXTRECORD} 2>/dev/null`"
        if echo "${TXT}" | grep -q "DKIM1" ; then
          FOUND_ONMICROSOFTCOM=true
          break
        fi
        let N+=1
        [ $N -eq 2 ] && ONMICROSOFTCOM="`echo ${DOMAIN} | sed 's/\..*//g' | cut -b1-17`"
        [ $N -eq 3 ] && SELECTOR="`echo ${DOMAIN} | sed 's/\.//g'`"
        [ $N -eq 4 ] && ONMICROSOFTCOM="`echo ${DOMAIN} | sed 's/\./-/g' | cut -b1-17`"
      done
      if [ ! ${FOUND_ONMICROSOFTCOM} ] && [ -n "${ONMICROSOFT}" ] ; then
        SELECTOR="`echo "${MX}" | sed 's/.mail.protection.outlook.*//g'`"
        TXT="`host -t txt selector1-${SELECTOR}._domainkey.${ONMICROSOFT} 2>/dev/null`"
        if echo "${TXT}" | grep -q "DKIM1" ; then
          FOUND_ONMICROSOFTCOM=true
          ONMICROSOFTCOM="`echo "${ONMICROSOFT}" | sed 's/.onmicrosoft.com//g'`"
        fi
      fi

      if [ ${FOUND_ONMICROSOFTCOM} ] ; then
        echo "${DOMAIN} create 2 CNAMES to DKIM-record @ ${ONMICROSOFTCOM}.onmicrosoft.com"

        /usr/local/psa/bin/dns --add ${DOMAIN} -cname selector1._domainkey -canonical selector1-${SELECTOR}._domainkey.${ONMICROSOFTCOM}.onmicrosoft.com
        /usr/local/psa/bin/dns --add ${DOMAIN} -cname selector2._domainkey -canonical selector2-${SELECTOR}._domainkey.${ONMICROSOFTCOM}.onmicrosoft.com
      else
        echo "${DOMAIN} Unable to find DKIM-record @ ${ONMICROSOFTCOM}.onmicrosoft.com"
      fi
    fi
  fi

done<${TMP1}

rm ${TMP1}
 
Last edited:
Back
Top