Can not register for example.com and *.example.com at same time with dns-01 challenge #16

Закрито
відкрито 2019-02-16 05:18:03 +00:00 користувачем Ghost · 4 коментарів
Ghost прокоментував(ла) 2019-02-16 05:18:03 +00:00

When we register with like example.com and *.example.com. acme will test all the domains parallelly, and then request certificates serially.

example.com and *.example.com using the same challenge dns name _acme-challenge.example.com, when testing domains, it will fail for competition. But we can disable testing by setting skipChallengeTest to avoid test failing temporary.

But the following step has another issue that will lead to failure.

That is the removeChallenge flow:

https://git.coolaj86.com/coolaj86/acme-v2.js/src/branch/master/node.js#L389

      if ('valid' === resp.body.status) {
        if (me.debug) { console.debug('poll: valid'); }

        try {
          if (1 === options.removeChallenge.length) {
            options.removeChallenge(auth).then(function () {}, function () {});
          } else if (2 === options.removeChallenge.length) {
            options.removeChallenge(auth, function (err) { return err; });
          } else {
            options.removeChallenge(identifier.value, ch.token, function () {});
          }
        } catch(e) {}
        return resp.body;
      }

Here we returned without waiting removing complete. When executing 2rd domain to update the same dns record, there's a great chance that the record has been deleted.

When we register with like `example.com` and `*.example.com`. acme will test all the domains parallelly, and then request certificates serially. `example.com` and `*.example.com` using the same challenge dns name `_acme-challenge.example.com`, when testing domains, it will fail for competition. But we can disable testing by setting `skipChallengeTest` to avoid test failing temporary. But the following step has another issue that will lead to failure. That is the `removeChallenge` flow: https://git.coolaj86.com/coolaj86/acme-v2.js/src/branch/master/node.js#L389 ```js if ('valid' === resp.body.status) { if (me.debug) { console.debug('poll: valid'); } try { if (1 === options.removeChallenge.length) { options.removeChallenge(auth).then(function () {}, function () {}); } else if (2 === options.removeChallenge.length) { options.removeChallenge(auth, function (err) { return err; }); } else { options.removeChallenge(identifier.value, ch.token, function () {}); } } catch(e) {} return resp.body; } ``` Here we returned without waiting removing complete. When executing 2rd domain to update the same dns record, there's a great chance that the record has been deleted.
Ghost прокоментував(ла) 2019-02-16 08:48:43 +00:00
Author

The TXT records could be multiple. So the removeChallenge sequence should not be the problem.

So we should call challenge.set concurrently for example.com and *.example.com before requesting acme server to validate?

The TXT records could be multiple. So the `removeChallenge` sequence should not be the problem. So we should call `challenge.set` concurrently for `example.com` and `*.example.com` before requesting acme server to validate?
Ghost прокоментував(ла) 2019-02-16 09:21:23 +00:00
Author

ACME server validate TXT record only once for one order?

I have validated two TXT records as acem-v2.js's sequence, but ACME server only found the first TXT records for two requests. So the second is not match.

ACME server validate TXT record only once for one order? I have validated two TXT records as acem-v2.js's sequence, but ACME server only found the first TXT records for two requests. So the second is not match.
Ghost прокоментував(ла) 2019-02-16 09:42:47 +00:00
Author

cerbot works well with this.

It seams that update all dns record of domains at the same time before submitting to ACME server in certbot.

It is relative codes below.

https://github.com/certbot/certbot/blob/master/certbot/plugins/dns_common.py#L46

    def perform(self, achalls): # pylint: disable=missing-docstring
        self._setup_credentials()

        self._attempt_cleanup = True

        responses = []
        for achall in achalls:
            domain = achall.domain
            validation_domain_name = achall.validation_domain_name(domain)
            validation = achall.validation(achall.account_key)

            self._perform(domain, validation_domain_name, validation)
            responses.append(achall.response(achall.account_key))

        # DNS updates take time to propagate and checking to see if the update has occurred is not
        # reliable (the machine this code is running on might be able to see an update before
        # the ACME server). So: we sleep for a short amount of time we believe to be long enough.
        logger.info("Waiting %d seconds for DNS changes to propagate",
                    self.conf('propagation-seconds'))
        sleep(self.conf('propagation-seconds'))

        return responses
`cerbot` works well with this. It seams that update all dns record of domains at the same time before submitting to ACME server in `certbot`. It is relative codes below. https://github.com/certbot/certbot/blob/master/certbot/plugins/dns_common.py#L46 ```python def perform(self, achalls): # pylint: disable=missing-docstring self._setup_credentials() self._attempt_cleanup = True responses = [] for achall in achalls: domain = achall.domain validation_domain_name = achall.validation_domain_name(domain) validation = achall.validation(achall.account_key) self._perform(domain, validation_domain_name, validation) responses.append(achall.response(achall.account_key)) # DNS updates take time to propagate and checking to see if the update has occurred is not # reliable (the machine this code is running on might be able to see an update before # the ACME server). So: we sleep for a short amount of time we believe to be long enough. logger.info("Waiting %d seconds for DNS changes to propagate", self.conf('propagation-seconds')) sleep(self.conf('propagation-seconds')) return responses ```
coolaj86 прокоментував(ла) 2019-04-10 07:46:59 +00:00
Власник

@taoyuan, sorry I didn't reply to this sooner. I had it on my plate to look at that.

I just spent a bunch of time going through the wildcard use case and adding a bunch of tests.

The plugin architecture is 10x simpler now and if you still need the node / javascript solution I'm confident that you'll find it functions exactly as it should now.

If you want to write a DNS plugin, here's the test harness:

And here's the fully-tested reference implementation:

I'm going to close this out, but feel free to re-open it.

Thanks for being so diligent in really digging into the problem to uncover helpful information.

@taoyuan, sorry I didn't reply to this sooner. I had it on my plate to look at that. I just spent a bunch of time going through the wildcard use case and adding a bunch of tests. The plugin architecture is 10x simpler now and if you still need the node / javascript solution I'm confident that you'll find it functions exactly as it should now. If you want to write a DNS plugin, here's the test harness: * https://git.coolaj86.com/coolaj86/greenlock-challenge-test.js And here's the fully-tested reference implementation: * https://git.coolaj86.com/coolaj86/greenlock-challenge-dns.js I'm going to close this out, but feel free to re-open it. Thanks for being so diligent in really digging into the problem to uncover helpful information.
coolaj86 закрив цю задачу 2019-04-10 07:47:02 +00:00
Підпишіться щоб приєднатися до обговорення.
Без мітки
Етап відсутній
Немає виконавця
2 учасників
Сповіщення
Дата завершення
Термін дії не дійсний або знаходиться за межами допустимого діапазону. Будь ласка використовуйте формат 'yyyy-mm-dd'.

Термін виконання не встановлений.

Залежності

No dependencies set.

Reference: coolaj86/acme.js-ARCHIVED#16
No description provided.