Skip to content

DNS — mihomo

Блок dns: в mihomo большой и плоский. Основная идея: объявить основной список резолверов (nameserver) и резервный список, а затем фильтровать, какие запросы идут в fallback, через fallback-filter. Переопределения по доменам — через nameserver-policy. Опциональный fake-IP-движок для маршрутизации, дружественной к сниффингу.

Верхнеуровневые параметры

ПолеТипПо умолчаниюДопустимые значенияОписание
enableboolfalsetrue | falseГлавный переключатель. При false остальная часть блока игнорируется и используется резолвер ОС.
prefer-h3boolfalsetrue | falseПредпочитать DNS-over-HTTPS/3 (поверх QUIC), когда URL сервера поддерживает и H2, и H3.
ipv6boolfalsetrue | falseРазрешать AAAA-записи. При false выполняются только A-запросы.
ipv6-timeoutuint100<milliseconds>Максимальное время ожидания AAAA-ответа перед откатом на только-IPv4. Документированное значение по умолчанию — 100 мс.
use-hostsboolfalsetrue | falseСначала сверяться с верхнеуровневым отображением `hosts:`, прежде чем идти в сеть.
use-system-hostsboolfalsetrue | falseДополнительно сверяться с файлом hosts ОС (`/etc/hosts`).
respect-rulesboolfalsetrue | falseПрогонять **правила маршрутизации** и по самим DNS-запросам. При true исходящий для запроса выбирается списком правил — удобно, чтобы направить DNS-трафик в конкретный туннель.
nameserver[]string[][<URL>]Список основных резолверов. Каждая запись — URL: `udp://...`, `tcp://...`, `tls://...`, `https://...`, `quic://...`, `system://`, `dhcp://<iface>` или `rcode://...`.
fallback[]string[][<URL>]Список резервных резолверов — используется, когда основной ответ отфильтрован `fallback-filter` (например, «домашний» IP в ответе на запрос заграничного домена).
fallback-filterRawFallbackFilter{geoip: true, geoip-code: "CN"}RawFallbackFilterФильтр, решающий, когда обращаться к `fallback`. Содержит `geoip`, `geoip-code`, `ipcidr`, `domain`, `geosite`.
fallback-lazy-queryboolfalsetrue | falseОпрашивать серверы `fallback` лениво: обращаться к ним только после того, как основной ответ отклонён `fallback-filter`, а не гонять их параллельно с `nameserver` на каждом запросе.
listenstring(disabled)<host:port>Если задано, запустить локальный DNS-сервер на этом адресе. Сервер подчиняется тем же правилам, что и внутренний резолвер.
listen-routing-markint0<uint32>Linux SO_MARK (fwmark), устанавливаемый на сокеты DNS-сервера `listen`, чтобы policy routing мог обрабатывать его трафик особо. 0 отключает.
enhanced-modeC.DNSModenormalnormal | redir-host | fake-ipРежим DNS-движка. `normal` возвращает настоящие ответы; `redir-host` возвращает IP, но помечает соединение исходным доменом (для маршрутизации, дружественной к сниффингу); `fake-ip` возвращает синтетические IP из `fake-ip-range`.
fake-ip-rangestring198.18.0.1/16<CIDR>Диапазон IPv4, выделяемый под фиктивные IP (только режим `fake-ip`).
fake-ip-range6string(unset)<CIDR>Опциональный диапазон IPv6.
fake-ip-filter[]string[]<domain pattern>Домены, которые **не** должны получать фиктивный IP — они уходят к настоящему резолверу. Поддерживаются шаблоны.
fake-ip-filter-modeC.FilterModeblacklistblacklist | whitelistЯвляется ли `fake-ip-filter` чёрным списком (отфильтрованные домены минуют fake-ip) или белым (fake-ip получают только отфильтрованные домены).
fake-ip-ttlint1<seconds>TTL в секундах для fake-IP-ответов. Низкие значения заставляют клиентов чаще перезапрашивать, что поддерживает отображение fake-ip свежим.
default-nameserver[]string[114.114.114.114, 223.5.5.5, 8.8.8.8, 1.0.0.1][<URL>]Бутстрап-резолверы, используемые для разрешения имён хостов самих записей в `nameserver`/`fallback`. **Должны** быть чистыми IP — дальнейшее разрешение не допускается.
cache-algorithmstringlrulru | arcАлгоритм вытеснения. `arc` (Adaptive Replacement Cache) иногда лучше для нагрузок со всплесками обращений.
cache-max-sizeint0 (unbounded)<int>Максимальное число кэшируемых записей.
nameserver-policy*orderedmap.OrderedMap[string, any]{}{<domain or rule>: <URL or [URL]>}Маршрутизация по шаблонам доменов. Ключи — шаблоны доменов или нотации `geosite:`/`rule-set:`/`+.`; значения — URL резолверов. Приоритет выше, чем у `nameserver`.
proxy-server-nameserver[]string[][<URL>]Резолверы, используемые **специально** для разрешения имён хостов прокси-серверов. Устраняет проблему курицы и яйца, когда имя прокси маршрутизируется через прокси, который его использует.
proxy-server-nameserver-policy*orderedmap.OrderedMap[string, any]{}{<pattern>: <URL>}Переопределение `proxy-server-nameserver` по шаблонам доменов.
direct-nameserver[]string[][<URL>]Резолверы для назначений, маршрутизируемых как DIRECT. Не даёт «домашним» DNS-запросам утекать через прокси.
direct-nameserver-follow-policyboolfalsetrue | falseПрименять `nameserver-policy` и к запросам `direct-nameserver`.

Исходный код: config/config.go:221-249 · зафиксировано на v1.19.29 (e26714a)

Схемы URL для nameserver

Списки nameserver, fallback, default-nameserver, proxy-server-nameserver и direct-nameserver принимают одну и ту же грамматику URL:

СхемаПримерПримечания
(чистый IP)223.5.5.5UDP/53
udp://udp://8.8.8.8:53Явный UDP, порт опционален
tcp://tcp://8.8.8.8:53DNS-over-TCP
tls://tls://1.1.1.1:853DNS-over-TLS
https://https://doh.pub/dns-queryDNS-over-HTTPS (H2)
quic://quic://dns.adguard-dns.comDNS-over-QUIC
h3://h3://1.1.1.1/dns-queryDoH поверх HTTP/3
system://system://Резолвер ОС
dhcp://dhcp://eth0Резолвер, выданный DHCP на eth0
rcode://rcode://refusedВозвращать фиксированный RCODE

Пути URL после хоста могут нести суффикс #<proxy>, принудительно направляющий DNS-трафик через именованный прокси:

yaml
nameserver:
  - https://cloudflare-dns.com/dns-query#proxy

nameserver-policy

Самое мощное поле. Ключи — сопоставители; значения — URL резолвера или список URL:

yaml
nameserver-policy:
  "geosite:cn,private":           # GeoSite category match
    - 223.5.5.5
    - 114.114.114.114
  "+.cn":                         # Suffix match — note the +. prefix
    - https://doh.pub/dns-query
  "rule-set:cn":                  # Rule-set reference
    - 223.5.5.5
  "www.example.com":              # Exact domain
    - https://example-dns.com/dns-query

nameserver-policy просматривается до основного списка nameserver, поэтому совпавшие домены полностью минуют стандартный резолвер.

fallback-filter

Решает, когда основной ответ «подозрителен» и нужно запросить fallback:

yaml
fallback-filter:
  geoip: true                # Apply GeoIP filtering
  geoip-code: CN             # Treat answers in this country as suspicious-foreign-domain
  ipcidr:
    - 240.0.0.0/4            # Specific CIDR triggers
  geosite:
    - gfw                    # GeoSite categories that must always go to fallback
  domain:
    - +.google.com           # Domain patterns that must always go to fallback

Когда основной ответ совпадает с geoip-code/ipcidr, а домен запроса не совпадает с geosite/domain, результат отклоняется и опрашивается список fallback.

Примеры

Классический DNS с обходом CN:

yaml
dns:
  enable: true
  prefer-h3: true
  enhanced-mode: fake-ip
  fake-ip-range: 198.18.0.1/16
  fake-ip-filter:
    - '+.lan'
    - '+.local'
    - 'localhost.ptlogin2.qq.com'

  default-nameserver:
    - 223.5.5.5
    - 119.29.29.29

  nameserver:
    - https://doh.pub/dns-query
    - https://dns.alidns.com/dns-query

  fallback:
    - https://1.1.1.1/dns-query
    - https://dns.google/dns-query
    - tls://8.8.4.4:853

  fallback-filter:
    geoip: true
    geoip-code: CN
    geosite:
      - gfw

  nameserver-policy:
    'geosite:cn,private':
      - https://doh.pub/dns-query
    'geosite:gfw,geolocation-!cn':
      - https://1.1.1.1/dns-query
      - https://dns.google/dns-query

  proxy-server-nameserver:
    - https://doh.pub/dns-query

  direct-nameserver:
    - https://doh.pub/dns-query

Локальный DNS-сервер для устройств в сети:

yaml
dns:
  enable: true
  listen: 0.0.0.0:53
  enhanced-mode: redir-host
  nameserver:
    - https://1.1.1.1/dns-query

Примечания

  • enhanced-mode: fake-ip — стандартный режим для схем прозрачного прокси. Настоящее разрешение IP происходит на стороне прокси, а не клиента — а значит, правила маршрутизации, знающие о сниффинге, видят исходный домен.
  • default-nameserver должен содержать только чистые IP-адреса. Они используются для разрешения имён хостов в самих nameserver / fallback; имена хостов здесь означали бы циклическую загрузку.
  • fake-ip-filter принимает тот же синтаксис доменных шаблонов, что и правила маршрутизации (+.example.com для суффикса, geosite:apple для категории).
  • proxy-server-nameserver критичен для схем, где имя хоста прокси-сервера одновременно фигурирует в правилах маршрутизации. Без него разрешение имени прокси может рекурсивно попытаться пройти через сам этот прокси.
  • direct-nameserver не даёт запросам для прямых направлений уходить на резервный (заграничный) резолвер. Полезно, когда fallback — ваш единственный нефильтруемый путь.
  • По умолчанию список fallback опрашивается параллельно с nameserver на каждом запросе, и резервный ответ используется, когда основной срабатывает на fallback-filter. fallback-lazy-query: true откладывает резервный запрос до момента, когда основной ответ действительно отклонён — меньше трафика к резервным резолверам ценой дополнительной задержки на отфильтрованных ответах. Имеет значение только при непустом fallback.

Сравнение с другими ядрами

  • Xray-core использует плоский блок с серверами в виде URL-строки или объекта и полями domains / expectedIPs / unexpectedIPs на сервер. См. DNS — Xray-core.
  • sing-box использует типизированные серверы (type: "https", type: "fakeip", …) и структурированную цепочку DNS-правил с явными действиями. См. DNS — sing-box.

Исходный код: config/config.go:221-249 · v1.19.29 (e26714a)

Core Tutorial от Argsment