diff --git a/letsencrypt_regru_api.py b/letsencrypt_regru_api.py index 3be1ee4..625265e 100644 --- a/letsencrypt_regru_api.py +++ b/letsencrypt_regru_api.py @@ -1569,20 +1569,28 @@ class LetsEncryptManager: self.logger.warning(" Не удалось определить authoritative NS, используем публичные DNS") public_resolvers = ["1.1.1.1", "8.8.8.8", "9.9.9.9"] + found_on_auth = False for attempt in range(attempts): try: # 1) Проверка через authoritative NS (самый точный источник) - for ns in auth_ns: - ns_output = self._query_txt_nslookup(full_domain, ns) - if expected_value in ns_output: - self.logger.info(f" ✅ Попытка {attempt + 1}/{attempts}: TXT найден на authoritative NS {ns}") - for line in ns_output.split('\n'): - if 'text =' in line.lower() or expected_value[:20] in line: - self.logger.info(f" {line.strip()}") - return True + if not found_on_auth: + for ns in auth_ns: + ns_output = self._query_txt_nslookup(full_domain, ns) + if expected_value in ns_output: + self.logger.info(f" ✅ Попытка {attempt + 1}/{attempts}: TXT найден на authoritative NS {ns}") + for line in ns_output.split('\n'): + if 'text =' in line.lower() or expected_value[:20] in line: + self.logger.info(f" {line.strip()}") + found_on_auth = True + break # 2) Проверка через публичные резолверы + # ВАЖНО: Let's Encrypt валидирует через рекурсивные резолверы, а не + # authoritative NS напрямую. Поэтому ОБЯЗАТЕЛЬНО ждём, пока запись + # станет видна через публичные DNS (8.8.8.8 и т.д.), иначе при + # wildcard + base domain сертификатах кэш рекурсивных резолверов + # может содержать старую версию без нового токена. found_public = False for resolver in public_resolvers: res_output = self._query_txt_nslookup(full_domain, resolver) @@ -1597,16 +1605,20 @@ class LetsEncryptManager: if found_public: return True - # 3) Fallback на системный resolver - default_output = self._query_txt_nslookup(full_domain) - if expected_value in default_output: - self.logger.info(f" ✅ Попытка {attempt + 1}/{attempts}: TXT найден через системный DNS") - for line in default_output.split('\n'): - if 'text =' in line.lower() or expected_value[:20] in line: - self.logger.info(f" {line.strip()}") - return True + # 3) Fallback: если нет authoritative NS, проверяем системный resolver + if not auth_ns: + default_output = self._query_txt_nslookup(full_domain) + if expected_value in default_output: + self.logger.info(f" ✅ Попытка {attempt + 1}/{attempts}: TXT найден через системный DNS") + for line in default_output.split('\n'): + if 'text =' in line.lower() or expected_value[:20] in line: + self.logger.info(f" {line.strip()}") + return True - self.logger.info(f" ⏳ Попытка {attempt + 1}/{attempts}: DNS запись не найдена, ждём...") + if found_on_auth: + self.logger.info(f" ⏳ Попытка {attempt + 1}/{attempts}: TXT есть на authoritative NS, ждём распространения на публичные DNS...") + else: + self.logger.info(f" ⏳ Попытка {attempt + 1}/{attempts}: DNS запись не найдена, ждём...") except Exception as e: self.logger.info(f" ⚠️ Попытка {attempt + 1}/{attempts}: Ошибка nslookup - {e}")