-
Notifications
You must be signed in to change notification settings - Fork 60
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
Module for handling dns-01 challenges by Dynamic DNS updates #90
Open
Yenya
wants to merge
3
commits into
do-know:master
Choose a base branch
from
Yenya:dynamic-dns
base: master
Could not load branches
Branch not found: {{ refName }}
Could not load tags
Nothing to show
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Conversation
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
NAME Crypt::LE::Challenge::DDNS - use dynamic DNS for ACME challenges SYNOPSIS use Crypt::LE; use Crypt::LE::Challenge::DDNS; ... my $le = Crypt::LE->new(); my $ddns_challenge = Crypt::LE::Challenge::DDNS->new(...); .. $le->accept_challenge($ddns_challenge, ...); $le->verify_challenge($ddns_challenge, ...); # Shell command line: $ le.pl ... --handle-as dns --handle-with Crypt::LE::Challenge::DDNS \ --handle-params '{"server": "127.0.0.1", "keyfile": "/var/named/keys/_le.example.org.key", "zone": "_le.example.org"}' DESCRIPTION This module uses Dynamic DNS (DDNS) updates for storing the ACME challenges for DNS-01 validation. Recommended mode of operation is to set up a Dynamic DNS subdomain solely for ACME challenges (for example, "_le.example.org"), and for domain names which would use Let's Encrypt certificates map their "_acme-challenge.$fqdn" into this domain. For example, to get a certificate for "myhost.example.org", create the following static DNS record in the "example.org" zone: _acme-challenge.myhost.example.org. IN CNAME myhost.example.org._le.example.org. This module will then ask the ACME server (Let's Encrypt CA) for a DNS-based challenge, and will store it using DDNS update to "myhost.example.org._le.example.org." TXT record. LE will then try to verify the challenge at "_acme-challenge.myhost.example.org" and will find it after being redirected by the above CNAME record. Note that ""example.org"" string is used both in the DDNS domain name, and inside that name. This is intentional - this way one common DDNS domain "_le.example.org" can serve for ACME challenges for multiple real DNS domains. If you want the renaming to be done in a different way, feel free to override the rr_from_fqdn() function in this module. The module accepts the following parameters (usable in "--handle-params" from the "le.pl" command line): server IP address of the DDNS server, where challenges will be stored. keyfile Authentication key for DDNS. This will be used for signing the DDNS update requests. Any key file format supported by "Net::DNS::RR::TSIG" will do. zone DDNS zone to which challenges will be written ("_le.example.org" in the above examples). If "zone" is a suffix of the host name for which the certificate is being created (e.g. "example.org"), then the challenge will be stored directly to _acme-challenge.$that_host_name instead of mapping to a different zone as described above. DDNS ZONE SETUP A quick and dirty tutorial how to create a Dynamic DNS zone and key in BIND. Firstly, create directories and the key file: BIND_DIR=/var/named DDNS_DOMAIN=_le.example.org install -d -u named -g named -m 775 $BIND_DIR/dynamic install -d -u root -g named -m 755 $BIND_DIR/keys tsig-keygen $DDNS_DOMAIN > $BIND_DIR/keys/$DDNS_DOMAIN.key chown root:named $BIND_DIR/keys/$DDNS_DOMAIN.key chmod 640 $BIND_DIR/keys/$DDNS_DOMAIN.key Create a zone file: cat > $BIND_DIR/dynamic/$DDNS_DOMAIN <<'EOF' $TTL 300 IN SOA ns.example.org. root.example.org. ( 1 ; serial 1H ; refresh 3H ; retry 2W ; expire 1 ; negative ttl ) IN NS ns.example.org. EOF Use the key and zone file in your named.conf: include "keys/_le.example.org.key"; zone "_le.example.org" { type master; file "dynamic/_le.example.org"; allow-query { any; }; allow-update { !{ !127.0.0.1; any; }; key _le.example.org; }; journal "dynamic/_le.example.org.jnl"; } Reload named and verify that it works: rndc reload nsupdate -k $BIND_DIR/keys/$DDNS_DOMAIN.key > server 127.0.0.1 > add test._le.example.org. 300 TXT "my test record" > send host -t any test._le.example.org. 127.0.0.1 SEE ALSO <https://letsencrypt.org/docs/challenge-types/>, Crypt::LE, Net::DNS::RR::TSIG, Crypt::LE::Challenge::Simple, nsupdate(1), tsig-keygen(1) AUTHOR Jan "Yenya" Kasprzak "<kas you_know_what yenya.net>". Based on "Crypt::LE::Challenge::Simple" by Alexander Yezhov.
guest20
reviewed
Apr 2, 2024
For wildcard certificates (*.$fqdn), ACME queries _acme-challenge.$fqdn, without the "*." prefix, obviously. This has to be taken into account when remapping the wildcard name to a different DDNS subdomain. Moreover, when getting certificate for both $fqdn and *.$fqdn, Crypt::LE calls ->handle_challenge_dns() twice for the same $fqdn, and ACME expects _two_ TXT records. So we should not blindly delete the TXT record at the beginning of ->handle_challenge_dns(). My approach is to count the number of times we've got called for each $fqdn, store it in $self->{fqdn_seen}->{$fqdn}, and delete the TXT only in the first handle_challenge_dns() call, and in the last handle_verification_dns() call.
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Hello, Alexander,
I have written a module for storing dns-01 ACME challenges in the Dynamic DNS domain. Do you think it is suitable for inclusion in the Crypt::LE distribution?
Thanks,
-Yenya