MTA.LAB.mtalab.cc Поддержка →
Гайд

Гео-маршрутизация и failover для трекера: как это работает и как настроить

Трекинг-домен — первая точка, куда попадает трафик. Разбираем, как раздавать его по гео и держать живым при падении узла на уровне DNS: 4 режима правил, Lua-строки, API и проверку через dig.

Трафик в трекер приходит не «в трекер» — он приходит на tracking-домен, и первым на запрос отвечает DNS. Значит, маршрутизацию по странам и отказоустойчивость дешевле всего решить именно здесь: до HTTP, до клоакинга, до приложения. Если узел лёг — резолвер отдаёт другой IP, а ссылки в источниках остаются теми же. Если ГЕО нужно другое — меняется одна запись, а не вся кампания.

Ниже — как это устроено в DNS-платформе MTA.LAB: четыре режима правил, генерация Lua-строк, настройка через UI и API, проверка через dig и чек-лист, который закрывает 90% проблем.

Зачем маршрутизировать на уровне DNS

  • Мульти-ГЕО лендинги. Один tracking-домен отдаёт разным странам разные IP: ближе по сети, проще разделить потоки, меньше зависимость от одного сервера.
  • Скрытие трекера за гео-A-записью. «Белым» резолверам уходит спокойный IP (заглушка или лендинг), рабочий узел виден только нужной гео-ветке. Адрес трекера не светится в общих списках и сканерских выгрузках.
  • Отказоустойчивость. Основной узел недоступен — DNS отдаёт backup. Переключение занимает один TTL, а не часы на правку ссылок в кабинетах источников.
  • Скорость. Ответ ближайшего по сети узла снижает время первого байта: у гео-веток задержка меньше на десятки миллисекунд, а на мобильных сетях разница видна в отвалах.

Экономика простая: одна ошибка в A-записи стоит весь трафик по кампании. TTL 60 секунд превращает аварию в минутный простой; TTL 3600 — в часовой.

Как это работает под капотом

Правила хранятся как PowerDNS Lua-записи и выполняются в момент ответа на DNS-запрос. Логика видит запрос и решает, какой IP вернуть. Ключевой момент, вокруг которого потом возникает больше всего вопросов:

Гео определяется по IP резолвера, а не пользователя. Функции country() и continent() смотрят на источник запроса к авторитативному серверу — то есть на резолвер. EDNS Client Subnet (ECS) не учитывается: если резолвер в другой стране или на anycast-адресе, ответ будет по нему, а не по гео человека.

Почему так, а не «по-другому»: ECS передают не все резолверы, и решение на его основе получается нестабильным. Привязка к IP резолвера предсказуема: пользователи одного публичного резолвера получают один и тот же ответ. Для лендингов и раздачи ближайших узлов этого достаточно; для тонкого гео-таргета по каждому пользователю — нет, и это надо помнить при планировании.

Второй рычаг — TTL. Он применяется к ответу и определяет, как долго резолверы и клиенты держат кэш. Рабочие диапазоны: 60–120 секунд для failover-веток (быстрое переключение) и 300 секунд для стабильных гео-веток, где важнее меньше запросов. Ниже 60 опускаться стоит только при реальной необходимости.

Четыре режима: когда какой

РежимЧто делаетКогда выбиратьНа что смотреть
geoВетка по стране или континенту резолвераМульти-ГЕО лендинги, разделение потоков, скрытие трекераОбязательная дефолтная ветка; TTL 300
closestВозвращает ближайший по сети IP из пулаОдин лендинг на нескольких PoP / anycastНе заменяет failover: ближайший узел тоже может лечь
failoverHealth-check primary и выдача backup при паденииОтказоустойчивость трекера и лендинговTTL 60–120, интервал и таймаут проверки
geo_failoverГео-ветки, внутри каждой — свой health-checkМульти-ГЕО + HA одновременноВдвое больше проверок; следить за дефолтом

Простое правило выбора: есть гео-условия, но нет требований к доступности — geo. Один пул узлов без гео, но важна доступность — failover. Нужны и гео, и доступность — geo_failover. closest — когда узлов много и они равнозначны.

Примеры сгенерированных Lua-строк

Панель не заставляет писать Lua руками: вы заполняете ветки, а правило собирается само. Ниже — что именно уходит в запись в каждом режиме.

geo — страна резолвера решает, какой IP вернуть:

if country() == "RU" then
  return "1.1.1.1"
end
if country() == "KZ" then
  return "2.2.2.2"
end
-- дефолтная ветка: обязательна
return "9.9.9.9"

closest — выбор ближайшего адреса из пула:

local pool = {"1.1.1.1", "5.5.5.5", "9.9.9.9"}
return pickclosest(pool)

failover — health-check порта, при неудаче отдаётся backup:

if ifportup(443, {"10.0.0.10"}, {timeout=1000, retries=2}) then
  return "10.0.0.10"
end
return "10.0.0.20"

Тот же режим с проверкой URL — полезно, когда приложение живёт на нестандартном порту или нужно проверить сам эндпоинт:

if ifurlup("http://10.0.0.10/healthz", {"10.0.0.10"},
           {timeout=1500}) then
  return "10.0.0.10"
end
return "10.0.0.20"

geo_failover — комбинация: гео-ветка, внутри неё primary/backup, снаружи общий дефолт:

if country() == "RU" then
  if ifportup(443, {"10.0.0.10"}) then return "10.0.0.10" end
  return "10.0.0.20"
end
if continent() == "EU" then
  if ifportup(443, {"10.0.1.10"}) then return "10.0.1.10" end
  return "10.0.1.20"
end
return "9.9.9.9"

Пошаговая настройка

В UI всё живёт на странице зоны — в секции «Гео-маршрутизация и отказоустойчивость». Порядок такой:

1
Открыть зону1 минута

Выберите tracking-домен, прокрутите до секции гео-маршрутизации. Здесь же видно текущие Lua-правила и их статус.

зонасекция гео-маршрутизациивкл/выкл правила
2
Собрать правило5 минут

Режим, гео-условия (страна или континент), primary и backup, проверка порта или URL. Список стран подтягивается из платформы — вручную ничего вводить не нужно.

geo / closest / failover / geo_failovertimeout 1000–1500 мс2–3 retry
контрольный пункт: у правила есть дефолтная ветка с живым IP
3
Предпросмотр и сохранение2 минуты

Предпросмотр показывает итоговую Lua-строку до записи. Сохранили — правило можно выключить и включить без удаления, TTL задаётся тут же.

preview LuaTTL 60–300toggle вкл/выкл
контрольный пункт: ответ проверен из двух гео
4
То же через API10 минут

Для автоматизации — REST: список, создание, правка, удаление и предпросмотр правил, плюс справочник стран. Ниже — примеры.

GET/POST /luaPUT/DELETE /lua/<id>POST /lua/previewGET /lua/countries
5
Мониторингпостоянно

Логи зоны показывают запросы и ответы, алерты приходят в Telegram при недоступности узла. Отдельно стоит следить за частотой смены ответа.

логи зоныалертыDNS Traffic

API: curl-примеры

Список правил зоны и создание гео-правила:

TOKEN=...; ZONE=go.example.com

curl -s -H "Authorization: Bearer $TOKEN" \
  https://dns.mtalab.cc/api/v1/zones/$ZONE/lua

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"geo","ttl":300,
       "rules":[{"country":"RU","answer":"1.1.1.1"}],
       "default":"9.9.9.9"}' \
  https://dns.mtalab.cc/api/v1/zones/$ZONE/lua

Правка и удаление правила по идентификатору, предпросмотр без сохранения:

curl -s -X PUT -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"ttl":60,"enabled":true}' \
  https://dns.mtalab.cc/api/v1/zones/$ZONE/lua/<id>

curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
  https://dns.mtalab.cc/api/v1/zones/$ZONE/lua/<id>

curl -s -X POST -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"type":"geo_failover","default":"9.9.9.9"}' \
  https://dns.mtalab.cc/api/v1/zones/$ZONE/lua/preview

Справочник стран для условий:

curl -s -H "Authorization: Bearer $TOKEN" \
  https://dns.mtalab.cc/api/v1/lua/countries

Проверка через dig

Базовый ответ:

dig @ns1.go.example.com go.example.com A +short

А теперь нюанс, который путает всех. Запрос с подставленным subnet не изменит ответ:

dig @ns1.go.example.com go.example.com A +subnet=5.5.5.5 +short
Почему одинаково: country() смотрит IP источника запроса к авторитативному серверу, то есть адрес самого dig или резолвера, а не +subnet. Чтобы протестировать ветку, запрашивайте с узла в нужной стране или через резолвер нужного гео: dig @<resolver-in-RU> .... ECS в платформе не учитывается сознательно — поведение предсказуемо и не зависит от того, пробрасывает ли резолвер subnet.

Проверка failover: остановите приложение на primary (или закройте порт) и повторите dig — после health-check ответ сменится на backup. Время смены = интервал проверки плюс TTL, который держат резолверы.

Чек-лист настройки

  • TTL осознан: 60–120 секунд для failover-веток, 300 — для стабильных гео; не 3600, если ждёте быстрого переключения.
  • Дефолтная ветка есть и возвращает живой IP: страна без правила не должна получать пустой ответ.
  • Health-check настроен на реальный путь: порт 443 или отдельный /healthz, timeout 1000–1500 мс, 2–3 retry — чтобы случайный сетевой всплеск не переключил трафик.
  • Primary и backup изолированы: разные стойки, сети или провайдеры; два IP на одном хосте отказоустойчивости не дают.
  • В гео-ветках — только проверенные узлы. Не кладите в правило тестовые и временные адреса: они уедут в прод.
  • После сохранения — проверка из двух гео и через API, чтобы исключить опечатку в country-коде.
  • Мониторинг включён: алерт на недоступность узла, логи DNS-запросов и отдельный взгляд на частоту переключений.
  • Изменения через предпросмотр. Сначала preview, потом запись — правило на живом домене ошибаться не должно.

Типичные ошибки

ОшибкаПоследствиеКак правильно
TTL 3600 на failover-веткеРезолверы держат упавший IP до часа60–120 секунд на время активного failover
Забыли дефолтЧасть гео получает NXDOMAIN или пустотуДефолтная ветка с рабочим IP всегда
Проверка через +subnetОжидание «правильной» страны, которого не будетТестировать с узла или резолвера нужного гео
Health-check на URL с самоподписанным сертификатомПроверка всегда «упала», трафик постоянно на backupВалидный TLS или проверка порта вместо URL
Primary и backup — один хостПадение узла = падение обеих ветокРазные машины и сети
Гео «по пользователю»VPN и публичные резолверы искажают картинуПланировать по гео резолвера, тестировать реальными резолверами
Правка правила без предпросмотраСломанная запись на живом доменеpreview → сохранение → проверка dig

Смежные темы — в других материалах: как защитить воронку от ботов на уровне трекера — гайд по антибот-фильтрации, а как перевезти кампании без потерь — план переезда на свой трекер.

← Все статьи блога Свой трекер и защита воронки от ботов → Переезд на свой трекер →
Настройте гео-маршрутизацию в DNS-платформе

Зоны, Lua-правила, health-check и логи запросов — в одном кабинете. Демо без регистрации, данные вымышленные.

DNS-платформа подробнее → Проверить домены
Есть свой сценарий маршрутизации?

Пришлите схему потоков и гео — соберём правила, покажем предпросмотр Lua и проверим ответы из нужных стран.

Написать в поддержку