Skip to content

TUN — sing-box

Входящий TUN в sing-box — каноническая реализация TUN в мире Go: большинство других реализаций (в mihomo, Clash-Meta и прочих) производны от неё. Входящий создаёт TUN-устройство, разбирает сырые пакеты в системном стеке или в стеке gVisor и передаёт полученные соединения движку маршрутизации.

Входящий

type: "tun":

ПолеТипПо умолчаниюДопустимые значенияОписание
interface_namestring(auto)<interface name>Имя TUN-устройства. Пустое значение выбирает вариант ОС по умолчанию (`tun0`, `utun5` и т. п.).
mtuuint329000<bytes>MTU устройства. 9000 — значение по умолчанию в sing-box; высокое, чтобы амортизировать накладные расходы на пакеты.
addressbadoption.Listable[netip.Prefix][]<CIDR>Адреса интерфейса (обычно один IPv4 + один IPv6). Заменяет устаревшую пару `inet4_address` / `inet6_address`.
auto_routeboolfalsetrue | falseАвтоматически устанавливать маршруты ОС, направляющие весь трафик в TUN-устройство.
iproute2_table_indexint2022<int>Индекс таблицы iproute2 в Linux, используемый `auto_route`.
iproute2_rule_indexint9000<int>Индекс правила iproute2 в Linux.
auto_redirectboolfalsetrue | falseАвтоперенаправление через NFTables в Linux — заводит трафик в TUN без изменения маршрутов. Быстрее auto_route на горячих loopback-путях.
auto_redirect_input_markFwMark0<uint32>fwmark, применяемый к пакетам, направляемым в TUN.
auto_redirect_output_markFwMark0<uint32>fwmark, применяемый к пакетам, выходящим из TUN.
auto_redirect_reset_markFwMark0<uint32>fwmark, снимаемый после обработки.
auto_redirect_nfqueueuint160<uint16>Номер NFQUEUE для пути автоперенаправления.
auto_redirect_iproute2_fallback_rule_indexint0<int>Резервный индекс правила, когда автоперенаправление не удаётся установить.
exclude_mptcpboolfalsetrue | falseПропускать MPTCP-потоки (оставлять им обычный путь через ядро).
loopback_addressbadoption.Listable[netip.Addr][]<IP>Адреса, считающиеся loopback (не маршрутизируются через TUN).
strict_routeboolfalsetrue | falseБлокировать утечку трафика в обход TUN-устройства (DROP-правила на границе маршрута по умолчанию).
route_addressbadoption.Listable[netip.Prefix][]<CIDR>При включённом `auto_route` маршрутизировать через TUN только эти CIDR. По умолчанию маршрутизируется всё.
route_address_setbadoption.Listable[string][]<rule-set tag>Маршрутизировать по IP-CIDR-записям набора правил вместо явного списка.
route_exclude_addressbadoption.Listable[netip.Prefix][]<CIDR>CIDR, оставляемые на интерфейсе по умолчанию (запасной выход).
route_exclude_address_setbadoption.Listable[string][]<rule-set tag>Исключение на основе набора правил.
include_interfacebadoption.Listable[string][]<interface>Подключаться только к этим интерфейсам (мобильные устройства с несколькими NIC).
exclude_interfacebadoption.Listable[string][]<interface>Исключить эти интерфейсы.
include_uidbadoption.Listable[uint32][]<uid>Включение по UID в Linux/macOS.
include_uid_rangebadoption.Listable[string][]<from:to>Включение по диапазону UID.
exclude_uidbadoption.Listable[uint32][]<uid>Исключение по UID.
exclude_uid_rangebadoption.Listable[string][]<from:to>Исключение по диапазону UID.
include_android_userbadoption.Listable[int][]<user id>Включение по пользователям Android (мультипользовательский режим).
include_packagebadoption.Listable[string][]<package name>Включение по пакетам Android.
exclude_packagebadoption.Listable[string][]<package name>Исключение по пакетам Android.
udp_timeoutUDPTimeoutCompat5m<duration or seconds>Тайм-аут простоя для UDP-потоков.
stackstringmixedsystem | gvisor | mixedРеализация стека TCP/IP. `system` использует сетевой стек ядра; `gvisor` — стек в пользовательском пространстве; `mixed` использует системный стек для TCP и gVisor для UDP.
platform*TunPlatformOptions(unset)TunPlatformOptionsПлатформенно-специфичные переопределения (сейчас только `http_proxy`).
gsoboolDeprecated: removed
inet4_addressbadoption.Listable[netip.Prefix]Deprecated: merged to Address
inet6_addressbadoption.Listable[netip.Prefix]Deprecated: merged to Address
inet4_route_addressbadoption.Listable[netip.Prefix]Deprecated: merged to RouteAddress
inet6_route_addressbadoption.Listable[netip.Prefix]Deprecated: merged to RouteAddress
inet4_route_exclude_addressbadoption.Listable[netip.Prefix]Deprecated: merged to RouteExcludeAddress
inet6_route_exclude_addressbadoption.Listable[netip.Prefix]Deprecated: merged to RouteExcludeAddress
endpoint_independent_natboolDeprecated: removed

Исходный код: option/tun.go:13-63 · зафиксировано на v1.13.15 (3708fa1)

Структура также встраивает InboundOptions (sniff, sniff_override_dest, domain_strategy и т. д.).

Выбор стека

  • system — нативный TCP/IP ядра. Самый быстрый. Требует, чтобы ОС предоставляла нужные TUN-ioctl (Linux: да; macOS: utun — да; Windows: wintun через DLL).
  • gvisor — TCP/IP-стек Google в пользовательском пространстве. Медленнее, но переносим; единственный вариант на платформах без хорошей поддержки TUN в ядре.
  • mixed — системный стек для TCP (пропускная способность уровня ядра на самом нагруженном пути), gVisor для UDP. Значение по умолчанию и то, что нужно большинству пользователей.

Модели маршрутизации

TUN в sing-box поддерживает два подхода к маршрутизации:

  1. auto_route: true (кроссплатформенный). Устанавливает маршруты ОС, направляющие весь трафик в TUN. В Linux использует индексы таблицы и правил iproute2. На macOS выполняет route add. В Windows программирует таблицу маршрутизации напрямую.

  2. auto_redirect: true (только Linux). Устанавливает правила перенаправления NFTables вместо изменения маршрутов. Быстрее на горячих loopback-путях, потому что нет лишнего перехода. Требует nft и соответствующих модулей ядра.

strict_route: true добавляет DROP-правила на окружающем интерфейсе, чтобы предотвратить утечку трафика в обход TUN, — важно для семантики kill switch.

Примеры

Стандартная настольная конфигурация (Linux/macOS):

json
{
  "inbounds": [{
    "type": "tun",
    "tag": "tun-in",
    "interface_name": "sing-tun",
    "mtu": 9000,
    "address": ["172.16.0.1/30", "fdfe:dcba:9876::1/126"],
    "auto_route": true,
    "strict_route": true,
    "stack": "mixed",
    "sniff": true,
    "sniff_override_dest": true
  }],
  "route": {
    "auto_detect_interface": true,
    "rules": [
      { "action": "sniff" },
      { "protocol": "dns", "action": "hijack-dns" },
      { "ip_is_private": true, "outbound": "direct" }
    ],
    "final": "proxy"
  }
}

Фильтрация приложений Android — проксировать только перечисленные пакеты:

json
{
  "inbounds": [{
    "type": "tun",
    "interface_name": "tun0",
    "mtu": 9000,
    "address": ["172.16.0.1/30"],
    "auto_route": true,
    "stack": "system",
    "include_package": ["com.netflix.mediaclient", "com.spotify.music"]
  }]
}

Linux с автоперенаправлением NFTables (предпочтительнее auto-route на нагруженных хостах):

json
{
  "inbounds": [{
    "type": "tun",
    "auto_redirect": true,
    "auto_redirect_input_mark": "0x100",
    "auto_redirect_output_mark": "0x200",
    "address": ["172.16.0.1/30"]
  }]
}

Примечания

  • Раньше address был двумя полями (inet4_address / inet6_address). Оба всё ещё разбираются, но выдают предупреждения об устаревании — в конфигурациях следует использовать новый объединённый список address.
  • endpoint_independent_nat удалён. Вместо этого задавайте его в действии правила маршрутизации (через udp_disable_domain_unmapping).
  • gso удалён — GSO ядра определяется автоматически.
  • auto_route и auto_redirect взаимоисключимы. Выберите что-то одно.
  • strict_route в Linux использует NFTables, когда он доступен, и откатывается на iptables. Оба варианта требуют root.

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

  • Xray-core имеет минимальный входящий TUN — без auto-route, без перехвата DNS, без фильтрации приложений. См. TUN — Xray-core.
  • mihomo имеет практически идентичный набор возможностей в блоке верхнего уровня tun:, с именами полей в kebab-case и дополнительным списком dns-hijack. См. TUN — mihomo.

Исходный код: option/tun.go:13-63 · v1.13.15 (3708fa1)

Core Tutorial от Argsment