7 KiB
Замена пересекающихся CIDR зон
Некоторые CIDR зоны принадлежат сразу нескольким порталам (например,
172.217.0.0/16 есть и у google, и у yandex — whois не может их
разделить автоматически). Чтобы не маршрутизировать чужой трафик
при выгрузке адресов одного портала, в его конфиге можно
задать «точечные» замены.
Синтаксис
{
...
"replace": {
"cidr4": {
"172.217.0.0/16": ["172.217.17.206/32", "172.217.17.207/32", "172.217.18.0/24"]
},
"cidr6": {
"2001::/32": ["2001:4860::/32"]
}
}
}
Ключи replace.cidr4 / replace.cidr6 — CIDR-зоны, которые надо убрать
из выдачи cidr4/cidr6 этого портала. Значения — массивы CIDR-зон или
IP-адресов с маской, которые подставляются вместо ключевой зоны.
Некорректная структура (значение не object / не array / не строка)
приводит к ошибке загрузки и остановке сервера — чтобы опечатки не
молчали.
Две фазы работы
Reload-time (при обновлении данных портала)
В конце каждого цикла reload, если выставлен
SYS_REPLACE_ESCALATE_IPS=true (по умолчанию true), сервис проходит
по ключам replace.cidr4/replace.cidr6 и добавляет в value-массивы
все ip4/ip6 портала, попадающие в ключевую зону, с маской /32
(или /128 для IPv6). К каждому value-массиву применяется
minimizeSubnets — поглощённые админом более узкой зоны записи
исчезают, повторный reload не плодит дубликатов. Результат
сохраняется в конфиг.
Таким образом value-массивы растут со временем по мере того, как DNS-запросы находят новые IP портала внутри ключевых зон.
View-time (при ответе HTTP-клиенту)
Все форматы, кроме json, выкидывают из cidr4/cidr6 ключевые
зоны replace и подставляют вместо них value-массивы. После агрегации
между сайтами применяется minimizeSubnets, дубликатов в ответе нет.
json намеренно возвращает сырое состояние портала вместе с полем
replace — клиент может сам решать, как его интерпретировать.
SYS_REPLACE_AGGREGATE_SUBNETS — агрегация без потерь
По умолчанию false.
Если SYS_REPLACE_AGGREGATE_SUBNETS=true, вместо minimizeSubnets
value-массивы прогоняются через supernet-агрегацию:
- 256 подряд идущих
/32свёртываются в один/24; - два смежных
/24— в/23; - и т.д.
Агрегация ограничена префиксом родительского ключа — итоговый блок
никогда не будет шире или равен самому ключу (иначе получился бы
бессмысленный "1.0.0.0/8": ["1.0.0.0/8"]).
Это lossless: покрываемые адреса не меняются, только форма записи.
Имеет смысл включать для порталов с тысячами IP-адресов (Adobe,
Google и т.п.), где без агрегации value-массив разрастается в
тысячи /32 записей.
SYS_REPLACE_COLLAPSE_THRESHOLD_* — плотностное схлопывание (lossy)
Четыре параметра, все по умолчанию 0 (выключены):
| ENV | Уровень | Bucket |
|---|---|---|
SYS_REPLACE_COLLAPSE_THRESHOLD_IP4_24 |
v4 узкий | /24 |
SYS_REPLACE_COLLAPSE_THRESHOLD_IP4_16 |
v4 широкий | /16 |
SYS_REPLACE_COLLAPSE_THRESHOLD_IP6_64 |
v6 узкий | /64 |
SYS_REPLACE_COLLAPSE_THRESHOLD_IP6_32 |
v6 широкий | /32 |
Значение — минимальное количество покрытых адресов в bucket'е.
Если в /24 (для _IP4_24) покрыто ≥ N адресов, весь /24
считается принадлежащим порталу и заменяется одной зоной целиком.
Аналогично для /16, /64, /32.
Порядок применения — «пирамидой»:
- Сначала срабатывает узкий уровень (
/24или/64) — раздувает плотные buckets до полных. - Затем широкий (
/16или/32) считает покрытие уже с учётом инфлейтнутых результатов и, если общая плотность внутри/16//32превышает порог, забирает и эту зону целиком.
Каждый уровень пропускается, если префикс родительского ключа
в replace.cidr4/cidr6 уже ≥ размеру bucket'а — внутри узкого
родителя нет места для bucket'а такого же или большего размера.
Это lossy: в ответ попадут и соседние адреса тех же зон,
не принадлежащие порталу (обычно соседи по CDN или датацентру).
Пороги задают компромисс между точностью и размером вывода.
Работает только в связке с SYS_REPLACE_AGGREGATE_SUBNETS=true.
Массовая разметка порталов
Если уже есть список «широких» CIDR-зон, которые встречаются у
нескольких порталов, можно одним скриптом разом посеять пустые
ключи в replace.cidr4 у всех подходящих порталов — дальше
reload под включённой эскалацией сам заполнит value-массивы.
Инструмент и инструкция: intersection/README.md.