Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Release DNS01 Challenge #8

Open
Toxma opened this issue Oct 17, 2024 · 8 comments
Open

Release DNS01 Challenge #8

Toxma opened this issue Oct 17, 2024 · 8 comments

Comments

@Toxma
Copy link

Toxma commented Oct 17, 2024

Hi,

First, thank you for your amazing work, I am actually working with the serles-acme HTTP01 challenge, but for some technical reason I would like to swap for DNS01 challenge.
Do you think it's possible to implement this ?

Have a good day !

@uedvt359
Copy link
Contributor

This should be fairly easy; I would like to do it, but can't get the resources for it right now.

firstly, implement dns_challenge() in serles/challenge.py, with the same signature as the other two supported challenges, and call it from verify_challenge(). then, in a seperate commit, add it to the list of supported challenges.

for designing and implementing the challenge function, the rfc lays out nicely what needs to be done (boils down to making a TXT lookup and comparing it to the challenge).

if you want to take a crack at it, i'm happy to mentor the PR.

@uedvt359
Copy link
Contributor

some more notes:

  • we might need some changes in order to handle wildcard requests
  • ideally, dns requests for the everthing (not just the dns challenge) should probably be made with dnspython, and some configuration to specify dns servers would be great. for this PR, this is not needed, though.

@syberalexis
Copy link

Hi,
Thank's for this awesome project !

I make a PR for this issue.
I follow the RFC for implementation, it manages classic identifier and wildcard.

But I think it's better to leave the system DNS configuration rather than having a configuration file for that ;)

@uedvt359
Copy link
Contributor

uedvt359 commented Nov 6, 2024

I'll keep this ticket open until the next release, which is probably going to be 1.2.0.

@dmizin
Copy link

dmizin commented Nov 7, 2024

@syberalexis Thank you fir your work on DNS-01. Timing for me was impeccable :) Started similar yesterday, and then checked the repo this morning to find you already done it. Matrix ;) And as to wildcard - just tested and with EJBCA and BIND it works perfectly. Thanks again both of you!

@uedvt359
Copy link
Contributor

uedvt359 commented Nov 7, 2024

And as to wildcard - just tested and with EJBCA and BIND it works perfectly.

erm, this is strange: we don't yet implement wildcard handling. can you please elaborate on what you have done and what certificate was issued in the end?

@dmizin
Copy link

dmizin commented Nov 7, 2024

you have done and what certificate was issued in the end?

Not sure where to start, but basically running your code inside a container per EJBCA integration instructions. Injected the latest merged code. Running certbot like this:

certbot certonly \
 --manual \
 --preferred-challenges dns \
 --server https://XXXXX:8080/directory \
 --manual-auth-hook "./dns_nsupdate.sh deploy_challenge" \
 --manual-cleanup-hook "./dns_nsupdate.sh clean_challenge" \
 -d "toolbox.okd-stage.XXX.XXX" -d "*.toolbox.okd-stage.XXX.XXX" \
 --register-unsafely-without-email --agree-tos -v

Inside the hook against the BIND

#!/bin/bash

DOMAIN="${CERTBOT_DOMAIN}"
CHALLENGE="${CERTBOT_VALIDATION}"
ZONE="okd-stage.XXX.XXX."  # (end with a dot)
TSIG_KEY_FILE="XXX.key"  # TSIG key path
DNS_SERVER="xxx.xxx.xxx.xxx"

# Function to add a DNS-01 challenge record
add_record() {
  echo "Adding DNS record for _acme-challenge.${DOMAIN}"
  nsupdate -k "${TSIG_KEY_FILE}" <<-EOF
  server ${DNS_SERVER}
  zone ${ZONE}
  update add _acme-challenge.${DOMAIN}. 300 IN TXT "${CHALLENGE}"
  send
EOF
}

# Function to remove a DNS-01 challenge record
remove_record() {
  echo "Removing DNS record for _acme-challenge.${DOMAIN}"
  nsupdate -k "${TSIG_KEY_FILE}" <<-EOF
  server ${DNS_SERVER}
  zone ${ZONE}
  update delete _acme-challenge.${DOMAIN}. TXT
  send
EOF
}

# Certbot hook cases
case $1 in
  "deploy_challenge")
      add_record
      # Wait for DNS propagation (adjust time as needed)
      sleep 5
      ;;
  "clean_challenge")
      remove_record
      ;;
  "deploy_cert")
      echo "Certificate for ${DOMAIN} has been deployed."
      ;;
  "unchanged_cert")
      echo "Certificate for ${DOMAIN} is unchanged."
      ;;
  "exit_hook")
      echo "Exit hook for ${DOMAIN}"
      ;;
  *)
      echo "Unknown hook: $1"
      ;;
esac

And comes out to this:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            <redacted>
        Signature Algorithm: ecdsa-with-SHA256
        Issuer: C = US, O = <redacted>, CN = <redacted>
        Validity
            Not Before: Nov  7 20:28:53 2024 GMT
            Not After : Feb  5 20:28:52 2025 GMT
        Subject: CN = toolbox.okd-stage.<redacted>
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (2048 bit)
                Modulus:
                    <redacted>
                 Exponent: 65537 (0x10001)
        X509v3 extensions:
            X509v3 Basic Constraints: critical
                CA:FALSE
            X509v3 Authority Key Identifier:
                <redacted>
            X509v3 Subject Alternative Name:
                DNS:toolbox.okd-stage.<redacted>, DNS:*.toolbox.okd-stage.<redacted>
            X509v3 Extended Key Usage:
                TLS Web Server Authentication
            X509v3 Subject Key Identifier:
                <redacted>
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
    Signature Algorithm: ecdsa-with-SHA256
    Signature Value:
        <redacted>

Tried with only the wildmark and same result. End result:

image

Now, if anyone could tell me why this works with certbot and same is rejected with cert-manager on EJBCA side with "userdata did not fulfill end entity profile" - would really appreciate it :) Figured this part after long search - maybe a note in documents if someone wants to implement this with cert-manager. In End Entity Profile used for ACME - ensure you have enabled "Send Notification" in "Other Data" section. It only took me a one night and one day to figure this :)) Without this cert request failed with order is in "errored" state: Failed to finalize Order: 400 urn:ietf:params:acme:error:badCSR: Email notification cannot be used.

@uedvt359
Copy link
Contributor

uedvt359 commented Dec 2, 2024

I'm still puzzled why that request worked: certbot requested two identifiers, *.xyz and xyz. because we don't handle wildcards, it should have generated two challenges, and when validating _acme-challenge.*.xyz it should have failed (as * is not a valid label). we need to filter these out (and either fail immediately or implement proper wildcard support).

regarding your sidenote on cert-manager (a different ACME client, afaiu): because you used --register-unsafely-without-email on certbot, no email was passed to EJBCA when issuing the cert. you probably passed an email address with cert-manager. i was not aware that you'll actually get rejected in this case. if you want to submit a documentation improvement PR, please do!

@uedvt359 uedvt359 changed the title Implement DNS01 Challenge Release DNS01 Challenge Dec 16, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants