certera-io / certera

A central validation server for Let's Encrypt certificates

Home Page:https://docs.certera.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Doc DNS-01 challenge

AntonioCayulao opened this issue · comments

Hello,
We have a custom DNS and We want use the DNS-01 challenge but I dont understand the documentation in https://docs.certera.io/#dns-01

In Settings:

  1. The "Set DNS record script" where live? Inside Certera server, the server that serves the website that it will have after the wildcard, or the DNS server?

  2. The location inside the server is anyplace? Can be "/var/www/letsencrypt/.well-known/acme-challenge"? for example.

  3. The script arguments "--set -d {{Domain}} -n {{Record}} -r TXT -v {{Value}}" is okey?

  4. I have the site cloud.example.sh and the certificate will be *.example.sh, then I created the file _acme-challenge.example.sh
    in the path "/var/www/letsencrypt/.well-known/acme-challenge", but inside is empty.
    How I can get the token ACME to add to the file? And the content inside?

  5. What register CNAME I have to add to my DNS? How I can get it?

  6. If I want to use Certera with Cloudflare for example, How I can make this?

Greetings!

Hi @AntonioCayulao!

  1. The script can be anything you want and it can live anywhere you'd like. Since you know best about what DNS provider you're using, you can place the script anywhere on the same machine that hosts the Certera application. For example, I use dnsc (https://github.com/certera-io/dns-client-project) and have a copy at the following path on the same machine as Certera: /opt/dnsc. Take a look here for an example: #2 (comment)

In that example, I ended up creating a script that executes dnsc to make things more flexible (to as to not have parameterization in the input field. It also allows me to tweak the script without having to change what's configured in Certera).

image

  1. Yep, location can be anywhere. I wouldn't put the script in a place that can be reached by an external request. /var/www isn't the best place. What if someone makes an HTTP call and can read your script? It may contain sensitive information about how to call your DNS provider's API! Create a directory in /opt and place things there. It'll be much safer.

  2. That's up to your script. May I ask what script you're using to set DNS records in Cloudflare? That may help me to understand how it works and can provide better guidance.

4, 5 & 6. Your Cloudflare script will be what sets the DNS record. It doesn't need to live/reside in any /.well-known/acme-challenge directory, that's only used for HTTP-01 validation.

So, how it works is like this: if you tell Certera to use DNS-01 validation when creating a certificate, Certera will invoke the Set & Clean-up scripts you've configured in the Settings page.

Certera will pass via arguments the {{Value}} (the token that ACME wants to verify) to your DNS script. Your script needs to set that DNS record in Cloudflare with the {{Record}} Certera passes to your script.

To give you an example, let's say I owned the domain mysite.com and I wanted to use DNS-01 validation to create a certificate for a subdomain www.dev.mysite.com.

After configuring the script that simply sets/deletes DNS records in Cloudflare, Certera would call that script and give it the {{Record}} argument of _acme-challenge.www.dev you can concatenate this with {{Domain}} if you need the full record (since different DNS providers vary with how they get/set DNS records). The script would also get {{Value}} that contains the token that you'd set for the TXT record named _acme-challenge.www.dev.mysite.com. Certera would then tell ACME to verify it and it would check for a period of time to make sure the verification was successful. If that succeeds, Certera fetches the certificate and stores it so that you may use it however you want.

I hope that helps, if not, happy to elaborate and explain it more.

Cheers!

commented

I am not sure why but whenever a DNS01 challenge is trying to run any script or program (I ended up trying to run pwd commnad) i get Win32Exception

System.ComponentModel.Win32Exception (2): No such file or directory at System.Diagnostics.Process.ForkAndExecProcess(String filename, String[] argv, String[] envp, String cwd, Boolean redirect Stdin, Boolean redirectStdout, Boolean redirectStderr, Boolean setCredentials, UInt32 userId, UInt32 groupId, UInt32[] groups, Int32& stdinFd, Int32& stdoutFd, Int32& stderr Fd, Boolean usesTerminal, Boolean throwOnNoExec)

Have you stumbled across that maybe?
I have Ubuntu 20.04 , certera running as a systemd service. And I have no idea why would it not be able to find files

Hi @nomailme, could you create a new issue with that error, please? I'd like to track things and keep this issue separate. I haven't seen that before. Can you let me know what you have configured for the Set and Clean-up scripts and arguments on your Settings page? Also, check the permissions of the script and what user you're running Certera with under systemd (if not as root).

@AntonioCayulao hopefully I've answered your question. If you still have concerns or issues, don't hesitate to re-open this issue and we can discuss more.

Thank you for your response.

I have this:

  1. I created a folder in /opt/dnsc
  2. Inside the folder I created a file called setdns
  3. The file has inside:
#!/bin/bash

#echo "$@"
echo "$@" > /opt/dnsc/record.txt

sleep 60
  1. The permissions are:
[root@certera dnsc]# ls -l
total 46624
-rwxr--r-- 1 certerauser root               0 Sep 22 18:21 deldns
-rwxr--r-- 1 certerauser root        47731206 Sep 20 12:56 dnsc
-rw-r--r-- 1 certerauser certerauser       71 Sep 22 21:48 record.txt
-rwxr-xr-x 1 certerauser root              68 Sep 22 21:43 setdns
  1. I tried to use the data inside record.txt to update my DNS server (this server is custom, no cloudflare, ni anyone).
    adding:
    _acme-challenge IN TXT QJ_...
    I created a file called _acme-challenge inside the server with the same value inside it that the value in DNS record.

But the challenge not works:

Forbidden urn:ietf:params:acme:error:unauthorized Incorrect TXT record "QJ..." found at _acme-challenge.mysite.sh

  1. If I do:
    dig TXT _acme-challenge.mysite.sh +short

show that the DNS works.

For now I need make this manually. The risk is too high to automate.

Certbot has the option to wait until add the register to DNS. How I can make this with certera?

Certbot has the option to wait until add the register to DNS. How I can make this with certera?

This is the issue here. Because your script doesn't actually set the DNS, the validation fails from Let's Encrypt. Certera doesn't have a way currently to wait until you've set the DNS. The best thing you can do is sleep for a longer amount of time, sufficient for you to read the value passed to the script and written to the record.txt file.

I'm not a big fan of this. Because of how prevalent Cloudflare DNS is, I think you should be able to find a descent CF CLI to utilize within your script.

Here's one that looks really good and easy to use: https://github.com/AnalogJ/lexicon
And another just in case: https://github.com/danielpigott/cloudflare-cli

Here's how I'd do it with lexicon (apologies, this is untested...)

#!/bin/bash

# Setup Cloudflare environmental variables:
export LEXICON_CLOUDFLARE_USERNAME="myusername@example.com"
export LEXICON_CLOUDFLARE_TOKEN="cloudflare-api-token"

# Make sure you're passing in the following values as your script arguments: {{FullRecord}} {{Subject}} {{Domain}} {{Record}} {{Value}}
# Then, you can just access them via the parameters as needed

# $1 -- {{FullRecord}} - The full record (e.g. _acme-challenge.www.dev.mysite.com)
# $2 -- {{Subject}} - The domain for which the certificate is being obtained (e.g. www.dev.mysite.com)
# $3 -- {{Domain}} - The registrable domain of the certificate being requested (e.g. mysite.com)
# $4 -- {{Record}} - The TXT record name to create (e.g. _acme-challenge.www.dev)
# $5 -- {{Value}} - The value to place in the TXT DNS record (this is the token that will be verified by ACME)

# NAME will be _acme-challenge.www.dev.mysite.com. (note the ending period here)
NAME="$1."
SUBJECT="$2"
VALUE="$3"

# I think this should work. You may need to change/tweak the SUBJECT value depending on how "zones" are done in CF

lexicon cloudflare create $SUBJECT TXT --name="$NAME" --content="$VALUE"

Should be super easy to test/validate outside of Certera to make sure it works as expected. Then, if it all works ok, wire it up in Certera and see if that works as expected. This should help with rate limits if you're not using the "staging" instance of Let's Encrypt.

Cheers!

Similarly, you'll want to create a "clean up" script to delete/remove old TXT records so things stay performant: https://dns-lexicon.readthedocs.io/en/latest/user_guide.html

I was having entropy issue with my DNS system so DNS updates took a few minutes to propagate. During this, I noticed Certera will only let a script run for 60s before it kills the process so just be aware that you can only sleep in your script for a limited time:
private const int PROCESS_WAIT_MS = 60000

Fortunately I resolved my issue and everything works fine now.

Ha! I had forgot that it had a 60 second timeout. Even after seeing that exact line in the PR submitted by nomailme.

Well, I'm glad you resolved your issue and that everything is working fine now.