Правила маршрутизации: DOMAIN, GEOIP и RULE-SET
Содержание
Правила маршрутизации — это то, что превращает прокси из «включил и всё пошло через сервер» в осмысленный инструмент: одни соединения уходят через выбранный узел, другие идут напрямую, третьи блокируются. В конфигурации mihomo за это отвечает секция rules, и её логика проще, чем кажется на первый взгляд.
Ядро проверяет правила строго сверху вниз и останавливается на первом совпавшем. Это единственный принцип, который нужно держать в голове: порядок строк важнее их количества. Разберём типы правил, параметр no-resolve, внешние наборы правил и способ узнать, какое именно правило сработало.
Как выполняется проверка
Для каждого нового соединения ядро идёт по списку сверху вниз, сравнивая запрошенный адрес с условием очередного правила. Первое совпадение определяет адресата — имя группы прокси, DIRECT для прямого подключения или REJECT для блокировки. Дальнейшие строки не проверяются.
Последняя строка обычно MATCH — правило без условия, которое ловит всё, что не совпало раньше. Без него часть трафика осталась бы без адресата. Отсюда практическое следствие: частные правила пишут выше, общие — ниже. Правило GEOIP,CN,DIRECT, поставленное первым, перехватит и те домены, которые вы намеревались направить в прокси отдельной строкой ниже.
Важная оговорка: весь этот механизм работает только в режиме rule. В глобальном режиме ядро отправляет через прокси всё подряд, в прямом — не проксирует ничего, и секция rules в обоих случаях не участвует. Если правила «не действуют», первым делом проверьте выбранный режим — этим объясняется добрая половина таких случаев.
Совет. Держите правила сгруппированными по смыслу и в устойчивом порядке: локальные адреса, блокировки, сервисы для прокси, географические исключения, MATCH. Так при добавлении новой строки сразу понятно, куда её ставить, и она не перекроет соседей.
Правила по доменам
Три основных типа отличаются способом сравнения имени:
| Тип | Что совпадает | Пример |
|---|---|---|
DOMAIN | Точное имя целиком | DOMAIN,api.example.com,PROXY |
DOMAIN-SUFFIX | Домен и все его поддомены | DOMAIN-SUFFIX,example.com,PROXY |
DOMAIN-KEYWORD | Любое имя, содержащее подстроку | DOMAIN-KEYWORD,github,PROXY |
Суффиксное правило — рабочая лошадка: одна строка накрывает и сам домен, и все поддомены сервиса. Правило по ключевому слову удобно, когда сервис размазан по десяткам доменов, но действует оно грубо и может зацепить лишнее, поэтому применять его стоит осознанно.
Разница между точным и суффиксным правилом важнее, чем кажется. DOMAIN,example.com совпадёт только с самим example.com, но не с www.example.com, а сайт почти всегда подтягивает ресурсы с поддоменов. Отсюда ощущение, что правило «работает через раз»: суффиксная форма закрывает домен целиком, а точная нужна лишь для выделения одного конкретного хоста.
Правила по IP-адресам и no-resolve
Когда домена нет (например, приложение соединяется прямо по адресу), в дело вступают правила по IP:
IP-CIDR— диапазон адресов в нотации CIDR:IP-CIDR,192.168.0.0/16,DIRECT.IP-CIDR6— то же самое для IPv6.GEOIP— принадлежность адреса стране по встроенной базе:GEOIP,CN,DIRECT.
Здесь появляется важный нюанс. Чтобы сравнить доменное соединение с IP-правилом, ядру нужно сначала узнать адрес — то есть выполнить DNS-запрос. Параметр no-resolve запрещает такое разрешение: правило проверяется только для соединений, где адрес уже известен.
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
Практическая польза двойная: экономятся лишние запросы к DNS и не происходит утечки имён при разрешении «на всякий случай». Для правил из локальных диапазонов no-resolve ставят почти всегда.
Перечисленными типами набор не исчерпывается: ядро понимает и более узкие условия — например, по порту назначения или по имени процесса, который устанавливает соединение. Они выручают в частных случаях вроде «этот мессенджер всегда напрямую», но в типовых конфигурациях провайдеров встречаются редко.
RULE-SET и внешние наборы правил
Держать тысячи доменов прямо в конфигурации неудобно. Для этого есть наборы правил: файл со списком лежит отдельно, а ядро подгружает и обновляет его само. Описываются они в секции rule-providers:
rule-providers:
ads:
type: http
behavior: domain
format: yaml
url: "https://example.com/rules/ads.yaml"
path: ./ruleset/ads.yaml
interval: 86400
Поле behavior сообщает, что внутри: domain — список доменов, ipcidr — список подсетей, classical — строки в том же формате, что и обычные правила. Поле interval задаёт период обновления в секундах, path — куда сохранять локальную копию. После описания набор используется одной строкой в rules:
- RULE-SET,ads,REJECT
Две типичные ошибки с наборами правил связаны как раз с этими полями. Первая — несоответствие behavior содержимому файла: список доменов, объявленный как ipcidr, ядро загрузить не сможет, и в логе появится сообщение о неверном формате набора. Вторая — слишком частое обновление: interval задаётся в секундах, и 86400 (раз в сутки) для списков доменов вполне достаточно. Локальная копия по пути из path позволяет ядру стартовать даже тогда, когда источник временно недоступен.
Типичная структура секции rules
Собранный вместе фрагмент выглядит примерно так — от частного к общему:
rules:
- DOMAIN-SUFFIX,local,DIRECT
- IP-CIDR,127.0.0.0/8,DIRECT,no-resolve
- IP-CIDR,192.168.0.0/16,DIRECT,no-resolve
- RULE-SET,ads,REJECT
- DOMAIN-KEYWORD,github,PROXY
- DOMAIN-SUFFIX,example.org,PROXY
- GEOIP,CN,DIRECT
- MATCH,PROXY
Сначала локальные адреса, затем блокировки, потом сервисы, которым нужен прокси, ниже — географическое исключение для прямых подключений и в самом конце MATCH. Имена PROXY и другие адресаты должны существовать среди групп прокси, иначе ядро откажется загружать конфигурацию.
Как понять, какое правило сработало
Гадать не нужно: клиенты на ядре mihomo показывают для каждого активного соединения адрес назначения, сработавшее правило и выбранного адресата. Откройте панель соединений, воспроизведите проблемный запрос и посмотрите строку — обычно сразу видно, что домен перехватило слишком общее правило выше по списку. Второй источник — журнал ядра при уровне debug.
Разбор удобно вести по одному и тому же порядку:
- Убедитесь, что выбран режим
rule, — иначе правила вообще не применяются. - Очистите список соединений и откройте проблемный адрес заново, чтобы он оказался в списке первым.
- Посмотрите в строке соединения имя сработавшего правила и выбранного адресата.
- Найдите это правило в конфигурации и проверьте, нет ли выше более общей строки, которая перехватила запрос.
- Внесите правку и перезагрузите профиль: правила читаются при загрузке конфигурации, а не на лету.
Если же прокси не работает целиком, а не для отдельного сайта, дело не в правилах — начните с пошаговой диагностики подключения.
Если же соединение вообще не появляется в списке, проблема не в правилах, а раньше — в разрешении имён. Что происходит на этом этапе, разобрано в руководстве по настройке DNS; общая структура файла, куда вписывается секция rules, — во введении в конфигурацию mihomo.