• 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.

Question Wildcard certificates depend on DNS being installed

mr-wolf

Silver Pleskian
Plesk Guru
I have, for years, chosen to have DNS on a seperate Plesk server instead of the servers on which the domains of my clients are configured.
This gives me several advantages, but also disadvantages.

When Plesk implemented support for wildcard certificates I noticed that I suddenly had to create an _acme-challenge.<domain> TXT record.
I falsely assumed this would mean that this TXT-record would also be used for future references, but it turned out that these TXT-records need to be changed on each renewal of the certificate.

This means that I have to reissue all the wildcard certificates manually each 3 months.

I could delegate the specific _acme-challenge.<domain> to the Plesk server of the domain, but I'm afraid this will open a can of worms. For starters I'm also running a slave DNS-server on one of the "normal" Plesk servers outside the scope and control of Plesk (just a normal bind installation).

What is unclear to me is why Plesk changes to the DNS-01 challenge when I choose for a wildcard. Is this mandatory for wildcard certificates?

If it's not mandated by Letsencrypt, would it be possible for Plesk to detect if it is in control of DNS and if not chose the HTTP-01 challenge?


I Hopefully didn't find the correct answer here:
"In order to issue wildcard certificates, Let's Encrypt is going to require users to prove their control over a domain by using a challenge based on DNS"

EDIT:

Confirmed... DNS-01 is mandatory for wildcard certificates.
 
Last edited:
The Plesk interface does not allow me to use an underscore for NS-records, nor does the CLI
This means I have to create this record manually by directly manipulating the zonefile.

1598348544671.png
 
Last edited:
Yes, it works!!!

By having an NS-record on my authoritative DNS-server _acme-challenge.<domain> pointing to the server that is running the webserver and installing the DNS-extension on that webserver, I have this working.

The only problem is that I can't create an NS-record with an underscore with Plesk.
I could create a cronjob that detects a "acme-challenge.<domain> NS-record" and then modify the zone file to create a "_acme-challenge.<domain> NS record".

Better, of course, is a modification of Plesk that will allow me to create NS-records with underscores.
I will create a ticket for that.
 
The trick to get Letsencrypt wildcards work when you have a seperate DNS-server is to make use of "DNS delegation"
By having an NS-record with the name _acme-challenge.<domain> pointing to your webserver, you will tell Letsencrypt to query the webserver for the TXT-record _acme-challenge.<domain> instead of the main DNS-server.

My main DNS-server is also running Plesk, but it's not used for webservers.
This creates a new problem.
Plesk does NOT allow me to create NS-records with an underscore.
This is only a problem if your authoritative DNS-server is also running Plesk.

I worked around that by directly manipulating the zonefile on the main DNS-server.
With Plesk I create an NS-record with the name "acme-challenge.<domain>" (notice the absence of the underscore).
Each 5 minutes the cronjob parses the zonefiles and if it finds such a record which does not have a 2nd NS-record with an underscore, it will create one.

Hopefully Plesk will be quicker this time to adapt their software. I've waited many years for "underscore support" for other records.

This bash-script is only needed until Plesk has changed their software so it supports the creation of NS-records with underscores.

Here's the bash script:


ln -s /usr/local/sbin/dns-acme-challenge /etc/cron.5min/
cat /usr/local/sbin/dns-acme-challenge
Code:
#!/bin/bash
#
# Script to workaround the problem that Plesk is unable to create an NS-record with an underscore
# This is needed for the NS-record   _acme-challenge.<domain>
# The solution is to create an NS-record acme-challenge.<domain>
# This script will manipulate the zone-file directly and add a line with a preceding underscore
#
#

TMPDIR=`mktemp -t -d ${0//*\/}.XXXXXXXXXX`
ZONEFOLDER=/var/named/chroot/var
[ -d ${ZONEFOLDER} ] || ZONEFOLDER=/var/named/run-root/var

if [ ! -d ${ZONEFOLDER} ] ; then
  echo "Unable to find the folder containing the zone files" >&2
  exit 1
fi

# Collect all zonefiles containing a acme-challenge NS-record
find ${ZONEFOLDER} -type f -exec grep -l '^acme-challenge\..* IN NS' {} \; >${TMPDIR}/zonefiles

RESTART_NAMED=  # set flag to FALSE

# Parse these zone files
while read ZONEFILE ; do
  ZONECHANGE=
  # collect all NS lines with ^acme-challenge NS lines
  grep '^acme-challenge\..* IN NS' ${ZONEFILE} >${TMPDIR}/challenges

  # loop lines that have an acme-challenge NS-record (this script supports more than 1 line, like an extra subdomain)
  while read CHALLENGE ; do
    if ! grep -q "_${CHALLENGE}" ${ZONEFILE} ; then     # check first if it does not have an _acme-challenge line already

      sed -i "s/^${CHALLENGE}/&\n&/"   ${ZONEFILE}      # duplicate acme-challenge line
      sed -i "0,/^${CHALLENGE}/s//_&/" ${ZONEFILE}      # place an underscore before the first one
      ZONECHANGE=true  # create a flag to indicate a zone in the zone file has changed.
    fi
  done<${TMPDIR}/challenges

  if [ ${ZONECHANGE} ] ; then
    RESTART_NAMED=true  # create a flag to indicate that named needs to read all the configs again (at the end).

    SERIAL=`grep "; Serial" ${ZONEFILE} | awk '{print $1}'`   # read the serialnumber
    OLDSERIAL=${SERIAL}                                       # remember it
    let SERIAL+=1                                             # increment serial with 1
    sed -i "s/${OLDSERIAL}/${SERIAL}/" ${ZONEFILE}            # replace serial with incremented one.
  fi

done<${TMPDIR}/zonefiles

# If something changed then force a re-read of configs for named
[ ${RESTART_NAMED} ] &&  killall -HUP named

rm -r ${TMPDIR}

This code only needs to run regularly on the authoritative DNS-server. The DNS-template needs to contain this line


On the Plesk server that's running the website you would normally have no DNS extension running.
You need to install it there and change the template.
Remove all the default records from the template, but keep these 2.
Plesk wants to have at least 1 NS-record. It will not be used as that DNS-server is not propagated by your registrar.
The webserver's DNS-service will only be queried for the TXT-record _acme-challenge.<domain>. (by Letsencrypt).


Total DNS records: 2
Entries per page: 10 25 100 All
Host
sort-up.gif
Record typeValue
<domain>.NSns1.wolf.com.
_acme-challenge.<domain>.TXTunconfigured
Total DNS records: 2

EDIT 26-08-2020:

I didn't update the serialnumber in the zonefile of my original script. I fixed this.
I'm aware that Plesk does not know this new serial# and may use that same incremented serial next time. This will however be corrected in 5 minutes as each change of DNS in Plesk will remove the NS-records that are not in its own database.
This will trigger this script to re-write the zone-file
 
Last edited:
Hello,

i found your thread already , thanks for your answer. I uses ns1 for the _acme-challange.domain.tld ... everything works fine, except plesk renewal or manual update of the renewal cert.

i installed BIND DNS on my server, pointed the acme domain to my main domain (on my external provider dns server), but no luck. I created a _acme-challenge domain, which works fine. Also Plesk updates the TXT ... but.. i get this error when renewal cert:

Invalid response from https://acme-v02.api.letsencrypt.org/acme/authz-v3/......
Details:
Type: urn:ietf:params:acme:error:dns
Status: 400
Detail: DNS problem: SERVFAIL looking up TXT for _acme-challenge.domain.tld - the domain's nameservers may be malfunctioning
 
As I said, I have this working in a production environment.
This doesn't mean I never had an error message after first implementing it.
These error messages were all related to timing.

So on your Authoritative DNS-server you created an NS-record named "_acme-challenge.domain.tld" with the value domain.tld ??
Let that sink in for a while.

You installed the Plesk DNS extension on the Plesk server that is running domain.tld ??
You have removed any _acme-challenge.domain.tld TXT-record on the authoritative DNS-server?

You went to the Plesk DNS page of domain.tld and you initialized DNS?
You have checked from another server that DNS is working on the Plesk server that's running domain.tld ??
Code:
host domain.tld domain.tld
host -t ns _acme-challenge.domain.tld 8.8.8.8
host -t ns domain.tld 8.8.8.8
host -t txt _acme-challenge.domain.tld domain.tld

When reissuing the certificate manually from the LetsEncrypt extension there will be a pop-up.
During that time Plesk is creating a new TXT-record and you need to wait until that pop-up disappears.
If it doesn't work the first time, try it some time later.
The NS-record may not have sunk in at LetsEncrypt.

Before re-issuing the certificate you can change the _acme-challenge.domain.tld to a text like "unconfigured".
If LetsEncrypt sees "Unconfigured" you clicked too soon on "reissue"
It will also be easier to verify that Plesk is indeed updating the TXT-record on your server.

You checked in Plesk's DNS page that an _acme-challenge.domain.tld TXT-record is created or altered?

I know for sure it works this way in the end.
 
Last edited:
THanks for the fast reply..

My settings of the testdomain are attached as pictures. I can not delete a A record in plesk like you. I can see the "txt" which is the same as in plesk. Interesting, i can see the TXT record from another server which is on the same network, but not from my home client. so i will wait a little bit and try again later.

*update : i reset to default zone settings and now the A record is gone.
*update2: without the A record, plesk wouldnt let me to issue a cert, so i need at least one a record
 

Attachments

  • dns plesk.PNG
    dns plesk.PNG
    9.5 KB · Views: 23
  • dns domain.PNG
    dns domain.PNG
    13.2 KB · Views: 18
Last edited:
Your webserver will only be queried for the _acme-challenge.domain.tld
Still I would make sure that the content of the other records (the ones you are forced to implement) is correct.
Strange mine doesn't force an A-record.

I don't know if an NS-record of _acme-challenge.domain.tld is mandated by RFC's as a glue record.
It should be the better thing to do, but I can't use it in a template (because of the underscore).

Until Plesk has fixed this bug I will not use it as it would force me to use that bash script on all my Plesk servers.
I prefer to keep hacks to a minimum.
 
i have no problem to use it in the template, but letsencrypt give me an error that ns1.domain.tld needs to have an A record to work.

*** EDIT ***

Okay. Port 53 on TCP/UDP where blocked because i didnt save the iptables.

for all:
when using plesk dns extension you have to open port 53 udp/tcp manual via shell when NOT using plesk firewall... It seems that it is not open manually when installing the extension via webinterface...


Code:
iptables -I INPUT -m tcp -p tcp --sport 53 -j ACCEPT
iptables -I INPUT -m udp -p udp --sport 53 -j ACCEPT 
iptables -I INPUT -m udp -p udp --dport 53 -j ACCEPT 
iptables -I INPUT -m tcp -p tcp --dport 53 -j ACCEPT
 

Attachments

  • dns template.PNG
    dns template.PNG
    32.6 KB · Views: 8
Last edited:
You have opened port 53 of your firewall?
It wasn't needed before.
Also double check if it is listening op port 53 with netstat -ntlp | grep 53

dig @domain.tld _acme-challenge.domain.tld TXT gives me the same result as dig _acme-challenge.domain.tld TXT
They both return the TXT-record
That's because dig also honours DNS-delegation

In your template you have pointed the NS-record to ns1.<domain>
In a real world scenario it would always point to the same nameserver (the one you use for all your domains).
This means it shouldn't change with each domain, but be a literal value.
I have it on ns1.wolf.com not ns1.<domain>
 
Last edited:
Yes.. that was the problem. Now everything works fine... Thanks for the help.

Interesting that i can use _acme in template... i am using Plesk Onyx 17.8.11 Update #90

are u using obsidian?
 
I think you misunderstood.
Plesk doesn't support underscores for NS records.
For CNAMES or TXT it works (I had to lobby for that as well)

yes, I'm using Obsidian
 
no

I was focusing on your template where you had ns1. <domain> instead of a literal value like ns1.wolf.com

have as little records as possible there.
your webserver is not an authority.
records that don't make a difference can be confusing

it can be especially confusing if your webserver is using itself for DNS client requests.
 
Maybe i have no clue, but for my plesk version, there is no problem to create a NS Record with underscore as template or in domain dns settings. I was just talking about your bug report. It must be a bug in obsidian, not in onyx.

i usually dont update to the newest version of plesk because there are many bugs. once i messed up a whole server with a failed plesk update, so i stick to old versions until there is a new function that i need.
 
Maybe i have no clue, but for my plesk version, there is no problem to create a NS Record with underscore as template or in domain dns settings. I was just talking about your bug report. It must be a bug in obsidian, not in onyx.
That's surprising.
Sorry that I assumed a misunderstanding on your part. I have all my servers upgraded to Obsidian.
Because this underscore thing was already a limitation in Plesk Onyx some years ago for other type of DNS-records and I complained about that too, I assumed it was only partially fixed then.

That Plesk programmer is overdoing his efforts to filter invalid input.
In itself that's a good thing, but that's until he's being sloppy and disallowing more than he should.
He needs to investigate better what the RFC's are before becoming creative.

  • SRV-records for years could only do UDP & TCP services (fixed after 5 years)
  • Underscores were not allowed as value in CNAMES (fixed after 2 years)
  • Underscores for NS-records are not allowed. (not fixed yet)
 
Last edited:
This all is not new to me. When Plesk makes a major versions upgrade, there are many functions gone or faulty which where functional in ealier versions. i have no idea why this happens all the time. i am not sure if they code from scratch for the new version or they use old code.

They broke up the backup manager so many times, this is not acceptable. i stopped upgrading plesk and stick to manual mode. i have a testing environment for new versions, so if everything seems fine, i update plesk. many domain/webspace hosters act like that because they already know about these shitty updates.

But all the naming problems you mention are fixed in latest version of onyx. see screenshot below
 

Attachments

  • onyx.PNG
    onyx.PNG
    32.4 KB · Views: 14
Last edited:
First off, thanks, @mr-wolf, for the thorough breakdown.

I was working on following along and ran into a technical error that "can't" be bypassed due to IETF RFC 1123 (RFC 1123: Requirements for Internet Hosts - Application and Support).

Unless I misread the instructions, they say to create a nameserver in the format _acme-challenge.domain.tld. Unfortunately, the underscore is not a valid character to start a hostname with (additional reference Underscores not allowed | digicert.com). While some implementations do allow it, it can cause issues.

Based on the post here, it looks like Cloudflare allows it, so I suppose I could try it there and see if it works.

Thanks again @mr-wolf!
 
Back
Top