290
290
# 2023-02-04 Create newline to ensure [SAN] section can be parsed (#792)(MRigal)
291
291
# 2023-02-22 Remove cronie from deb package dependencies (2.48)
292
292
# 2024-03-16 Use FTP_PORT when deleting ftp tokens. Delete tokens when using sftp, davfs, ftpes, ftps (#693,#839) (tlhackque)
293
+ # 2024 03-16 Fix dns-01's CNAME processing. (#840) (tlhackque)
293
294
# ----------------------------------------------------------------------------------------
294
295
295
296
case :$SHELLOPTS : in
@@ -594,26 +595,12 @@ check_challenge_completion_dns() { # perform validation via DNS challenge
594
595
check_result=$( grep -i " ^${rr} " <<< " ${check_output}" | grep ' IN\WTXT' | awk -F' "' ' { print $2}' )
595
596
debug " check_result=\" $check_result \" "
596
597
597
- # Check if rr is a CNAME
598
- if [[ -z " $check_result " ]]; then
599
- rr_cname=$( grep -i " ^${rr} " <<< " ${check_output}" | grep ' IN\WCNAME' | awk ' { print $5}' )
600
- debug " cname check=\" $rr_cname \" "
601
- if [[ -n " $rr_cname " ]]; then
602
- # shellcheck disable=SC2086
603
- check_output=$( $DNS_CHECK_FUNC $DNS_CHECK_OPTIONS TXT " ${rr_cname} " " @${ns} " )
604
- check_result=$( grep -i " ^${rr_cname} " <<< " ${check_output}" | grep ' IN\WTXT' | awk -F' "' ' { print $2}' | uniq)
605
- fi
606
- fi
598
+ # No need to check if rr is a CNAME, because the CNAME is static and this is called
599
+ # with the target of the CNAME, which is the record added for verification.
600
+ # In theory, a chain of CNAMEs might exist. Not clear that an issuer would follow
601
+ # more than one. The code previously present here only tried to handle one.
602
+ # If there is no CMAME (the usual case), ${rr} is always in ${d}.
607
603
608
- if [[ -z " $check_result " ]]; then
609
- # shellcheck disable=SC2086
610
- debug " $DNS_CHECK_FUNC " $DNS_CHECK_OPTIONS ANY " ${rr} " " @${ns} "
611
- # shellcheck disable=SC2086
612
- check_result=$( $DNS_CHECK_FUNC $DNS_CHECK_OPTIONS ANY " ${rr} " " @${ns} " \
613
- | grep -i " ^${rr} " \
614
- | grep ' IN\WTXT' | awk -F' "' ' { print $2}' )
615
- debug " check_result=\" $check_result \" "
616
- fi
617
604
elif [[ " $DNS_CHECK_FUNC " == " host" ]]; then
618
605
debug " $DNS_CHECK_FUNC " -t TXT " ${rr} " " ${ns} "
619
606
check_result=$( $DNS_CHECK_FUNC -t TXT " ${rr} " " ${ns} " \
@@ -1441,21 +1428,24 @@ for d in "${alldomains[@]}"; do
1441
1428
| sed -e ' s:=*$::g' -e ' y:+/:-_:' )
1442
1429
debug auth_key " $auth_key "
1443
1430
1444
- add_dns_rr " ${d} " " ${auth_key} " \
1445
- || error_exit " DNS_ADD_COMMAND failed for domain $d "
1446
-
1447
1431
# shellcheck disable=SC2018,SC2019
1448
1432
rr=" _acme-challenge.$( printf ' %s' " ${d# \* .} " | tr ' A-Z' ' a-z' ) "
1449
1433
1450
- # find a primary / authoritative DNS server for the domain
1451
- if [[ -z " $AUTH_DNS_SERVER " ]]; then
1452
- # Find authorative dns server for _acme-challenge.{domain} (for CNAMES/acme-dns)
1453
- get_auth_dns " ${rr} "
1454
- if test -n " ${cname} " ; then
1434
+ # find a primary / authoritative DNS server for the domain & see if RR is a CNAME
1435
+ # DNS add drivers will always prefix the domain with _acme-challenge for the TXT record.
1436
+ # Therefore, the target of a CNAME must start with _acme-challenge.${d} (Not an RFC
1437
+ # constraint.) Note that the target of a CNAME can be ANYWHERE on the web, including
1438
+ # a different TLD or a subdomain of the domain being verified..
1439
+ get_auth_dns " ${rr} "
1440
+ if [[ -n " ${cname} " ]]; then
1441
+ if ! [[ " ${cname} " =~ ^" _acme-challenge.${d} ." .. ]]; then
1442
+ error_exit " ${d} : $rr uses a CNAME to ${cname} , which does not start with '_acme-challenge.${d} ', which is required by getssl"
1443
+ fi
1455
1444
rr=${cname}
1456
- fi
1445
+ fi
1457
1446
1458
- # If no authorative dns server found, try again for {domain}
1447
+ if [[ -z " $AUTH_DNS_SERVER " ]]; then
1448
+ # If no authoritative dns server defined and RR search failed, try again for {domain}
1459
1449
if [[ -z " $primary_ns " ]]; then
1460
1450
get_auth_dns " $d "
1461
1451
fi
@@ -1466,13 +1456,16 @@ for d in "${alldomains[@]}"; do
1466
1456
fi
1467
1457
debug set primary_ns = " $primary_ns "
1468
1458
1469
- # internal check
1470
- check_challenge_completion_dns " ${d} " " ${rr} " " ${primary_ns} " " ${auth_key} "
1459
+ add_dns_rr " ${rr/# _acme-challenge./ } " " ${auth_key} " \
1460
+ || error_exit " DNS_ADD_COMMAND failed to add _acme-challenge.${rr/# _acme-challenge./ } for domain $d "
1461
+
1462
+ # internal check for visibility of the record just added.
1463
+ check_challenge_completion_dns " ${d} " " _acme-challenge.${rr/# _acme-challenge./ } " " ${primary_ns} " " ${auth_key} "
1471
1464
1472
1465
# let Let's Encrypt check
1473
1466
check_challenge_completion " ${uri} " " ${d} " " ${keyauthorization} "
1474
1467
1475
- del_dns_rr " ${d } " " ${auth_key} "
1468
+ del_dns_rr " ${rr /# _acme-challenge. / } " " ${auth_key} "
1476
1469
else # set up the correct http token for verification
1477
1470
if [[ $API -eq 1 ]]; then
1478
1471
# get the token from the http component
0 commit comments