Как перенести сотни доменов на Cloudflare и не отдать кому-то Global API Key

Спойлер: через веб-интерфейс это 6–8 часов кликов, через чистый API — упираешься в ограничения scoped-токенов, а Global API Key нельзя с чистой совестью хранить на чужом сервере.

Рассказываю, как мы собрали два инструмента под одну задачу — и почему именно два, а не SaaS.

Привет. Делаем с командой инфраструктуру на Cloudflare под 301.ru, и за последний год руками прошли через все три варианта добавления доменов в Cloudflare в больших количествах. Всё, что ниже — не гипотетика, а то, куда реально упёрлись и чем лечили.

Боль, с которой всё началось

Представьте: заводим новый Cloudflare-аккаунт под проект, на него нужно подцепить 200–500 доменов. Через веб-интерфейс это выглядит так:

  1. «Add site» → ввод домена → Continue
  2. Выбор плана (Free) → Continue
  3. Сканирование DNS → Continue
  4. Копирование назначенных nameservers → идём в регистратор → меняем NS
  5. Возврат в Cloudflare → Check nameservers

Пять экранов на один домен. Умножаем на 300 — получаем примерно 1500 кликов и весь рабочий день в глухом интерфейсе, где половина времени уходит на ожидание. Это та точка, в которой нормальный разработчик говорит «окей, пойду в API».

Подход №1: чистый API и boilerplate на Python

Первое, что делаешь — идёшь на api.cloudflare.com, берёшь API Token, пишешь скрипт. Выглядит всё просто: POST /zones c {"name": "example.com", "account": {"id": "..."}}. На десятке доменов работает, на сотне начинаются нюансы:

  • Rate limits. У Cloudflare API глобальный лимит — 1200 запросов за 5 минут на user. На пачках это ловится не сразу, а ближе к середине, и нужен корректный backoff с уважением Retry-After.
  • Domain parsing. Реальные списки редко приходят чистыми — там субдомены, www, URL с путями, смешанные IDN и Punycode. Нужен нормальный парсер, который достанет eTLD+1.
  • Идемпотентность. Нажал Ctrl+C на 340-м домене из 500 — как продолжить без повторов и без пропусков?
  • Многоаккаунтность. Если у тебя 4 аккаунта под разные пулы — каждый прогон нужно перенастраивать.

Всё это решается, но это проект на неделю, а не «часик вечером». И главное — этот скрипт живёт у тебя в консоли, не у клиента/коллеги, который тоже хочет заливать домены.

Подход №2: сделать SaaS — и тут вылезает настоящая проблема

Логичная мысль: раз боль массовая, сделаем веб-сервис. Юзер вводит API-ключ, заливает список доменов, жмёт кнопку — получает результат. Сотни часов экономии на всех.

И тут ты упираешься в архитектурную стену, о которую разбивается половина потенциальных CF-сервисов.

API Token не умеет создавать зоны в рамках только своего scope. Токены в Cloudflare привязаны к списку уже существующих зон. Чтобы создать новую — нужен permission Zone:Edit на уровне аккаунта, не на уровне отдельных зон. А токен с таким permission фактически равен доступу ко всему пулу доменов клиента — он может их создавать, удалять, перевыпускать DNS-записи, менять SSL-настройки. По степени власти это недалеко от Global API Key.

Global API Key — это root-доступ ко всему аккаунту: домены, DNS, Workers, KV, R2, billing, members. Один ключ на всё. Удобно для автоматизации — но смертельно для того, кто собирается этот ключ хранить у себя.

Представьте сервис, которому пользователи отдают свои Global API Keys. Что ты получаешь вместе с базой этих ключей:

  • Фактическое владение инфраструктурой всех клиентов. Утечка базы = катастрофа для каждого из них.
  • Compliance. Хранение чувствительных credentials → SOC 2, пентесты, страхование.
  • Юридическую ответственность. Если через скомпрометированный ключ кто-то заддосит клиента или уведёт трафик — отвечать будешь ты.
  • Полное несоответствие философии 301.st, где мы специально не храним ни трафик клиентов, ни их конфиги — всё работает на их собственных Cloudflare-аккаунтах через их токены.

Мы посидели с этим 15 минут и сказали «нет, спасибо».

Подход №3: вынести автоматизацию на клиент

Архитектурный вывод оказался простой: если ключ настолько мощный, что его нельзя передавать никому — пусть он и не передаётся. Автоматизация выполняется на устройстве пользователя, ключ живёт там же, мы в принципе не видим ни ключа, ни того, какие домены добавляются.

Так появились два инструмента. Один — расширение браузера, второй — десктоп для Windows. Разные рантаймы под разные сценарии, общая логика: API-запросы идут напрямую client → Cloudflare, через наши серверы не проходит ничего.

Cloudflare Tools — расширение браузера

Как перенести сотни доменов на Cloudflare и не отдать кому-то Global API Key

wpps.ru/products/cloudflare-tools — Chrome / Firefox / Edge.

Когда подходит: работаешь в браузере, нужна мобильность между машинами, разовые пачки по несколько десятков — несколько сотен доменов. Живёт в боковой панели (Side Panel API), не открывается отдельным окном.

Что внутри:

  • Парсер доменов. Вставляешь что угодно — список из Excel, кусок лога, письмо с URL, экспорт из регистратора. Выделяет валидные домены, нормализует до eTLD+1, показывает preflight-превью: что будет создано, что пропущено как дубликат, что невалидно. Это до вызова API.
  • Хранение ключа. AES-256-GCM со случайным 256-битным ключом. Сам ключ живёт только в session storage браузера и уничтожается при закрытии. Изолировано в storage расширения — сайты и другие расширения не имеют доступа.
  • Устойчивость. Прогресс операции сохраняется в IndexedDB. Закрыл браузер на 300-м домене из 500 — открываешь обратно, жмёшь Resume, продолжаешь с 301-го. Pause/resume/cancel работают на любой фазе.
  • Rate-limit handling. Cloudflare возвращает 429 с заголовком Retry-After — расширение читает его и выдерживает нужную паузу, не упарывая экспоненциальный backoff вслепую.
  • Сопутствующие операции. На том же интерфейсе — массовый purge cache (everything для выбранных зон) и массовое удаление зон с постраничным выбором.

CFTools для Windows — десктоп

Как перенести сотни доменов на Cloudflare и не отдать кому-то Global API Key

Когда подходит: десятки аккаунтов, работаешь постоянно, нужно чтобы приложение жило в системе и не требовало открывать браузер. Плюс Windows Credential Manager как место хранения — это другой threat model, чем session storage.

Отличия от расширения:

  • Persistent-хранилище ключа. Windows Credential Manager, DPAPI под капотом. Не уничтожается при перезапуске.
  • Мульти-аккаунт. Вводишь Global API Key один раз, переключаешься между аккаунтами в один клик без повторного логина. Для тех, у кого отдельные CF-аккаунты под каждый проект/бренд — экономия часа в неделю просто на переключении.
  • Парсер с IDN/Punycode. Русские, немецкие, китайские домены — нормализует корректно в обе стороны.
  • Светлая/тёмная тема по системным настройкам.

Что выбрать

СценарийИнструментРазовая пачка, работа с нескольких машинРасширениеПостоянная работа с десятками аккаунтовWindowsНе доверяешь persistent-хранилищу, хочешь чтобы ключ умирал с сессиейРасширениеРаботаешь без интернета в браузере, всё через трейWindowsНужно и то и тоОба, ключ один, поведение разное

Выводы

Массовое добавление доменов в Cloudflare — это не столько про «написать скрипт», сколько про доверие к ключу. API Token упирается в scope, Global API Key нельзя отдавать наружу — и правильное архитектурное решение лежит не в сторону SaaS, а в сторону клиентского софта, где ключ вообще не покидает устройство.

Оба инструмента бесплатные, без телеметрии и аккаунтов. Если у вас своя боль с Cloudflare API — напишите в комментариях, возможно следующий инструмент мы соберём под неё.

Делаем в 301.ru — команда из трех человек, остальное на Cloudflare Workers.

Начать дискуссию