• We value your experience with Plesk during 2024
    Plesk strives to perform even better in 2025. To help us improve further, please answer a few questions about your experience with Plesk Obsidian 2024.
    Please take this short survey:

    https://pt-research.typeform.com/to/AmZvSXkx
  • 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.

CLI change DNS

Frater

Regular Pleskian
I would like to change DNS-records from the CLI because it is too much work to go through all the different domains and changing them using a GUI
I found this page, but there aren't that many examples given.
It's rather ambiguous what I have to put there or it's just not working... I don't know....

I would like to remove all SRV-records that were set once using a template.
They were ment to improve the autodiscovery of the mail settings, but I now believe these are worse than having no directives in DNS


Code:
# grep '_imap._tcp.mydomain.com' /var/named/run-root/var/*
/var/named/run-root/var/mydomain.com:_imap._tcp.mydomain.com.          IN SRV 5 50 143 imap.mydomain.com.

I tried this command and some variations on it, but it always responds with "Unable to del record in DNS server: unable to find DNS record"

Code:
/usr/local/psa/bin/dns --del mydomain.com -srv mydomain.com -srv-priority 5 -srv-weight 50 -srv-port 143 -srv-protocol tcp -srv-service imap -srv-target-host imap.mydomain.com

Could someone point out where I'm going wrong?
 
Looks like a bug. I have reproduced it and submitted request to developers (PPPM-1293 for your and my reference). As possible workaround you can try to remove srv record from dns_recs table and then run dnsmng --update
 
Looks like a bug. I have reproduced it and submitted request to developers (PPPM-1293 for your and my reference). As possible workaround you can try to remove srv record from dns_recs table and then run dnsmng --update

Very much appreciated.

I feel somewhat uneasy with MySQL.
Would you know the command to remove all SRV-records containing imap in the database...?
 
Just find all dns records with SRV type and imap:

mysql> select * from dns_recs where type='SRV' and host like '%imap%';

and remove needed.
 
Also as possible workaround you can use -srv-target-host option without trailing dot.
 
Also as possible workaround you can use -srv-target-host option without trailing dot.

Your efforts are appreciated, but that doesn't work.
I didn't use a trailing dot in my example, btw.
I just tried all the different combinations.

Could you give a working example for domain.com ?

Is there now work being done by the development team to make this more robust?
 
Have you tried this variant?

# /usr/local/psa/bin/dns --del mydomain.com -srv '' -srv-priority 5 -srv-weight 50 -srv-port 143 -srv-protocol tcp -srv-service imap -srv-target-host imap.mydomain.com
 
Hello, you have used wrong subdomain in your example:
root@a10-52-148-181:~# /usr/local/psa/bin/dns --add mydomain.com -srv "" -srv-priority 5 -srv-weight 50 -srv-port 143 -srv-protocol tcp -srv-service imap -srv-target-host imap.mydomain.com
SUCCESS: Creation of DNS record in Domain 'mydomain.com' complete.
root@a10-52-148-181:~# grep -r imap /var/named/run-root/
/var/named/run-root/var/mydomain.com:_imap._tcp.mydomain.com. IN SRV 5 50 143 imap.mydomain.com.
root@a10-52-148-181:~# /usr/local/psa/bin/dns --del mydomain.com -srv "" -srv-priority 5 -srv-weight 50 -srv-port 143 -srv-protocol tcp -srv-service imap -srv-target-host imap.mydomain.com
SUCCESS: Removal of DNS record in Domain 'mydomain.com' complete.
 
Ah, of course...
That works and already wrote a little script and removed all the obsolete records.

Thanks
 
For anyone who's interested
I'm running Plesk for many clients that don't know what DNS is, so I'm more or less in charge.
During a migration the TTL is changed and the SOA-records probably as well. Later all this is forgotten and stays unnecessarily at a too low value.

With 1 command I can set all the records straight on my Plesk server with this script:

# cat /usr/local/sbin/pleskresetsoa
Code:
#!/bin/sh
# Author: JP
#
# Resets all SOA-records and TTL on a Plesk server
#

PSADNS=/usr/local/psa/bin/dns
ZONEDIR=/var/named/run-root/var
TTL=1D
REFRESH=4H
RETRY=1H
EXPIRE=1W
MINIMUM=3H

if ! which dig >/dev/null 2>&1 ; then
  echo "This script needs 'dig' installed" >&2 ; exit 1
fi
if [ ! -d ${ZONEDIR} ] ; then
  echo "${ZONEDIR} is not a folder" >&2 ; exit 1
fi
if [ ! -x ${PSADNS}  ] ; then
  echo "I can't find Plesk's DNS-tool ${PSADNS}" >&2 ; exit 1
fi

human2seconds ()
{
  SECONDS=0
  PARAM=`echo $1 | tr 'a-z' 'A-Z' | egrep '^[0-9]+[SMHDW]$'`
  if [ -n "${PARAM}" ] ; then
    TIME_DIV=`echo ${PARAM} | tr -d '0-9'`
    TIME=`echo ${PARAM} | tr -cd '0-9'`
    case ${TIME_DIV} in
      W)  SECONDS=$((604800 * ${TIME} )) ;;
      D)  SECONDS=$((86400  * ${TIME} )) ;;
      H)  SECONDS=$((3600   * ${TIME} )) ;;
      M)  SECONDS=$((60     * ${TIME} )) ;;
      S)  SECONDS=$((1      * ${TIME} )) ;;
    esac
  fi
  echo ${SECONDS}
}

seconds2human ()
{

  HUMAN="0S"
  SECONDS=`echo "$1" | tr -cd '0-9'`
  if [ ! -z "${SECONDS}" ] ; then
    if   [ $((   ${SECONDS} % 604800)) -eq 0 ] ; then
      HUMAN="$(( ${SECONDS} / 604800 ))W"
    elif [ $((   ${SECONDS} % 86400)) -eq 0 ] ; then
      HUMAN="$(( ${SECONDS} / 86400 ))D"
    elif [ $((   ${SECONDS} % 3600)) -eq 0 ] ; then
      HUMAN="$(( ${SECONDS} / 3600 ))H"
    elif [ $((   ${SECONDS} % 60)) -eq 0 ] ; then
      HUMAN="$(( ${SECONDS} / 60 ))M"
    else
      HUMAN="${SECONDS}S"
    fi
  fi
  echo "${HUMAN}"
}

TMP1=`mktemp`
grep 'SOA' ${ZONEDIR}/* | awk -F: '{print $1}' | awk -F/ '{print $6}' | egrep '^[a-z0-9-]+\.[a-z]+$' | sort | uniq | egrep -v '\.(local|rev)$' >${TMP1}

TTLs=`human2seconds ${TTL}`
REFRESHs=`human2seconds ${REFRESH}`
RETRYs=`human2seconds ${RETRY}`
EXPIREs=`human2seconds ${EXPIRE}`
MINIMUMs=`human2seconds ${MINIMUM}`

SOAreset="$REFRESHs $RETRYs $EXPIREs $MINIMUMs"

echo "SOA will reset to $REFRESHs $RETRYs $EXPIREs $MINIMUMs (Refresh=$REFRESH Retry=$RETRY Expire=$EXPIRE Minimum=$MINIMUM)"
echo -e "TTL will reset to ${TTL}\n"

while read DOMAIN ; do
  echo -en "\r${DOMAIN}                   \r"
  SOA=`host -t SOA ${DOMAIN} 127.0.0.1 2>/dev/null | grep -o 'has SOA record .*' | head -n1 `

  if [ ! -z "${SOA}" ] ; then

    curTTL=`dig @127.0.0.1 ${DOMAIN} 2>/dev/null | grep -A1 'ANSWER SECTION:' | egrep '[0-9]+.*IN.*A.*[0-9.]+' | head -n1 | awk '{print $2}'`

    if [ -z "${curTTL}" ] ; then
      echo "Error obtaining TTL for ${DOMAIN} from this server" 2>/dev/null
    else
      curREFRESH=`echo ${SOA} | awk '{print $7}'`
      curRETRY=`  echo ${SOA} | awk '{print $8}'`
      curEXPIRE=` echo ${SOA} | awk '{print $9}'`
      curMINIMUM=`echo ${SOA} | awk '{print $10}'`

      SOAcur="$curREFRESH $curRETRY $curEXPIRE $curMINIMUM"

      if [ ! "${SOAcur}" == "${SOAreset}" ] || [ ${TTLs} -ne ${curTTL} ] ; then
        echo -e "${DOMAIN}:"
        [ ${TTLs} -ne ${curTTL} ]       && echo "TTL is now `seconds2human ${curTTL}` and will be set to ${TTL}"
        [ "${SOAcur}" = "${SOAreset}" ] || echo "SOA is now ${SOAcur} and will be set to ${SOAreset}"

        ${PSADNS} --update-soa $DOMAIN -soa-ttl ${TTL} -soa-refresh ${REFRESH} -soa-retry ${RETRY} -soa-expire ${EXPIRE} -soa-minimum ${MINIMUM}
        echo -e '\n'
      fi
    fi
  fi
done<${TMP1}
rm ${TMP1}
echo '                                          '
 
Here's another script regarding DNS to check if there are domains left behind or there's a difference between the authorative nameservers.


# cat /usr/local/sbin/dnsconfigcheck
Code:
#!/bin/bash
# Author: JP van Melis

ZONEFILE="$1"

NAMED_CONF=/etc/named.conf
CACHING_DNS=8.8.8.8

ZONES=`mktemp`
THIS_SERVER_A=`mktemp`
THIS_SERVER_IP=`mktemp`
IP_SOA=`mktemp`
IP_AUTH=`mktemp`

# get this server's IP's
ifconfig | egrep -o 'inet( | addr:)[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' | tr -cd '0-9.\n' >${THIS_SERVER_IP}

# extract domain names from named.conf or given file
if [ -z "${ZONEFILE}" ] || [ ! -f "${ZONEFILE}" ] ; then
  egrep -o '^zone \"[a-z0-9-]+\.[a-z]+\"' ${NAMED_CONF} | awk '{print $2}' | tr -d '"' >${ZONES}
else
  egrep -o '[a-z0-9-]+\.[a-z]+' ${ZONEFILE} >${ZONES}
fi
sed -i '/^domain.com$/d' ${ZONES}
# Parse all the domains
while read ZONE ; do
  echo -en "${ZONE}                    \r"

  # Get SOA-record
  SOA=`host -t SOA ${ZONE} ${CACHING_DNS} 2>/dev/null | egrep -o 'has SOA record [A-Za-z0-9.-]+' | awk '{print $4}'`

  if [ -z ${SOA} ] ; then
    echo "${ZONE}:" | awk '{ printf("%-35s",$0)}'
    echo "has no SOA-record (according to ${CACHING_DNS})"
  else
    IT_IS_ME=
    if ! grep -q ${ZONE} ${THIS_SERVER_A} ; then
      # Collect all the IP's of that SOA-record
      host -t A ${SOA} ${CACHING_DNS} 2>/dev/null | egrep -o 'has address [0-9.]+'| awk '{print $3}' >${IP_SOA}
      while read IP ; do
        # Check if the SOA-record points to one of my IP-addresses
        if grep -q "^${IP}$" ${THIS_SERVER_IP} ; then
          IT_IS_ME=${IP}
          echo "${ZONE}" >>${THIS_SERVER_A}
          break
        fi
      done <${IP_SOA}

      # If the domain is foreign then warn me
      if [ ! ${IT_IS_ME} ] ; then
        echo "${ZONE}:" | awk '{ printf("%-35s",$0)}'
        echo "has ${SOA} as SOA-record (not me)"
      fi
    fi
    if [ ${IT_IS_ME} ] ; then
      egrep -A15 "zone.+\"${ZONE}" ${NAMED_CONF} | grep -B20 '^};' | grep -A8 'allow-transfer {' | grep -B8 'common-allow-transfer;' | egrep -o '[0-9]+\.[0-9]+\.[0-9]+\.[0-9]+' >${IP_AUTH}
      if [ -s ${IP_AUTH} ] ; then
        SOA_THIS_SERIAL=`host -t SOA ${ZONE} ${IT_IS_ME} 2>/dev/null | egrep -o 'has SOA record [A-Za-z0-9.-]+ .*' | awk '{print $6}'`
        while read IP ; do
          SOA_AUTH_COMPLETE=`host -t SOA ${ZONE} ${IP} 2>/dev/null | egrep -o 'has SOA record [A-Za-z0-9.-]+ .*'`
          SOA_AUTH=`echo "${SOA_AUTH_COMPLETE}" | awk '{print $4}'`
          SOA_AUTH_SERIAL=`echo "${SOA_AUTH_COMPLETE}" | awk '{print $6}'`
          if [ -z "${SOA_AUTH}" ] ; then
            echo "${ZONE}:" | awk '{ printf("%-35s",$0)}'
            echo "Unable to resolve the SOA-record at the IP ${IP}"
          elif [ ! "${SOA_AUTH}" = "${SOA}" ] ; then
            echo "${ZONE}:" | awk '{ printf("%-35s",$0)}'
            echo "The SOA-record I resolved at the IP ${IP} (${SOA_AUTH}) is different than the one I resolved using ${CACHING_DNS} (${SOA})"
          elif [ ! "${SOA_AUTH_SERIAL}" = "${SOA_THIS_SERIAL}" ] ; then
            echo "The serial of the SOA-record I resolved at the IP ${IP} (${SOA_AUTH_SERIAL}) is different than the one I resolved using ${IT_IS_ME} (${SOA_THIS_SERIAL})"
          fi
        done<${IP_AUTH}
      else
        echo "${ZONE}:" | awk '{ printf("%-35s",$0)}'
        echo "No IP's for Authorative Namerserver found in ${NAMED_CONF}"
      fi
    fi
  fi
done<${ZONES}
echo "                                "

rm ${ZONES}
rm ${THIS_SERVER_A}
rm ${THIS_SERVER_IP}
rm ${IP_SOA}
rm ${IP_AUTH}
 
Last edited:
Back
Top