Перейти к основному содержанию

Синтаксис правил DNS-фильтрации

info

Рассказываем, как писать пользовательские правила DNS-фильтрации для использования в продуктах AdGuard

Быстрые ссылки: Скачать Блокировщик AdGuard, Установить AdGuard Home, Попробовать AdGuard DNS

Введение

Синтаксис правил фильтрации AdGuard DNS можно использовать, чтобы сделать правила более гибкими и блокировать контент в соответствии с вашими предпочтениями. Применять данный синтаксис можно в разных продуктах AdGuard, таких как AdGuard Home, AdGuard DNS, AdGuard для Windows/Mac/Android.

Есть три подхода к написанию hosts-списков блокировки:

  • Синтаксис в стиле Adblock: современный подход к написанию правил фильтрации, базирующийся на использовании подгруппы синтаксиса правил типа Adblock. Таким образом списки блокировки становятся совместимы с браузерными блокировщиками.

  • /etc/hosts синтаксис: это старый и проверенный подход, при котором используется тот же синтаксис, что и в операционных системах для hosts-файлов.

  • Синтаксис Domains-only: простое перечисление имён доменов.

Если вы создаёте список блокировки, мы рекомендуем использовать синтаксис Adblock. У него есть несколько важных преимуществ перед старым синтаксисом:

  • Размер списков блокировки. Применяя сопоставление шаблонов, вы сможете использовать одно правило вместо сотен записей /etc/hosts.

  • Совместимость. Ваш список блокировки будет совместим с браузерными блокировщиками рекламы, что сделает обмен правилами с фильтрами браузера более простым.

  • Расширяемость. За последнее десятилетие синтаксис Adblock значительно развился, и мы не видим причин, почему мы не можем расширить его ещё больше и дать дополнительные возможности сетевым блокировщикам.

Если вы поддерживаете чёрный список в стиле /etc/hosts или несколько списков фильтрации (независимо от типа), мы предоставляем инструмент для их составления. Мы назвали его Компилятор списков хостов и сами используем его для создания DNS-фильтра AdGuard.

Базовые примеры

  • ||example.org^: блокирует доступ к домену example.org и всем его поддоменам, таким как www.example.org.

  • @@||example.org^: разблокирует доступ к домену example.org и всем его поддоменам.

  • 1.2.3.4 example.org: (внимание, устаревший синтаксис типа /etc/hosts) в AdGuard Home отвечает 1.2.3.4 на запросы к домену example.org, но не к его поддоменам. В приватном AdGuard DNS блокирует доступ к example.org. www.example.org остаётся доступным.

    В AdGuard Home использование неопределённого IP-адреса (0.0.0.0) или локального адреса (127.0.0.1 и т. п.) для хоста практически то же самое, что и блокировка этого хоста.

    # Возвращает IP-адрес 1.2.3.4. для example.org.
    1.2.3.4 example.org
    # Блокирует example.org ответом 0.0.0.0.
    0.0.0.0 example.org
  • example.org: простое доменное правило. Блокирует домен example.org, но не его поддомены. www.example.org остаётся доступным.

  • ! Это комментарий и # Это тоже комментарий: комментарии.

  • /REGEX/: блокирует доступ к доменам, соответствующим заданному регулярному выражению.

Синтаксис по примеру блокировщиков

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

     rule = ["@@"] pattern [ "$" modifiers ]
modifiers = [modifier0, modifier1[, ...[, modifierN]]]
  • pattern: маска имени хоста. Каждое имя хоста сопоставляется с этой маской. Шаблон также может содержать особые знаки, о которых сказано ниже.

  • @@: маркер, использующийся в правилах исключений. Ставьте этот маркер в начало правила, если хотите отключить фильтрацию для совпадающих имён хостов.

  • modifiers: параметры, объясняющие правило. Они могут ограничить сферу применения правила или даже полностью изменить принцип его действия.

Специальные символы

  • *: подстановочный знак. Используется, чтобы обозначить любой набор символов. Это может быть пустая строка или строка любой длины.

  • ||: совпадает с началом имени хоста, включая любые субдомены. Например, ||example.org соответствует example.org и test.example.org, но не testexample.org.

  • ^: символ-разделитель. В отличие от блокировки рекламы в браузере в имени хоста нечего разделять, поэтому единственная цель этого символа — отметить конец имени хоста.

  • |: указатель на начало или конец имени хоста. Значение зависит от расположения символов в маске. Например, правило ample.org| относится к example.org, но не к example.org.com. А правило |example относится к example.org, но не к test.example.

Регулярные выражения

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

pattern = "/" regexp "/"

Примеры:

  • /example.*/ заблокирует хосты, совпадающие с регулярным выражением example.*.

  • @@/example.*/$important разблокирует хосты, совпадающие с регулярным выражением example.*. Обратите внимание, что это правило также включает модификатор important.

Комментарии

Любая строка, начинающаяся с восклицательного знака или хеша, является комментарием, и будет проигнорирована движком фильтрации. Комментарии обычно размещаются над правилами и описывают то, что они делают.

Пример:

! Это комментарий.
# Это тоже комментарий.

Модификаторы правил

Вы можете изменить поведение правила при помощи модификаторов. Их необходимо располагать в конце правила после символа $ и разделять запятыми.

Примеры:


  • ||example.org^ — паттерн правила. $ — разделитель, который указывает на то, что остальные части правила — это модификаторы. important — модификатор.

  • Возможно, вы захотите использовать в правиле несколько модификаторов. В этом случае разделяйте их запятыми:

    ``none ||example.org^$client=127.0.0.1,dnstype=A


    `||example.org^` — совпадающий шаблон. `$` — разделитель, который указывает на то, что остальные части правила являются модификаторами. `client=127.0.0.1` — модификатор [`client`][] со значением `127.0.0.1`. `,` — разделитель между модификаторами. И наконец, `dnstype=A` — [`dnstype-модификатор`][] со значением `А`.

Обратите внимание: если правило содержит модификатор, не указанный в этом документе, всё правило следует игнорировать. Таким образом мы избегаем ложных срабатываний, когда люди пытаются использовать немодифицированные списки фильтров браузерных блокировщиков рекламы, таких как EasyList или EasyPrivacy.

client

Модификатор client позволяет указывать клиентов, к которым применяется это правило. Есть два основных способа определения клиента:

  • По его IP-адресу или CIDR-префиксу. Этот способ подходит для всех типов клиентов.

  • По имени. Этот способ работает только для сохранённых клиентов в AdGuard Home и устройств в приватном AdGuard DNS, которых вы добавили вручную.

    Внимание: в AdGuard Home ClientID временно не поддерживаются, только имена. Если вы добавили клиента с именем «My Client» и ID клиентаmy-client, напишите модификатор как $client='My Client', а не $client=my-client.

Синтаксис:

$client=value1|value2|...

Вы также можете исключить клиента из фильтрации, добавив перед значением символ ~. В этом случае правило не будет применяться к DNS-запросам этого клиента.

$client=~value1

Имена клиентов обычно содержат пробелы или другие специальные символы, поэтому необходимо заключать их в кавычки. Поддерживаются как одинарные, так и двойные кавычки ASCII. Используйте обратный слеш (\), чтобы изолировать кавычки (" и '), запятые (,) и вертикальные разделители (|).

Обратите внимание: исключая клиента из фильтрации, обязательно выносите символ ~ за кавычки.

Примеры:

  • @@||*^$client=127.0.0.1: разблокирует всё для localhost.

  • ||example.org^$client='Frank\'s laptop': блокирует домен example.org только для клиента с именем Frank's laptop. Обратите внимание, что апостроф (') в имени должен быть экранирован.

  • ||example.org^$client=~'Mary\'s\, John\'s\, and Boris\'s laptops': блокирует домен example.org для всех, кроме клиентов с именами Mary's, John's, and Boris's laptops. Как вы видите, запятая (,) тоже должна быть экранирована.

  • ||example.org^$client=~Mom|~Dad|Kids: блокирует домен example.org для клиента Kids, но не для клиентов Mom и Dad. Этот пример демонстрирует, как указать несколько клиентов в одном правиле.

  • ||example.org^$client=192.168.0.0/24: блокирует домен example.org для клиентов с IP-адресами в диапазоне от 192.168.0.0 до 192.168.0.255.

denyallow

Вы можете использовать модификатор denyallow, чтобы исключить домены из правила блокировки. Чтобы добавить несколько доменов в одно правило, используйте символ | в качестве разделителя.

Синтаксис:

$denyallow=domain1|domain2|...

Этот модификатор позволяет избежать создания ненужных правил исключения, когда блокирующее правило охватывает слишком много доменов. Возможно, вы захотите заблокировать всё, за исключением нескольких доменов верхнего уровня. Вы можете использовать стандартный подход, т. е. такие правила, как эти:

! Заблокировать всё.
/.*/

! Разблокировать несколько доменов верхнего уровня.
@@||com^
@@||net^

Проблема этого подхода в том, что вы также разблокируете отслеживающие домены, расположенные на этих доменах верхнего уровня (например, google-analytics.com). Но её можно решить с помощью модификатора denyallow:

*$denyallow=com|net

Примеры:

  • *$denyallow=com|net: блокирует все домены *.com и *.net.

  • @@*$denyallow=com|net: разблокирует все домены, кроме *.com и *.net.

  • ||example.org^$denyallow=sub.example.org. блокирует example.org и *.example.org, но не блокирует sub.example.org.

dnstype

Модификатор dnstype позволяет указать тип DNS-запроса или ответа, на который будет срабатывать это правило.

Синтаксис:

$dnstype=value1|value2|...
$dnstype=~value1|~value2|~...

Имена типов можно указывать в любом регистре, но они проверяются на соответствие настоящим типам DNS-записей.

Не объединяйте исключающие правила с включающими. Например, это правило:

$dnstype=~value1|value2

эквивалентно этому:

$dnstype=value2

Примеры:

  • ||example.org^$dnstype=AAAA: блокирует DNS-запросы для IPv6-адресов домена example.org.

  • ||example.org^$dnstype=~A|~CNAME: пропускает только A и CNAME DNS-запросы для домена example.org и блокирует все остальные.

Обратите внимание: до версии 0.108.0 для фильтрации записей ответа AdGuard Home использовал тип запроса, а не тип ответа самой записи. Это вызывало проблемы, поскольку у пользователя не было возможности написать правила, которые разрешали бы определённые записи CNAME в ответах на запросы A и AAAA. Начиная с версии 0.108.0 были внесены изменения, и теперь это правило:

||canon.example.com^$dnstype=~CNAME

позволяет избежать фильтрации следующего ответа:

ОТВЕТЫ:
-> example.com
canonical name = canon.example.com.
ttl = 60
-> canon.example.com
internet address = 1.2.3.4
ttl = 60

dnsrewrite

Модификатор ответа dnsrewrite позволяет заменить содержание ответа на DNS-запрос для совпадающих хостов. Обратите внимание, что этот модификатор работает во всех правилах AdGuard Home, а в приватном AdGuard DNS — только в пользовательских.

Правила, содержащие модификатор ответа dnsrewrite, получают больший приоритет в сравнении с другими правилами в AdGuard Home.

Ответы на все запросы к хосту, соответствующему правилу dnsrewrite, будут заменены. Раздел ответа замещающего ответа будет содержать только RRs, которые соответствуют типу запроса и, возможно, CNAME RRs. Обратите внимание, что это означает, что ответы на некоторые запросы могут стать пустыми (NODATA), если хост соответствует правилу dnsrewrite.

Сокращённый синтаксис:

$dnsrewrite=1.2.3.4
$dnsrewrite=abcd::1234
$dnsrewrite=example.net
$dnsrewrite=REFUSED

Ключевые слова должны быть написаны ЗАГЛАВНЫМИ буквами (например, NOERROR). Перезапись ключевых слов получает приоритет над предыдущими, результатом будет пустой ответ с соответствующим кодом.

Полный синтаксис использует форму RCODE;RRTYPE;VALUE:

$dnsrewrite=NOERROR;A;1.2.3.4
$dnsrewrite=NOERROR;AAAA;abcd::1234
$dnsrewrite=NOERROR;CNAME;example.net
$dnsrewrite=REFUSED;;

У модификатора $dnsrewrite с кодом ответа NOERROR также могут быть пустые поля RRTYPE и VALUE.

Модификатор CNAME особенный, поскольку AdGuard Home будет резолвить хост и добавит его информацию к ответу. Так будет происходить, если у домена example.net будет IP-адрес 1.2.3.4, а у пользователя в правилах фильтрации указано следующее:

||example.com^$dnsrewrite=example.net
! Или:
||example.com^$dnsrewrite=NOERROR;CNAME;example.net

в таком случае ответ будет выглядеть примерно так:

nslookup example.com my.adguard.local
Server: my.adguard.local
Address: 127.0.0.1#53

Non-authoritative answer:
example.com canonical name = example.net.
Name: example.net
Address: 1.2.3.4

Далее идёт перезапись CNAME. После этого все значения других записей суммируются в один ответ, таким образом это:

||example.com^$dnsrewrite=NOERROR;A;1.2.3.4
||example.com^$dnsrewrite=NOERROR;A;1.2.3.5

получит ответ с двумя записями A.

В данный момент поддерживаются подобные ресурсные записи:

  • ||4.3.2.1.in-addr.arpa^$dnsrewrite=NOERROR;PTR;example.net. добавляет запись PTR для обратного DNS. Обратные DNS-запросы на 1.2.3.4 к DNS-серверу получат результат example.net.

    ВНИМАНИЕ: IP ДОЛЖЕН быть указан в обратном порядке. См. RFC 1035.

  • ||example.com^$dnsrewrite=NOERROR;A;1.2.3.4 добавляет запись A со значением 1.2.3.4.

  • ||example.com^$dnsrewrite=NOERROR;AAAA;abcd::1234 добавляет запись AAAA со значением abcd::1234.

  • ||example.com^$dnsrewrite=NOERROR;CNAME;example.org добавляет запись CNAME. Выше объяснение, почему так.

  • ||example.com^$dnsrewrite=NOERROR;HTTPS;32 example.com alpn=h3 добавляет запись HTTPS. Поддерживается только подмножество значений параметров: значения должны быть смежными и, там, где ожидался список значений, только одно значение поддерживается:

    ipv4hint=127.0.0.1             // Поддерживается.
    ipv4hint="127.0.0.1" // Не поддерживается.
    ipv4hint=127.0.0.1,127.0.0.2 // Не поддерживается.
    ipv4hint="127.0.0.1,127.0.0.2" // Не поддерживается.

    В будущем это изменится.

  • ||example.com^$dnsrewrite=NOERROR;MX;32 example.mail добавляет запись MX с порядковым номером 32 и доменным именем почтового сервера example.mail.

  • ||example.com^$dnsrewrite=NOERROR;SVCB;32 example.com alpn=h3 добавляет значение SVCB. Посмотрите на пример HTTPS выше.

  • ||example.com^$dnsrewrite=NOERROR;TXT;hello_world добавляет запись TXT со значением hello_world.

  • ||_svctype._tcp.example.com^$dnsrewrite=NOERROR;SRV;10 60 8080 example.com добавляет запись SRV с приоритетным значением 10, значением веса 60, портом 8080 и целевым значением example.com.

  • ||example.com^$dnsrewrite=NXDOMAIN;; отвечает кодом NXDOMAIN.

  • $dnstype=AAAA,denyallow=example.org,dnsrewrite=NOERROR;; отвечает пустым NOERROR значением для всех запросов AAAA, кроме запросов к example.org.

Правила исключений разблокируют одно или все правила:

  • @@||example.com^$dnsrewrite разблокирует все правила перезаписи DNS.

  • @@||example.com^$dnsrewrite=1.2.3.4 разблокирует правило перезаписи DNS, которое добавляет запись A со значением 1.2.3.4.

important

Модификатор important, применённый к правилу, повышает его приоритет по отношению к любому другому правилу без модификатора. Даже относительно базовых правил-исключений.

Примеры:

  • В этом примере:

    ||example.org^$important
    @@||example.org^

    ||example.org^$important заблокирует все запросы к *.example.org, кроме правила исключения.

  • В этом примере:

    ||example.org^$important
    @@||example.org^$important

    правило исключения также содержит модификатор important, поэтому правило сработает.

badfilter

Правила с модификатором badfilter отключают другие базовые правила, на которые они ссылаются. Это означает, что текст отключённого правила должен совпадать с текстом правила badfilter (без модификатора badfilter).

Примеры:

  • ||example.com$badfilter отменяет ||example.com.

  • @@||example.org^$badfilter отменяет @@||example.org^.

    Обратите внимание: модификатор badfilter не работает с правилами /etc/hosts. 127.0.0.1 example.org$badfilter не отменяет оригинальное правило 127.0.0.1 example.org.

ctag

Модификатор ctag может быть использован только в AdGuard Home.

Он позволяет блокировать домены только для определённых типов тегов DNS-клиентов. Вы можете присвоить теги клиентам в пользовательском интерфейсе AdGuard Home. В будущем, мы планируем автоматически присваивать теги после анализа поведения каждого клиента.

Синтаксис:

$ctag=value1|value2|...

Если один из клиентских тегов совпадает со значениями ctag, то это правило применяется к клиенту. Синтаксис для исключения:

$ctag=~value1|~value2|...

Если один из клиентских тегов совпадает со значениями исключения ctag, то это правило не применяется к клиенту.

Примеры:

  • ||example.org^$ctag=device_pc|device_phone: блокировать example.org для тегов device_pc или device_phone.

  • ||example.org^$ctag=~device_phone: блокировать example.org для всех тегов, кроме device_phone.

Список разрешённых тегов:

  • По типу устройства:

    • device_audio: аудио устройства.
    • device_camera: фотоаппараты.
    • device_gameconsole: игровые консоли.
    • device_laptop: ноутбуки.
    • device_nas: системы NAS (сетевые хранилища).
    • device_pc: ПК.
    • device_phone: телефоны.
    • device_printer: принтеры.
    • device_securityalarm: системы сигнализации.
    • device_tablet: планшеты.
    • device_tv: телевизоры.
    • device_other: другие устройства.
  • По операционной системе:

    • os_android: Android.
    • os_ios: iOS.
    • os_linux: Linux.
    • os_macos: macOS.
    • os_windows: Windows.
    • os_other: другие операционные системы.
  • По группам пользователей:

    • user_admin: администраторы.
    • user_regular: рядовые пользователи.
    • user_child: дети.

синтаксис в стиле /etc/hosts

Для каждого хоста должна быть строка со следующей информацией:

IP_address canonical_hostname [aliases...]

Поля для ввода данных разделены любым количеством пробелов или символов табуляции. Текст от знака # до конца строки — это комментарий, он игнорируется.

Имена хостов могут содержать только буквенно-численные значения, дефис-минусы (-) и точки (.). Они должны начинаться буквенным значением и заканчиваться буквенно-численным. Дополнительные псевдонимы предлагаются со сменой названий, альтернативным написанием, укороченными или универсальными именами хостов (например, localhost).

Пример:

# Это комментарий
127.0.0.1 example.org example.info
127.0.0.1 example.com
127.0.0.1 example.net # это тоже комментарий

В AdGuard Home IP-адреса используются для ответа на DNS-запросы по этим доменам. В приватном AdGuard DNS эти адреса просто блокируются.

Синтаксис только для доменов

Простое перечисление имён доменов, по одному в линию.

Пример:

# Это комментарий
example.com
example.org
example.net # это тоже комментарий

Если в строке указан недействительный домен (например *.example.org), AdGuard Home посчитает его правилом в стиле Adblock.

Компилятор хостлистов

Если вы поддерживаете список блокировки и используете в нём разные источники, Компилятор хостлистов может быть вам полезен. Этот инструмент упрощает составление hosts-списка блокировки, совместимого с AdGuard Home, приватным AdGuard DNS или любым другим продуктом AdGuard с DNS-фильтрацией.

Что он может сделать:

  1. Собрать единый список блокировки из разных источников.

  2. Исключить правила, которые вам не нужны.

  3. Подчистить список, получившийся в результате: убрать дубли, неработающие правила и сжать список.