Is it possible to get challanges info without validation and generating certificate


I have script that upload to DirectAdmin using manual mode because my shared hosting don’t support lensencrypt out of the box (I also don’t have ssh and no root) and I wanted to automate the process of setting certificate.

I want my script to be universal so I thought that I write code that will set DNS challenge using DirectAdmin. The flow looks like this first I run certbot and then my script to POST the cert to DirectAdmin on my shared hosting server. But if DNS is not set, like when I want to add certificate for new domain or subdomain, the certbot will fail.

So my question is, can somehow get the challenges in a form of a text? Maybe run certbot in noninteractive mode, that will output challenges to set, without validating and generating Certificate. Is something like this exists.


IMHO, this could be done with the manual plugin.

certbot certonly --manual --preferred-challenges=dns --manual-auth-hook /path/to/script -d domainname

/path/to/script should be a simple script which echoes the corresponding variables (CERTBOT_VALIDATION, CERTBOT_TOKEN). I don’t know if certbot evaluates the exitcode of a hook-skript, maybe it could be forced to bail out on exitcode >0.


It ignores the exit code, I couldn’t find any graceful way to force Certbot to bail out.

Auth hook is definitely the way to go.


Unfortunately this don’t work I’ve put /bin/false and got message in red that Hook command return error code 1 but the certbot continue to validate the challanges. But maybe I can write second script that will set DNS records.


Did you plan to run certbot again later to finish the issuance process? Right now certbot doesn’t have a way to resume a previous challenge attempt. It expects to succeed or fail in a single pass. So, the auth-hook script is expected to complete the process of setting up the challenge before exiting (however long that takes and whatever method it uses).

#6 is a popular Let’s Encrypt client that does have a DNS authentication flow that lets you get the tokens with one CLI command and issue with another one later.

That being said, usually it is better to let your client try and complete issuance, even if you know it is going to fail. If you obtain tokens and don’t follow up on the validation, eventually your account will reach the pending authorizations rate limit.


Yes, I just reached the limit, I was testing my code that was uploading http challenge files and I’ve used certbot, because it was adding token and verification, instead testing the upload first with fake data, I didn’t know there is rate limit.

I decide to use http challenge, create the files and upload them to the sever using ftp. The upload now work so I need to wait until certbot is unlocked. (I don’t need to use staging because I only need to test valid certificate for new subdomain).

The only issue I have that I need to create bash script that execute my python script (I have one script that I use to upload the files and set Certificates in DirectAdmin) with parameter because I couldn’t find a way to pass it to certbot.

I need to execute this:

./ -d <List of comma separated domains>

is it possible to pass args to hook?


The domain is passed to your script in the $CERTBOT_DOMAIN environment variable.

For a full listing of all the environment variables set in hook scripts, see:


Yes I also use this variable the -d argument is for my domains that are connected to my shared hosting and $CERTBOT_DOMAIN contains both domains and subdomains.

The problem is that I can’t distinguish domains from subomains because some domains have more parts than the other, I want my script to be universal so I can’t assume that my domain have or instance two parts like because domain can be and both domains can have subdomains.


Ah, so you just want to hardcode the primary domain in your auth hook invocation rather than have certbot pass it?

In that case, just enclose the full command with arguments in quotes, e.g.:

sudo certbot --manual --preferred-challenges=http -d,, --manual-auth-hook '/path/to/ -d'


You could use the Python publicsuffix package and then

ps = publicsuffix.PublicSuffixList()
basedomain = lambda d: ps.get_public_suffix(d)

>>> ps.get_public_suffix("")
>>> ps.get_public_suffix("")


Awesome, thanks. Didn’t search for solutions because I’ve didn’t know that’s possible.