32 lines
10 KiB
Markdown
32 lines
10 KiB
Markdown
# Реальная приёмка ACME — 2026-10-14
|
||
|
||
Принят блок 12.5.250: `mmt250-c22a9715.pngs.top`, CHR `104.165.244.7`, production Let's Encrypt DNS-01 / Cloudflare. Пользователь разрешил только собственные поддомены `mmt*` и подтвердил назначение сертификата сервисам с последующей очисткой. Звёздочка обозначает разрешённый префикс; в заявке использовалось точное обычное имя.
|
||
|
||
Временные credentials только в ignored private fixture; ключи/почта/account ID в Git не публикуются. Перед запуском проверить token/zone/account и отсутствие записей на точном FQDN и `_acme-challenge.FQDN`. Снять приватный native export, сертификаты/файлы и исходные `www-ssl`/`api-ssl`; сохранить исходную строку `acme_settings`, включая ключ ACME-аккаунта и дату. После окончания восстановить её полностью.
|
||
|
||
Текущий issuer создаёт TXT, выполняет ACME, синхронизирует A-запись с IPv4 сервера, импортирует leaf/key/chain и назначает сертификат **обоим** `www-ssl`/`api-ssl`, включая их. Переключатели trust-store не отключают назначение. Поэтому исходные параметры сервисов обязательны для отката. HTTP REST80 используется для управления во время проверки.
|
||
|
||
Ручной helper: `backend/scripts/acceptance/acme-live-issue.mjs`, private fixture через `MMAPP_ACME_FIXTURE` (по умолчанию ignored `tmp/acme250-private.json`). Требуется отдельно разрешённый тест, baseline, Portal fixture и SSH-туннель. Helper не заменяет native/DNS очистку; при уже сохранённом jobId новый выпуск блокируется. Неподтверждённый запрос сначала проверять по тому же ID, не отправлять новую задачу. Не запускать этот helper повторно без свежей подготовки: временные credentials после блока удалены.
|
||
|
||
Проверено: реальный Portal/UI, один POST issue, terminal done; trusted TLS/SNI/SAN, DNS A → `104.165.244.7`, REST HTTPS200 с обычной проверкой сертификата; RouterOS private key и назначение обоим сервисам. После теста сервисы восстановлены, собственные leaf/chain/files/job удалены, первоначальные коллекции/экспорт/settings совпали. Приложение удалило TXT; собственная A-запись удалена по проверенным имени/типу/content/ID. Даты PostgreSQL сравниваются после JSON-нормализации; неверное сравнение Date со строкой не должно повторять очистку.
|
||
|
||
Выданный публичный сертификат CA не объявляется отозванным: экземпляры и ключевые файлы на CHR удалены, DNS очищен; запись о выпуске сохраняется у CA. Это не тест автоматического renewal, CA revocation или нескольких backend.
|
||
|
||
Протоколы: [UI](../docs/ux-ui/acceptance/acme250-live-ui.json), [TLS](../docs/ux-ui/acceptance/acme250-tls.json), [DNS](../docs/ux-ui/acceptance/acme250-cloudflare.json), [native/cleanup](../docs/ux-ui/acceptance/acme250-native.json).
|
||
|
||
## Подготовка повторной выдачи / renewal — блок253 (2026-10-14)
|
||
|
||
Подготовлен конкретный домен `mmt253-8e62a941.pngs.top`, certName `mmt253-8e62a941`, CHR `104.165.244.7` (server2). Это обычное имя без wildcard. Этот раздел описывает следующий тест; выдача и продление253 ещё не запускались. Первичная выдача250 не доказывает замену сертификата при повторном импорте. HTTP ACK и terminal job сами по себе также не доказывают, какой leaf обслуживает TLS.
|
||
|
||
1. Перед изменениями снять свежий приватный baseline: native export, certificates/files/services; SQL ACME и renewal settings, список managed targets/jobs; scheduler state. Подтвердить отсутствие любых других managed targets/active jobs и DNS записей на обоих точных именах. Если они появились — остановиться до мутации. Не использовать удалённый baseline250.
|
||
2. Временно остановить автоматический certificates_renew через его настройки и дождаться отсутствия текущего запуска. Сохранить исходные настройки целиком. Не запускать несколько экземпляров collector. Настроить тестовый Cloudflare token и выполнить первый UI выпуск с новым requestId. Публично сохранить только terminal job/protocol и native metadata без секретов.
|
||
3. По аутентифицированному RouterOS чтению выбрать ровно один собственный leaf с exact name/CN, private-key=true и отпечатком; снять served TLS с SNI/обычной проверкой доверия. Если native fingerprint не SHA-256, сначала экспортировать только публичный сертификат и вычислить SHA-256 через X509Certificate; не интерпретировать другой алгоритм как SHA-256. Изолированная сводка для helper содержит только fqdn/certName/nativePrivateKey/nativeFingerprint256.
|
||
4. Read-only helper `node backend/scripts/acceptance/acme-renew-tls.mjs sample native-summary.json before.json` подключается только к104.165.244.7:443 с точным SNI, rejectUnauthorized=true и15s timeout. Требует совпадения native и TLS SHA-256, private key и hostname. Существующий output не перезаписывается. Этот helper ничего не выпускает и не меняет RouterOS/DNS.
|
||
5. Для реального collector renewal подтвердить канонический срок/статус leaf по state. Не менять даты на CHR и не обходить unknown guard252. Если RouterOS дата не распознаётся, записать препятствие и не запускать повторную выдачу. Для известного срока при выключенном renewal подготовить порог90 дней и интервал не менее3600s, подтвердить единственный собственный target. Затем один PUT enabled=true запускает certificates_renew через refreshScheduler немедленно: отдельный run-now НЕ отправлять. После terminal сразу выключить renewal до следующего интервала. Сохранить ID созданной scheduler-задачи; при неизвестном ACK проверять тот же ID, новый run не отправлять. Проверить source=scheduler, matching context, terminal done и snapshot renewed1/errors0.
|
||
6. Снять after.json тем же helper и сравнить `node backend/scripts/acceptance/acme-renew-tls.mjs compare samples.json comparison.json`, где samples.json содержит before/after. Новый SHA-256 должен отличаться от первого, native должен совпасть с served TLS. Не требовать увеличения expiry на целый день: обе выдачи могут быть в один день. Проверить оба назначения www-ssl/api-ssl и HTTPS REST с обычным доверием. Если job done, а TLS leaf прежний, это ошибка приёмки; не удалять первый leaf ради получения ложного успеха.
|
||
7. Независимо от результата остановить own renewal, вернуть исходные SSL сервисы, удалить только собственные exact cert IDs/fingerprints/PEM файлы/job IDs; вернуть ACME/renew settings целиком. Удалять только DNS записи с проверенными exact name/type/content/ID, не чужие записи. Подтвердить исходные коллекции, normalized export, settings и0 own DNS; удалить private baseline/token. Контрольный194.226.121.150 не менять, пароли не менять, перезагрузки не нужны.
|
||
|
||
Для этих двух выдач и повторного назначения SSL необходимо согласие на конкретный сценарий. Разрешение250 относилось к уже завершённому тесту. До согласия выполняются только подготовка/чтение. Полная регрессия и Docker build для изменения лишь ручного acceptance helper не нужны; comparator проверяется отдельно. CA revocation и multi-instance здесь не принимаются.
|
||
|
||
Нормативная справка для native полей/import: [MikroTik Certificates](https://help.mikrotik.com/docs/spaces/ROS/pages/2555969/Certificates). Документация не гарантирует успех повторного импорта в текущем приложении; именно это предстоит измерить.
|