Улучшено логирование процесса добавления и проверки DNS записей. Добавлены рекомендации по устранению проблем при получении сертификата. Обновлены сообщения о статусе выполнения для большей информативности.
This commit is contained in:
@@ -1085,21 +1085,40 @@ class LetsEncryptManager:
|
|||||||
self.logger.error("Не удалось добавить TXT запись")
|
self.logger.error("Не удалось добавить TXT запись")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
self.logger.info("✅ TXT запись успешно добавлена")
|
self.logger.info("✅ TXT запись успешно добавлена в API reg.ru")
|
||||||
|
|
||||||
# Ждем распространения DNS
|
# Ждем распространения DNS
|
||||||
wait_time = self.config.get("dns_propagation_wait", 60)
|
wait_time = self.config.get("dns_propagation_wait", 60)
|
||||||
self.logger.info(f"Ожидание распространения DNS ({wait_time} секунд)...")
|
self.logger.info("")
|
||||||
time.sleep(wait_time)
|
self.logger.info("⏳ Ожидание распространения DNS...")
|
||||||
|
self.logger.info(f" Время ожидания: {wait_time} секунд")
|
||||||
|
self.logger.info(f" TXT запись: _acme-challenge.{base_domain}")
|
||||||
|
self.logger.info("")
|
||||||
|
|
||||||
|
# Показываем прогресс ожидания
|
||||||
|
for i in range(wait_time):
|
||||||
|
if i % 10 == 0:
|
||||||
|
elapsed_pct = int((i / wait_time) * 100)
|
||||||
|
self.logger.info(f" ⏱️ Прошло: {i}/{wait_time} сек ({elapsed_pct}%)")
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
|
self.logger.info(f" ✅ Ожидание завершено ({wait_time} секунд)")
|
||||||
|
self.logger.info("")
|
||||||
|
|
||||||
# Проверяем DNS запись (используем base_domain для проверки)
|
# Проверяем DNS запись (используем base_domain для проверки)
|
||||||
self.logger.info("Проверка распространения DNS...")
|
self.logger.info("🔍 Проверка распространения DNS через публичные серверы...")
|
||||||
if self.verify_dns_record_external(base_domain, subdomain, validation_token):
|
if self.verify_dns_record_external(base_domain, subdomain, validation_token):
|
||||||
self.logger.info("✅ DNS запись подтверждена через публичные DNS")
|
self.logger.info("✅ DNS запись подтверждена через публичные DNS серверы")
|
||||||
|
self.logger.info(" Certbot сможет пройти валидацию")
|
||||||
return True
|
return True
|
||||||
else:
|
else:
|
||||||
self.logger.warning("⚠️ DNS запись не обнаружена через публичные DNS, но продолжаем...")
|
self.logger.warning("⚠️ DNS запись НЕ обнаружена через публичные DNS, но продолжаем...")
|
||||||
self.logger.warning("Let's Encrypt может использовать свои DNS серверы")
|
self.logger.warning(" Возможные причины:")
|
||||||
|
self.logger.warning(" • DNS серверы ещё не обновились (требуется больше времени)")
|
||||||
|
self.logger.warning(" • Let's Encrypt использует свои DNS серверы")
|
||||||
|
self.logger.warning(" • API reg.ru обновляет записи с задержкой")
|
||||||
|
self.logger.warning("")
|
||||||
|
self.logger.warning(" Certbot будет продолжать попытки валидации...")
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -1146,7 +1165,10 @@ class LetsEncryptManager:
|
|||||||
attempts = self.config.get("dns_check_attempts", 10)
|
attempts = self.config.get("dns_check_attempts", 10)
|
||||||
interval = self.config.get("dns_check_interval", 10)
|
interval = self.config.get("dns_check_interval", 10)
|
||||||
|
|
||||||
self.logger.info(f"Проверка DNS записи для {full_domain}")
|
self.logger.info(f" Проверяем: {full_domain}")
|
||||||
|
self.logger.info(f" Ожидаемое значение: {expected_value[:30]}...")
|
||||||
|
self.logger.info(f" Попыток: {attempts}, интервал: {interval} сек")
|
||||||
|
self.logger.info("")
|
||||||
|
|
||||||
for attempt in range(attempts):
|
for attempt in range(attempts):
|
||||||
try:
|
try:
|
||||||
@@ -1159,16 +1181,22 @@ class LetsEncryptManager:
|
|||||||
)
|
)
|
||||||
|
|
||||||
if expected_value in result.stdout:
|
if expected_value in result.stdout:
|
||||||
self.logger.info(f"DNS запись найдена (попытка {attempt + 1})")
|
self.logger.info(f" ✅ Попытка {attempt + 1}/{attempts}: DNS запись НАЙДЕНА!")
|
||||||
|
# Показываем найденную запись
|
||||||
|
for line in result.stdout.split('\n'):
|
||||||
|
if 'text =' in line.lower() or expected_value[:20] in line:
|
||||||
|
self.logger.info(f" {line.strip()}")
|
||||||
return True
|
return True
|
||||||
|
else:
|
||||||
|
self.logger.info(f" ⏳ Попытка {attempt + 1}/{attempts}: DNS запись не найдена, ждём...")
|
||||||
|
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
self.logger.debug(f"Попытка {attempt + 1}: DNS запись не найдена - {e}")
|
self.logger.info(f" ⚠️ Попытка {attempt + 1}/{attempts}: Ошибка nslookup - {e}")
|
||||||
|
|
||||||
if attempt < attempts - 1:
|
if attempt < attempts - 1:
|
||||||
time.sleep(interval)
|
time.sleep(interval)
|
||||||
|
|
||||||
self.logger.warning("DNS запись не найдена после всех попыток")
|
self.logger.warning(f" ❌ DNS запись не найдена после {attempts} попыток")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def verify_dns_record(self, subdomain: str, expected_value: str) -> bool:
|
def verify_dns_record(self, subdomain: str, expected_value: str) -> bool:
|
||||||
@@ -1303,13 +1331,75 @@ class LetsEncryptManager:
|
|||||||
check=True
|
check=True
|
||||||
)
|
)
|
||||||
|
|
||||||
self.logger.info("Сертификат успешно получен!")
|
self.logger.info("=" * 80)
|
||||||
self.logger.debug(result.stdout)
|
self.logger.info("✅ СЕРТИФИКАТ УСПЕШНО ПОЛУЧЕН!")
|
||||||
|
self.logger.info("=" * 80)
|
||||||
|
|
||||||
|
# Выводим stdout certbot (может содержать полезную информацию)
|
||||||
|
if result.stdout:
|
||||||
|
self.logger.info("Вывод Certbot:")
|
||||||
|
for line in result.stdout.split('\n'):
|
||||||
|
if line.strip():
|
||||||
|
self.logger.info(f" {line}")
|
||||||
|
|
||||||
|
# Информация о местоположении сертификата
|
||||||
|
if staging:
|
||||||
|
self.logger.info("")
|
||||||
|
self.logger.info("⚠️ Это STAGING сертификат - не используйте на production!")
|
||||||
|
self.logger.info(" Для получения production сертификата используйте: letsencrypt-regru --obtain")
|
||||||
|
|
||||||
return True
|
return True
|
||||||
|
|
||||||
except subprocess.CalledProcessError as e:
|
except subprocess.CalledProcessError as e:
|
||||||
self.logger.error(f"Ошибка при получении сертификата: {e}")
|
self.logger.error("=" * 80)
|
||||||
self.logger.error(e.stderr)
|
self.logger.error("❌ ОШИБКА ПРИ ПОЛУЧЕНИИ СЕРТИФИКАТА")
|
||||||
|
self.logger.error("=" * 80)
|
||||||
|
self.logger.error(f"Код возврата: {e.returncode}")
|
||||||
|
|
||||||
|
# Выводим stderr (основные ошибки)
|
||||||
|
if e.stderr:
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("Сообщения об ошибках:")
|
||||||
|
for line in e.stderr.split('\n'):
|
||||||
|
if line.strip():
|
||||||
|
self.logger.error(f" {line}")
|
||||||
|
|
||||||
|
# Выводим stdout (может содержать дополнительную информацию)
|
||||||
|
if e.stdout:
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("Дополнительная информация:")
|
||||||
|
for line in e.stdout.split('\n'):
|
||||||
|
if line.strip():
|
||||||
|
self.logger.error(f" {line}")
|
||||||
|
|
||||||
|
# Рекомендации по устранению проблем
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("=" * 80)
|
||||||
|
self.logger.error("РЕКОМЕНДАЦИИ ПО УСТРАНЕНИЮ ПРОБЛЕМ:")
|
||||||
|
self.logger.error("=" * 80)
|
||||||
|
self.logger.error("1. Проверьте детальный лог Certbot:")
|
||||||
|
self.logger.error(" tail -100 /var/log/letsencrypt/letsencrypt.log")
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("2. Проверьте логи скрипта:")
|
||||||
|
self.logger.error(" tail -100 /var/log/letsencrypt-regru/letsencrypt_regru.log")
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("3. Убедитесь, что DNS записи создаются:")
|
||||||
|
self.logger.error(" letsencrypt-regru --test-dns")
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("4. Проверьте доступ к API reg.ru:")
|
||||||
|
self.logger.error(" letsencrypt-regru --test-api")
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("5. Запустите с подробным выводом:")
|
||||||
|
self.logger.error(" letsencrypt-regru --staging -v")
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("6. Убедитесь что ваш IP в белом списке API reg.ru:")
|
||||||
|
self.logger.error(" https://www.reg.ru/user/account/#/settings/api/")
|
||||||
|
self.logger.error("")
|
||||||
|
self.logger.error("7. Проверьте DNS записи вручную:")
|
||||||
|
self.logger.error(" nslookup -type=TXT _acme-challenge.{domain}")
|
||||||
|
self.logger.error(" dig TXT _acme-challenge.{domain}")
|
||||||
|
self.logger.error("=" * 80)
|
||||||
|
|
||||||
return False
|
return False
|
||||||
finally:
|
finally:
|
||||||
# Удаляем временные wrapper скрипты
|
# Удаляем временные wrapper скрипты
|
||||||
@@ -1499,9 +1589,9 @@ def main():
|
|||||||
parser = argparse.ArgumentParser(
|
parser = argparse.ArgumentParser(
|
||||||
description="Автоматическое управление SSL сертификатами Let's Encrypt через API reg.ru",
|
description="Автоматическое управление SSL сертификатами Let's Encrypt через API reg.ru",
|
||||||
epilog="""
|
epilog="""
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
|
ПРИМЕРЫ ИСПОЛЬЗОВАНИЯ
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
|
|
||||||
Основные команды:
|
Основные команды:
|
||||||
letsencrypt-regru --check Проверить срок действия
|
letsencrypt-regru --check Проверить срок действия
|
||||||
@@ -1519,31 +1609,31 @@ def main():
|
|||||||
letsencrypt-regru --obtain -v Подробный вывод
|
letsencrypt-regru --obtain -v Подробный вывод
|
||||||
letsencrypt-regru --force-cleanup Очистить lock-файлы Certbot
|
letsencrypt-regru --force-cleanup Очистить lock-файлы Certbot
|
||||||
|
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
РЕКОМЕНДУЕМЫЙ WORKFLOW
|
РЕКОМЕНДУЕМЫЙ WORKFLOW
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
|
|
||||||
1. Проверка настройки:
|
1. Проверка настройки:
|
||||||
letsencrypt-regru --test-api ✓ API доступен?
|
letsencrypt-regru --test-api [+] API доступен?
|
||||||
letsencrypt-regru --test-dns ✓ DNS работает?
|
letsencrypt-regru --test-dns [+] DNS работает?
|
||||||
|
|
||||||
2. Тестирование (неограниченно):
|
2. Тестирование (неограниченно):
|
||||||
letsencrypt-regru --staging ✓ Полный процесс SSL
|
letsencrypt-regru --staging [+] Полный процесс SSL
|
||||||
|
|
||||||
3. Production:
|
3. Production:
|
||||||
letsencrypt-regru --obtain ✓ Боевой сертификат
|
letsencrypt-regru --obtain [+] Боевой сертификат
|
||||||
|
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
СРАВНЕНИЕ РЕЖИМОВ ТЕСТИРОВАНИЯ
|
СРАВНЕНИЕ РЕЖИМОВ ТЕСТИРОВАНИЯ
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
|
|
||||||
--staging Полный Let's Encrypt, БЕЗ лимитов, ~2-3 мин, тестирует всё
|
--staging Полный Let's Encrypt, БЕЗ лимитов, ~2-3 мин, тестирует все
|
||||||
--test-cert Самоподпись, мгновенно, БЕЗ интернета, для локальной разработки
|
--test-cert Самоподпись, мгновенно, БЕЗ интернета, для локальной разработки
|
||||||
--test-dns Только DNS, ~1-2 мин, не создает сертификат
|
--test-dns Только DNS, ~1-2 мин, не создает сертификат
|
||||||
|
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
|
ДОПОЛНИТЕЛЬНАЯ ИНФОРМАЦИЯ
|
||||||
════════════════════════════════════════════════════════════════════════════════
|
================================================================================
|
||||||
|
|
||||||
Документация: https://github.com/DFofanov/configure_nginx_manager
|
Документация: https://github.com/DFofanov/configure_nginx_manager
|
||||||
Поддержка: https://github.com/DFofanov/configure_nginx_manager/issues
|
Поддержка: https://github.com/DFofanov/configure_nginx_manager/issues
|
||||||
@@ -2006,14 +2096,30 @@ def main():
|
|||||||
logger.info("СКРИПТ УПРАВЛЕНИЯ SSL СЕРТИФИКАТАМИ LET'S ENCRYPT")
|
logger.info("СКРИПТ УПРАВЛЕНИЯ SSL СЕРТИФИКАТАМИ LET'S ENCRYPT")
|
||||||
logger.info("=" * 60)
|
logger.info("=" * 60)
|
||||||
|
|
||||||
|
# Получаем текущий IP
|
||||||
|
try:
|
||||||
|
ip_response = requests.get("https://api.ipify.org", timeout=5)
|
||||||
|
current_ip = ip_response.text
|
||||||
|
logger.info(f"Текущий IP адрес: {current_ip}")
|
||||||
|
except:
|
||||||
|
logger.warning("Не удалось определить IP адрес")
|
||||||
|
|
||||||
# Проверка доступности API reg.ru (кроме режимов только проверки)
|
# Проверка доступности API reg.ru (кроме режимов только проверки)
|
||||||
if not args.check:
|
if not args.check:
|
||||||
|
logger.info("Проверка доступности API reg.ru...")
|
||||||
if not api.test_api_access():
|
if not api.test_api_access():
|
||||||
logger.error("=" * 80)
|
logger.error("=" * 80)
|
||||||
logger.error("❌ КРИТИЧЕСКАЯ ОШИБКА: API reg.ru недоступен")
|
logger.error("❌ КРИТИЧЕСКАЯ ОШИБКА: API reg.ru недоступен")
|
||||||
logger.error("=" * 80)
|
logger.error("=" * 80)
|
||||||
logger.error("Скрипт не может продолжить работу без доступа к API")
|
logger.error("Скрипт не может продолжить работу без доступа к API")
|
||||||
logger.error("Исправьте проблему и запустите скрипт заново")
|
logger.error("")
|
||||||
|
logger.error("Возможные причины:")
|
||||||
|
logger.error(" 1. Неверные учётные данные reg.ru")
|
||||||
|
logger.error(" 2. IP адрес не добавлен в белый список API")
|
||||||
|
logger.error(" 3. Проблемы с интернет-соединением")
|
||||||
|
logger.error("")
|
||||||
|
logger.error("Проверьте настройки и запустите скрипт заново")
|
||||||
|
logger.error("Для диагностики используйте: letsencrypt-regru --test-api -v")
|
||||||
return 1
|
return 1
|
||||||
logger.info("")
|
logger.info("")
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user