Начал раздавать бесплатные поддомены на fluxcast.dev и погряз в войне с DNS, гитом и сертификатами

от автора

Если вы читали мою прошлую статью про FluxCast (тот самый лучший Miracast-клиент =] ), то там мелькал некрасивый сабдомен моего лендинга. Но недавно все изменилось. Я зарегистрировал нормальный домен fluxcast.dev и так бы он и лежал в интернете, а потом я понял, что домену этому реально нужен только один апекс, остальное простаивает без дела.

Тогда я вспомнил проект is-a.dev на который натыкался и раньше. Механика простая: форкаешь репозиторий, кидаешь JSON-файл со своими DNS-записями, открываешь PR, тебе выдают бесплатный поддомен. Идея понравилась настолько, что решил сделать так же у себя, только код написать самому и на Python, а не на JS и Go с DNSControl, как у них.

Звучало как вечер работы. Оказалось не совсем.

Валидация

Первым делом написал проверки для входящих файлов, примерно те же, что у is-a.dev, только на pytest. Приватные IP отсекаются через ipaddress, а дублирующиеся ключи в JSON пришлось ловить отдельно руками. Оказывается, json.loads в Python молча схлопывает повторяющиеся ключи объекта и оставляет только последний. Если бы я это не проверил, кто-то мог бы подсунуть в PR второй набор DNS-записей, спрятанный под задублированным ключом, и я бы этого не заметил при ревью.

Продакшен есть продакшен

На fluxcast.dev уже жил боевой лендинг, и всю миграцию на Cloudflare я боялся, что скрипт случайно снесёт его записи. Решил просто: каждая запись, которую создаёт мой синк, помечается комментарием managed-by:fluxcast-domains, и при каждом запуске скрипт видит в Cloudflare только записи с этой меткой. Остальное для него не существует.

Потом перепутал Zone ID с Account ID в дашборде Cloudflare… ну с кем не бывает, они рядом и выглядят одинаково. Синк справедливо отказался работать с ошибкой “zone not found”, минут десять искал, где накосячил. Разобрался, запустил публикацию по-настоящему — прилетело TypeError: Missing required argument: 'ttl'. В новой версии Cloudflare SDK для Python этот параметр стал обязательным, хотя в документации я этого не заметил. Починил одной строчкой.

Гит не прощает

Пока разбирался, как устроен is-a.dev, склонировал их репо в соседнюю папку для референса и забыл про это. Папка вместе со своим .git внутри попала в коммит не как файлы, а как ссылка на чужой коммит. На GitHub это выглядело как битая директория. Обычный git rm тут не годится, запись уже сидит в истории, пришлось пересобирать всё дерево в один чистый коммит и форсить его поверх старой ветки.

И напоследок сюрприз от собственного домена

Когда всё было готово, запустил публикацию вручную и минут пять смотрел на статус “в очереди”, хотя должно было выполниться за секунды. Совпало два фактора: у GitHub в тот день был лёгкий сбой Actions, а мой репозиторий был приватным, а приватным раннеры выдаются в последнюю очередь. Сделал репозиторий публичным, очередь исчезла.

А ещё, когда поднял публичный API реестра на отдельном поддомене через GitHub Pages, зашёл проверить в браузере и получил во весь экран предупреждение про небезопасное соединение с несовпадающим сертификатом. Секунд десять реально думал, что домен перехватили. Разгадка банальная: сертификат для нового поддомена ещё не успел выпуститься, а зона .dev в HSTS-preload листе, поэтому браузер не даёт исключение и жёстко ругается. Через пару минут всё встало на место само.

Что в итоге

Получился рабочий реестр: форкаешь репозиторий, добавляешь один JSON

// пример{    "owner": { "username": "your-github-username", "email": "you@example.com" },    "records": { "CNAME": "your-github-username.github.io" }}

с DNS-записями, открываешь PR. Проверки гоняют файл через валидацию и следят, что ты правишь только свой файл. Проходит — мёржу, через пару минут поддомен резолвится.

Отдельно решил не повторять чужую бюрократию: сам не раз упирался в сервисы, где твой проект придирчиво проверяют “достаточно ли он про разработку” и заворачивают, если сайт кажется недостаточно готовым. У меня правило одно: сайт должен быть законным, а тема любая, хоть личная страница, хоть коммерция. Режу только реальный вред.

Реестр совсем свежий. Если хотите поддомен, гайд лежит на sub.fluxcast.dev. Найдёте баг в проверках — открывайте issue, я читаю все каждый день 24/7 =]

ссылка на оригинал статьи https://habr.com/ru/articles/1062462/