Сайт падает молча: как сертификат и DNS убивают выручку, пока никто не смотрит
Сертификат истекает в 3 часа ночи в субботу. Мониторинг доступности зелёный: сервер отвечает, просто браузер клиента показывает страшный экран. Собираем проверку, которая ловит это заранее.
Сертификат истёк в субботу, в 03:12. Автопродление сломалось ещё в мае — тогда поменяли веб-сервер, и хук перезапуска перестал находить конфиг. Никто не заметил: сертификат был выписан на 90 дней, и до субботы всё работало.
Мониторинг в это время показывал зелёное. Он ходил на /health и получал
честный HTTP 200 — сервер-то жив, приложение отвечает, база на месте. Просто у каждого,
кто в эти часы открывал сайт, браузер рисовал красный экран с надписью про небезопасное
соединение. Ни один из них не написал в поддержку — люди в такой ситуации просто уходят.
Разбор в понедельник занял четыре минуты: открыли сайт в браузере — и всё стало ясно. Обиднее всего было не то, что чинили долго, а то, что о поломке узнали от коммерческого директора, который в воскресенье вечером посмотрел на выручку выходных.
Вторая история из того же класса — тише и дороже. Домен переносили к новому регистратору, аккуратно перенесли A и AAAA, проверили, что сайт открывается, и закрыли задачу. Через три недели выяснилось, что вместе со старой зоной остались MX и TXT: почта с домена уходила, но никуда не приходила, а письма от сервиса рассылки провайдеры складывали в спам, потому что SPF в новой зоне не завезли.
Где мониторинг слепнет
Типовая проверка доступности — это запрос по HTTP и ожидание кода 200. Её пишут один раз и потом годами не трогают. У неё есть два слепых пятна, и именно в них живут самые дорогие отказы: те, при которых с точки зрения сервера всё в порядке.
Сертификат истёк, а сервер отвечает
- Что происходит
- Проверка ходит на внутренний адрес или по HTTP, а если по HTTPS — то с выключенной валидацией сертификата, иначе «мониторинг ложно срабатывает». Ответ 200 приходит и в тот момент, когда браузер клиента уже показывает предупреждение на весь экран.
- Во что обходится
- Конверсия на публичной странице падает почти до нуля, а платные клики продолжают откручиваться: рекламная система про ваш сертификат ничего не знает.
- Чем закрывается
- Проверка SSL-сертификата возвращает daysRemaining и список ошибок. За 30 дней до истечения это задача в бэклоге, за 3 дня — срочная задача, после истечения — инцидент.
Зона переехала, половина записей осталась
- Что происходит
- При переносе зоны копируют то, что видно глазами: A, AAAA, иногда CNAME. MX, TXT со SPF и запись _dmarc остаются у старого провайдера — и молчат, потому что сайт-то открывается.
- Во что обходится
- Письма домена перестают доходить, а узнаёте вы об этом от клиента, который «не получил счёт». Репутация домена у почтовых провайдеров восстанавливается неделями.
- Чем закрывается
- Проверка DNS-записей одним ответом отдаёт A, AAAA, MX, TXT, CNAME и NS. Эталон записей держите в репозитории и сравнивайте с тем, что реально отвечает резолвер.
Проверка есть, но она не запускалась
- Что происходит
- Cron-строку взяли из чужого гайда. «0 0 */5 * *» выглядит как «каждые пять дней», а на деле срабатывает 1, 6, 11, 16, 21, 26 числа — и в конце месяца между запусками проходит семь дней, а не пять.
- Во что обходится
- Сторож, который срабатывает не тогда, когда вы думаете, хуже отсутствия сторожа: на него полагаются. Проверить это в бою можно только пропустив событие.
- Чем закрывается
- Разбор Cron-выражений возвращает нормализованное выражение и список ближайших запусков в нужном часовом поясе. Ошибка в расписании видна за секунду и до выкатки.
Про выключенную валидацию TLS в проверках стоит сказать отдельно, потому что это не разгильдяйство, а логичный шаг. Мониторинг обычно ходит на внутренний адрес или прямо в контейнер, где сертификата нет вовсе или он самоподписанный. Включённая валидация там начинает орать постоянно, её выключают — и вместе с ложными срабатываниями теряют настоящее. Правильный ответ не «включить обратно», а «завести вторую проверку, которая смотрит на публичный адрес глазами клиента».
Отдельный сорт этой же беды — несовпадение имени. Завели поддомен
api.example.com, направили его на тот же сервер и забыли перевыпустить
сертификат: в нём есть example.com и www.example.com, а нового
имени нет. Сервер отвечает, приложение отдаёт JSON, мобильное приложение падает
с ошибкой TLS. В ответе проверки это видно сразу: список
subjectAlternativeNames и строка про name mismatch в errors.
Сколько стоит тишина
Считать будем на магазине с выручкой 1,2 млн ₽ в месяц. Это примерно 40 000 ₽ в сутки. Допущение назову вслух: выручка по часам распределена неравномерно, ночью заказов почти нет, и растягивать сутки в ровные 1 700 ₽ в час было бы враньём в свою пользу. Возьмём консервативно: 70% выручки приходится на десять дневных часов, то есть один дневной час стоит около 2 800 ₽.
Сертификат истёк ночью в субботу. Первый клиент упёрся в красный экран около десяти утра, а починили в 16:40 — потому что дежурный сначала полчаса искал, что не так с приложением. Шесть дневных часов простоя — это около 17 000 ₽ невыкупленных корзин. Плюс контекстная реклама, которая эти шесть часов исправно вела людей на страницу с предупреждением.
История с DNS считается хуже, и поэтому её обычно не считают вовсе. Прямых потерь в день поломки нет: сайт работает, заказы идут. Платите вы потом. Пока SPF отсутствовал, часть писем домена уходила в спам — а почтовые провайдеры запоминают такое поведение не на один день. Восстановление репутации домена занимает недели, и всё это время письма о статусе заказа не видят даже те клиенты, которые их ждут и ищут.
А теперь вторая колонка: сколько стоило бы узнать заранее. Проверка сертификата по трём хостам раз в сутки — это 90 проверок в месяц. Сверка DNS — ещё 30. Цены считайте на странице тарифов, но порядок такой, что сумма за месяц не дотягивает до стоимости одного потерянного заказа. Отдельного договора и абонентской платы тут нет: платите за сделанные запросы, а один ключ работает и для сертификата, и для DNS, и для остальных сервисов.
| Событие | Что видит проверка доступности | Что видит проверка сертификата и DNS | Запас времени |
|---|---|---|---|
| Сертификат истекает через 2 недели | HTTP 200, всё в порядке | daysRemaining: 14 |
14 дней |
| Сертификат истёк | HTTP 200 (валидация TLS обычно выключена) | isValid: false, в errors — «Certificate has expired» |
0, но узнаёте за минуты, а не за часы |
| Сертификат выписан на другое имя | HTTP 200 | errors: «Certificate name mismatch for host …» |
сразу |
| A-запись подменили или потеряли | 200 — резолвер мониторинга ещё держит старый ответ в кэше | значение A не совпадает с эталоном | минуты |
| SPF пропал при переносе зоны | ничего: сайт открывается | в группе TXT нет записи v=spf1 … |
до первой рассылки |
Как собрать проверку за вечер
Порядок ровно такой, и первый шаг — не про код.
Шаг первый: заведите эталон. Файл в репозитории рядом с инфраструктурным кодом:
список хостов с сертификатами, ожидаемый издатель для каждого и ожидаемые DNS-записи —
A, AAAA, MX, TXT со SPF, отдельно запись _dmarc. Без эталона сравнивать
не с чем: скрипт сможет сказать «MX-записи такие-то», но не сможет сказать, что
они не те. Эталон меняется через тот же pull request, что и всё остальное, — значит,
у любого расхождения есть автор и дата.
Шаг второй: раз в сутки проверяйте сертификаты. Эндпоинт
/api/certificate/batch принимает до 10 хостов за запрос и отдаёт по каждому
карточку: isValid, daysRemaining, expirationDate,
issuer, subject, subjectAlternativeNames,
версию TLS, размер ключа, цепочку и список ошибок. Одиночный хост —
/api/certificate?host=…, а если у вас на руках полный URL из браузера,
подойдёт /api/certificate/url?url=…: хост и порт он разберёт сам.
Шаг третий: сверяйте DNS. /api/dns/lookup?domain=… возвращает записи,
сгруппированные по типам — A, AAAA, MX, TXT, CNAME, NS, — с TTL и приоритетом для MX.
DMARC живёт не на самом домене, а на поддомене _dmarc.example.com, поэтому
для него нужен отдельный запрос: смотреть надо в его TXT. Резолвер по умолчанию —
Cloudflare; параметр resolver принимает публичный IP любого другого,
а значение system заставит сервис спросить системный DNS.
Когда домен переезжает, полезен /api/dns/propagation: он опрашивает
несколько резолверов сразу и показывает, кто из них уже видит новые записи, а кто
ещё отдаёт старые. По умолчанию их четыре — Cloudflare, Google, OpenDNS, Quad9;
своих можно передать до восьми.
Шаг четвёртый: пороги. Одно «сертификат истекает» бесполезно: если писать в чат каждый день начиная с 60 дней, к 30-му дню на это перестанут смотреть. Пороги должны повышать голос по мере приближения даты.
| Осталось дней | Что делает скрипт | Почему так |
|---|---|---|
| 30 | Заводит задачу в бэклог, молча | Автоматика продления обычно обновляет сертификат, когда остаётся меньше 30 дней. Если порог перешагнули — просто ждём, это нормальный день из жизни домена. |
| 20 | Первое сообщение в рабочий чат | Автопродление должно было отработать и не отработало. Это уже сигнал, что сломан хук или права на файлы, а не что «время пока есть». |
| 14 | Напоминание в чат ежедневно, задача с исполнителем | Двух недель хватает на ручное продление даже с платным УЦ, где нужна проверка организации. |
| 7 | Эскалация: чат плюс письмо владельцу сервиса | Неделя — это последний срок, когда отпуск дежурного ещё не превращается в аварию. |
| 3 | Пейджер, звонок дежурному | Три дня — это выходные плюс понедельник. Дальше сертификат истечёт в тот момент, когда никто не смотрит. |
0 или isValid: false |
Инцидент | Клиенты уже видят предупреждение браузера. |
Шаг пятый: расписание. Проверка сертификатов раз в сутки — этого достаточно:
сертификат не истекает внезапно. DNS лучше сверять чаще, раз в час: подмена или потеря
записи происходит мгновенно. Строку для планировщика прогоните через
/api/cron/evaluate до того, как она попадёт в прод: сервис вернёт
нормализованное выражение, разбор по полям и список ближайших запусков в вашем
часовом поясе. Если написали не то, что имели в виду, — увидите это по датам.
Жить этот сторож должен не на том сервере, за которым он следит. Иначе он утонет вместе с ним и в самый нужный момент промолчит. Подойдёт что угодно: соседняя виртуалка, рабочая машина админа с включённым питанием, задача в CI по расписанию. Тридцать строк скрипта, переменная окружения с ключом и одна строка в crontab.
Код: сторож на два запроса
Все примеры работают с публичным демо-ключом ak_sandbox_demo_mockdata_v1:
скопируйте команду и получите ответ, не заводя аккаунт. С этим ключом API отдаёт моки —
правдоподобные, но сгенерированные данные, одинаковые от запроса к запросу. На них
удобно отладить разбор ответа и написать тесты; настоящий сертификат вашего домена
приходит только с личным ключом.
curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
"https://atlorium.com/api/certificate/batch?hosts=example.com,shop.example.com,api.example.com"
import os
import requests
API = "https://atlorium.com/api"
HEADERS = {"Authorization": "Bearer " + os.environ["ATLORIUM_KEY"]}
HOSTS = ["example.com", "shop.example.com", "api.example.com"]
EXPECTED_ISSUER = "Let's Encrypt"
# Пороги из таблицы выше: от самого срочного к самому спокойному.
THRESHOLDS = [(3, "PAGE"), (7, "ESCALATE"), (14, "DAILY"), (20, "CHAT"), (30, "BACKLOG")]
def level(days_remaining):
for limit, name in THRESHOLDS:
if days_remaining <= limit:
return name
return None
response = requests.get(
API + "/certificate/batch",
params={"hosts": ",".join(HOSTS)},
headers=HEADERS,
timeout=30,
)
response.raise_for_status()
for cert in response.json():
host = cert["host"]
# isValid = false — это уже инцидент: имя не то, цепочка не строится или срок вышел.
if not cert["isValid"]:
print("CRITICAL " + host + ": " + "; ".join(cert["errors"]))
continue
# Издатель сменился сам собой — повод посмотреть руками, а не радоваться.
if EXPECTED_ISSUER not in cert["issuer"]:
print("WARN " + host + ": издатель " + cert["issuer"] + ", ожидали " + EXPECTED_ISSUER)
alert = level(cert["daysRemaining"])
if alert:
print(alert + " " + host + ": осталось " + str(cert["daysRemaining"]) + " дн.")
using System.Net.Http.Json;
var http = new HttpClient();
http.DefaultRequestHeaders.Authorization =
new("Bearer", Environment.GetEnvironmentVariable("ATLORIUM_KEY"));
var hosts = "example.com,shop.example.com,api.example.com";
var certs = await http.GetFromJsonAsync<List<CertificateData>>(
$"https://atlorium.com/api/certificate/batch?hosts={hosts}");
foreach (var cert in certs!)
{
if (!cert.IsValid)
Console.WriteLine($"CRITICAL {cert.Host}: {string.Join("; ", cert.Errors)}");
else if (cert.DaysRemaining <= 14)
Console.WriteLine($"WARN {cert.Host}: осталось {cert.DaysRemaining} дн.");
}
// Поля берём ровно те, что отдаёт API.
record CertificateData(
string Host, bool IsValid, int DaysRemaining,
string Issuer, string Subject, List<string> Errors);
[
{
"host": "example.com",
"port": 443,
"isValid": true,
"daysRemaining": 47,
"validFrom": "2026-05-28T09:14:00",
"expirationDate": "2026-08-30T09:14:00",
"issuer": "CN=R3, O=Let's Encrypt, C=US",
"subject": "CN=example.com",
"subjectAlternativeNames": ["example.com", "www.example.com"],
"tlsVersion": "Tls13",
"signatureAlgorithm": "sha256RSA",
"keySize": 2048,
"isSelfSigned": false,
"certificateChain": [
{
"subject": "CN=example.com",
"issuer": "CN=R3, O=Let's Encrypt",
"validTo": "2026-08-30T09:14:00",
"isValid": true,
"errors": []
}
],
"errors": [],
"checkedAt": "2026-07-14T03:00:12Z"
}
]
Тот же вызов на шести языках (Python, TypeScript, Go, Java, C#, PHP) — в репозитории ssl-certificate-check-api-client. Примеры запускаются сразу: ключ в них уже стоит демонстрационный.
Разбирать ответ целиком не нужно — для сторожа хватает четырёх полей. Вот что с ними делать.
| Что в ответе | Что это значит | Решение |
|---|---|---|
isValid: true, daysRemaining больше порога |
Всё в порядке | Молчать. Сторож, который говорит каждый день, перестаёт быть сторожем. |
errors: «Certificate has expired» |
Срок вышел, клиенты видят предупреждение | Инцидент. Продлевать немедленно. |
errors: «Certificate name mismatch for host …» |
Сертификат выписан на другое имя: обычно завели поддомен и забыли добавить его в SAN | Смотреть subjectAlternativeNames: нужного имени там нет. Перевыпустить. |
errors: «SSL handshake failed: …» |
Рукопожатие не состоялось: сервер не отдал TLS на этом порту или не сошлись протоколы | Проверить, что на порту действительно HTTPS, и заглянуть в tlsVersion. |
isSelfSigned: true на публичном хосте |
Самоподписанный сертификат — в проде такого быть не должно | Скорее всего, приложение отдаёт дефолтный сертификат сервера: конфиг не подхватился. |
issuer не тот, что в эталоне |
Сертификат выписан другим удостоверяющим центром | Разбираться руками. Чаще всего это откат конфига, но проверить стоит внимательно. |
Сверка издателя в этом скрипте — не паранойя. Сертификат, который вдруг выписан другим
удостоверяющим центром, чаще всего означает, что при перезапуске сервер подхватил
не тот файл: старый, тестовый или дефолтный. Браузер такое иногда проглатывает, а
мобильное приложение с закреплённым сертификатом — нет. Заодно загляните в
certificateChain: там каждое звено цепочки со своими датами, издателем
и флагом isValid. Про промежуточные сертификаты вспоминают редко, а даты
у них тоже есть — и проблемы с цепочкой попадают в errors вместе
со всем остальным.
Вторая половина сторожа — сверка DNS. Логика та же: получить записи, сравнить множества значений с эталоном, сказать вслух только про расхождение.
curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
"https://atlorium.com/api/dns/lookup?domain=example.com"
# DMARC лежит на отдельном поддомене — это отдельный запрос:
curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
"https://atlorium.com/api/dns/lookup?domain=_dmarc.example.com"
import os
import requests
API = "https://atlorium.com/api"
HEADERS = {"Authorization": "Bearer " + os.environ["ATLORIUM_KEY"]}
# Эталон. Лежит в репозитории и меняется через pull request — как и любой другой конфиг.
EXPECTED = {
"example.com": {
"A": {"93.184.216.34"},
"MX": {"mail1.example.com", "mail2.example.com"},
"TXT": {"v=spf1 include:_spf.example.com ~all"},
},
"_dmarc.example.com": {
"TXT": {"v=DMARC1; p=quarantine; rua=mailto:dmarc@example.com"},
},
}
def lookup(domain):
r = requests.get(API + "/dns/lookup", params={"domain": domain}, headers=HEADERS, timeout=15)
r.raise_for_status()
data = r.json()
# Пустые records при непустых errors — резолвер не ответил. Это не «записей нет»,
# а «мы не знаем»: поднимать тревогу по такому ответу нельзя.
if not data["records"] and data["errors"]:
raise RuntimeError(domain + ": " + "; ".join(data["errors"]))
# Ответ сгруппирован по типам: records = [{"type": "A", "records": [...]}, ...]
return {g["type"]: {rec["value"] for rec in g["records"]} for g in data["records"]}
for domain, expected_groups in EXPECTED.items():
actual = lookup(domain)
for record_type, expected in expected_groups.items():
got = actual.get(record_type, set())
if got != expected:
print("DNS DRIFT " + domain + " " + record_type)
print(" ожидали: " + str(sorted(expected)))
print(" получили: " + str(sorted(got)))
{
"domain": "example.com",
"resolver": "Cloudflare",
"requestedAtUtc": "2026-07-14T03:00:14Z",
"records": [
{
"type": "A",
"records": [
{ "name": "example.com", "value": "93.184.216.34", "ttl": 300 }
]
},
{
"type": "MX",
"records": [
{ "name": "example.com", "value": "mail1.example.com", "preference": 10, "ttl": 3600 },
{ "name": "example.com", "value": "mail2.example.com", "preference": 20, "ttl": 3600 }
]
},
{
"type": "TXT",
"records": [
{ "name": "example.com", "value": "v=spf1 include:_spf.example.com ~all", "ttl": 3600 }
]
}
],
"errors": []
}
Тот же вызов на шести языках (Python, TypeScript, Go, Java, C#, PHP) — в репозитории dns-lookup-api-client. Примеры запускаются сразу: ключ в них уже стоит демонстрационный.
Осталось запустить это по расписанию. Строку планировщика стоит проверить до того, как
она уедет в прод: /api/cron/evaluate принимает выражение и часовой пояс,
а возвращает нормализованное выражение, разбор по полям и ближайшие запуски.
curl -X POST "https://atlorium.com/api/cron/evaluate" \
-H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
-H "Content-Type: application/json" \
-d '{"expression":"0 6 * * *","timeZoneId":"Europe/Moscow","take":3}'
import requests
resp = requests.post(
"https://atlorium.com/api/cron/evaluate",
json={"expression": "0 6 * * *", "timeZoneId": "Europe/Moscow", "take": 3},
headers={"Authorization": "Bearer ak_sandbox_demo_mockdata_v1"},
timeout=10,
)
result = resp.json()
if not result["isValid"]:
raise SystemExit("Расписание не разобралось: " + result["error"])
# Смотрим глазами на даты — именно здесь ловятся «каждые пять дней», которые не каждые пять.
for moment in result["occurrences"]:
print(moment)
{
"isValid": true,
"rawExpression": "0 6 * * *",
"normalizedExpression": "0 6 * * *",
"segments": ["0", "6", "*", "*", "*"],
"warnings": [],
"error": "",
"occurrences": [
"2026-07-15T06:00:00+03:00",
"2026-07-16T06:00:00+03:00",
"2026-07-17T06:00:00+03:00"
]
}
Тот же вызов на шести языках (Python, TypeScript, Go, Java, C#, PHP) — в репозитории cron-expression-parser-api-client. Примеры запускаются сразу: ключ в них уже стоит демонстрационный.
Сервис принимает 5 и 6 полей (второй вариант — с секундами). Выражения из Quartz он
приводит к своему виду и говорит об этом вслух: символ ? заменяется на
*, седьмое поле с годом отбрасывается — и то и другое попадает в
warnings. Если разобрать выражение не получилось, придёт
isValid: false и текст ошибки в error: ответ 200, а не 400,
потому что «невалидное выражение» — это результат разбора, а не сбой запроса.
Чего это не умеет
Раздел, ради которого стоит читать любую статью про инструмент.
Отзыв сертификата не проверяется. Ни по CRL, ни по OCSP. Сервис устанавливает
TLS-соединение и разбирает то, что сервер показал в рукопожатии: срок, цепочку, издателя,
соответствие имени хосту. Если сертификат отозван удостоверяющим центром, но по датам
ещё действует, в ответе будет isValid: true. Это осознанное ограничение,
а не забытая задача, и полагаться на нас в вопросе отзыва нельзя.
Ответ может быть не сиюминутным. Успешная проверка сертификата сохраняется
и в течение суток отдаётся из локального хранилища, не порождая нового соединения
с вашим сервером. Поле checkedAt показывает, когда рукопожатие было
на самом деле. Для сторожа, который смотрит на daysRemaining, разница
в несколько часов не значит ничего.
Это взгляд снаружи и с одного адреса. Мы видим то, что ваш сервер показал нашему
серверу. Split-horizon DNS, гео-балансировку и региональные различия так не поймать:
propagation по четырём-восьми публичным резолверам даёт срез, а не карту мира.
Это API, а не система мониторинга. Мы не храним историю, не рисуем графики и никому не звоним. Мы отвечаем на один вопрос за один запрос. Скрипт, расписание, пороги и канал оповещения — ваши, и это как раз тот код, который стоит держать у себя: в нём вся ваша специфика.
Демо-ключ отдаёт моки. Сертификат из песочницы всегда валиден, а даты в нём сгенерированы. На нём отлаживают разбор ответа — мониторить боевой домен с ним нельзя.
И привычная оговорка: если внешний источник не ответил, приходит 503 и деньги за такой запрос не списываются.
Частые вопросы
Частые вопросы
Почему мониторинг доступности не видит истёкший сертификат?
Потому что он проверяет другое: жив ли сервер и отвечает ли приложение. Истёкший сертификат серверу не мешает — он честно возвращает HTTP 200. Отказывается работать браузер клиента, а не сервер. К тому же проверки доступности почти всегда ходят с выключенной валидацией TLS, иначе они начинают ложно срабатывать на внутренних адресах.
За сколько дней предупреждать об истечении SSL-сертификата?
Порогов должно быть несколько. Первое молчаливое напоминание — за 30 дней, первое сообщение в чат — за 20 (к этому моменту автопродление уже должно было отработать), ежедневные напоминания — за 14, эскалация владельцу сервиса — за 7, звонок дежурному — за 3 дня. Один порог не работает: либо на него перестают смотреть, либо он срабатывает слишком поздно.
Проверяет ли сервис отзыв сертификата по CRL или OCSP?
Нет. Сервис делает TLS-рукопожатие и разбирает то, что отдал сервер: срок действия, цепочку доверия, издателя, соответствие имени хосту, версию TLS и размер ключа. Отозванный, но не истёкший сертификат он покажет как валидный. Это ограничение, о котором мы говорим прямо.
Как проверить SPF и DMARC через DNS API?
SPF — это TXT-запись самого домена: запросите /api/dns/lookup?domain=example.com и найдите в группе TXT значение, начинающееся с v=spf1. DMARC живёт на отдельном поддомене, поэтому нужен второй запрос — domain=_dmarc.example.com, и смотреть снова в TXT. Обе записи возвращаются вместе с TTL.
Чем propagation отличается от обычного lookup?
Lookup спрашивает один резолвер и отдаёт записи по шести типам. Propagation опрашивает несколько резолверов сразу и показывает ответ каждого отдельно — это нужно после изменения зоны, когда одни резолверы уже видят новые записи, а другие ещё отдают старые. По умолчанию опрашиваются четыре публичных резолвера, всего можно указать до восьми, и тарифицируется такая проверка по числу резолверов.
Можно попробовать без регистрации?
Да. Публичный демо-ключ ak_sandbox_demo_mockdata_v1 работает со всеми примерами из статьи: скопируйте curl и получите ответ. Данные при этом сгенерированные, а не настоящие — они нужны, чтобы увидеть формат и написать код. Реальные сертификаты и DNS-записи приходят с личным ключом.
Сервисы из этой статьи
Срок действия, цепочка доверия и параметры TLS-сертификата домена
Резолв A/AAAA/MX/TXT и других типов, в т.ч. через DoH
Попробовать прямо сейчас — без регистрации
Демо-ключ ak_sandbox_demo_mockdata_v1 — публичный и общий для всех.
С ним API отвечает моками: данные правдоподобные, но сгенерированные,
и они не меняются от запроса к запросу — на них удобно писать тесты.
Настоящие данные приходят с личным ключом.
curl -H "Authorization: Bearer ak_sandbox_demo_mockdata_v1" \
https://atlorium.com/openapi/certificate_ru.json