Commit 3fc26f61 authored by Adrien Dorsaz's avatar Adrien Dorsaz

v2: remove CheckChallengeDelay option and replace it by a TTL option in DNS section

The new option TTL is used to configure the TXT resource records installed
by acme-dns-tiny: this allows us to correctly define records according
to the DNS server policy.

It allows too to fix issues about invalid TXT record errors, caused by
the ACME server cache which hidden new TXT records to the ACME server.
parent e1f23bea
Pipeline #190 failed with stage
in 2 minutes and 55 seconds
......@@ -182,14 +182,14 @@ def get_crt(config, log=LOGGER):
keyauthorization = "{0}.{1}".format(token, thumbprint)
keydigest64 = _b64(hashlib.sha256(keyauthorization.encode("utf8")).digest())
dnsrr_domain = "_acme-challenge.{0}.".format(domain)
dnsrr_set = dns.rrset.from_text(dnsrr_domain, 300, "IN", "TXT", '"{0}"'.format(keydigest64))
dnsrr_set = dns.rrset.from_text(dnsrr_domain, config["DNS"]["TTL"], "IN", "TXT", '"{0}"'.format(keydigest64))
try:
_update_dns(dnsrr_set, "add")
except dns.exception.DNSException as dnsexception:
raise ValueError("Error updating DNS records: {0} : {1}".format(type(dnsexception).__name__, str(dnsexception)))
log.info("Waiting for {0} seconds before starting self challenge check.".format(config["acmednstiny"].getint("CheckChallengeDelay")))
time.sleep(config["acmednstiny"].getint("CheckChallengeDelay"))
log.info("Waiting for 1 TTL ({0} seconds) before starting self challenge check.".format(config["DNS"].getint("TTL")))
time.sleep(config["DNS"].getint("TTL"))
challenge_verified = False
number_check_fail = 1
while challenge_verified is False:
......@@ -206,10 +206,10 @@ def get_crt(config, log=LOGGER):
if number_check_fail >= 10:
raise ValueError("Error checking challenge, value not found: {0}".format(keydigest64))
number_check_fail = number_check_fail + 1
time.sleep(2)
time.sleep(config["DNS"].getint("TTL"))
log.info("Waiting for {0} seconds before asking ACME server to validate challenge.".format(max(10, config["acmednstiny"].getint("CheckChallengeDelay"))))
time.sleep(max(10, config["acmednstiny"].getint("CheckChallengeDelay")))
log.info("Waiting for one TTL ({0} seconds) before asking ACME server to validate challenge.".format(config["DNS"].getint("TTL")))
time.sleep(config["DNS"].getint("TTL"))
code, result, headers = _send_signed_request(challenge["url"], {"keyAuthorization": keyauthorization})
if code != 200:
raise ValueError("Error triggering challenge: {0} {1}".format(code, result))
......@@ -286,7 +286,8 @@ See example.ini file to configure correctly this script."""
config = ConfigParser()
config.read_dict({"acmednstiny": {"ACMEDirectory": "https://acme-staging-v02.api.letsencrypt.org/directory",
"CheckChallengeDelay": 3},
"DNS": {"Port": "53"}})
"DNS": {"Port": "53",
"TTL": "10"}})
config.read(args.configfile)
if args.csr :
......@@ -294,7 +295,7 @@ See example.ini file to configure correctly this script."""
if (set(["accountkeyfile", "csrfile", "acmedirectory", "checkchallengedelay"]) - set(config.options("acmednstiny"))
or set(["keyname", "keyvalue", "algorithm"]) - set(config.options("TSIGKeyring"))
or set(["zone", "host", "port"]) - set(config.options("DNS"))):
or set(["zone", "host", "port", "ttl"]) - set(config.options("DNS"))):
raise ValueError("Some required settings are missing.")
LOGGER.setLevel(args.quiet or LOGGER.level)
......
[acmednstiny]
# Required readable ACME account key
AccountKeyFile = account.key
# Required readable CSR file
# Note: if you use the "--csr" optional argument, this setting is not read and can be omitted
CSRFile = domain.csr
# Optional ACME directory url
# Default: https://acme-staging-v02.api.letsencrypt.org/directory
ACMEDirectory = https://acme-staging-v02.api.letsencrypt.org/directory
# Optional time in seconds to wait between DNS update and challenge check
# Default: 3
CheckChallengeDelay = 3
# Optional To be able to be reached by ACME provider (e.g. to warn about
# certificate expicration), you can provide some contact informations.
# Contacts setting is a list of contact URI separated by semicolon (;).
......@@ -19,6 +19,7 @@ CheckChallengeDelay = 3
# without header fields (see [RFC6068]).
# Default: none
Contacts = mailto:mail@example.com;mailto:mail2@example.org
# Optional to give hint to the ACME server about your prefered language for errors given by their server
# See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Accept-Language for more informations
# Default: en
......@@ -27,15 +28,25 @@ Language = en
[TSIGKeyring]
# Required TSIG key name
KeyName = host-example
# Required TSIG key value in base64
KeyValue = XXXXXXXXXXX==
# Required TSIG algorithm
Algorithm = hmac-sha256
[DNS]
# Required name of zone to update
Zone = dnszone
# Required name or IP of DNS server
Host = dnsserver
# Optional port to connect on DNS server (default: 53)
Port = 53
# Optional time to live (TTL) value for the added DNS entries
# If you set a value too high, ACME server could return error about invalid entries while checking the TXT resources
# So, the default value is low to increase the probability of having a working setup without needing to update it
# Default: 10 seconds
TTL = 10
after_script:
- sleep 10
jessie:
image: adt-jessie_dnspython3_1.11
before_script:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment