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 и т. п.).
netnsstring(unset)<network namespace tag / name / path>Только Linux. Создаёт TUN-интерфейс внутри этого сетевого пространства имён — тег из верхнеуровневого network_namespaces либо имя или путь пространства имён. Тогда auto_route / auto_redirect работают внутри него, и root не нужен, если пространство имён принадлежит текущему пользователю. Конфликтует с platform.
mtuuint3265535<bytes>MTU устройства. Если не задан: 65535, на Android — 9000, внутри Apple Network Extension — 4064.
addressbadoption.Listable[netip.Prefix][]<CIDR>Адреса интерфейса (обычно один IPv4 + один IPv6). Старые поля inet4_address / inet6_address отклоняются при запуске.
dns_modestringhijackdisabled | native | hijackКак обрабатывается DNS на TUN-интерфейсе. native задаёт нативный DNS интерфейса платформы (systemd-resolved в Linux, DNS на интерфейс в Windows / Apple); hijack (по умолчанию) дополнительно перехватывает трафик порта 53 — правилом iproute2 в Linux, nftables-DNAT на dns_address при auto_redirect, фильтром WFP в Windows при strict_route; disabled не делает ни того, ни другого.
dns_addressbadoption.Listable[netip.Addr](derived from address)<IP>Адрес(а) DNS-сервера для dns_mode. Если не задано, для каждого семейства берётся следующий IP после первого элемента address, и соединения к нему автоматически перехватываются в DNS-модуль (как правило hijack-dns). Если задано, автоперехват отключается — при необходимости добавьте явное правило маршрутизации hijack-dns.
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.
include_mac_addressbadoption.Listable[string][]<MAC address>Только Linux при включённых auto_route и auto_redirect. Маршрутизировать только трафик с этих MAC-адресов источника (например, LAN-устройства на роутере). Конфликтует с exclude_mac_address.
exclude_mac_addressbadoption.Listable[string][]<MAC address>Только Linux при включённых auto_route и auto_redirect. Исключить эти MAC-адреса источника. Конфликтует с include_mac_address.
udp_timeoutUDPTimeoutCompat5m<duration or seconds>Тайм-аут простоя для UDP-потоков.
udp_mappingUDPNATBehaviorendpoint_independentendpoint_independent | address_dependent | address_and_port_dependentСопоставление UDP NAT: одно сопоставление на адрес и порт источника для всех назначений (по умолчанию) либо отдельное для каждого адреса назначения / адреса и порта.
udp_filteringUDPNATBehaviorendpoint_independentendpoint_independent | address_dependent | address_and_port_dependentФильтрация UDP NAT: принимать пакеты от любого удалённого узла (по умолчанию) либо только от адресов / пар адрес-порт, куда уже отправлялись пакеты.
udp_nat_maxuint320 (auto)<uint32>Максимум сессий UDP NAT; при достижении лимита закрывается дольше всех не использовавшаяся. 0 — это 4096 на iOS, на других платформах от 4096 до 16384 в зависимости от объёма памяти (16384, если его не удалось определить).
stackstring(mixed / system)system | gvisor | mixedРеализация стека TCP/IP. system использует сетевой стек ядра; gvisor — стек в пользовательском пространстве; mixed использует системный стек для TCP и gVisor для UDP. По умолчанию mixed при сборке с gVisor, иначе system.
platform*TunPlatformOptions(unset)TunPlatformOptionsПлатформенно-специфичные переопределения (сейчас только http_proxy).

Исходный код: option/tun.go:14-72 · зафиксировано на v1.14.2 (af6e64c)

Структура также встраивает 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. Значение по умолчанию в сборках с gVisor (иначе по умолчанию system) и то, что нужно большинству пользователей.

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

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

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

  2. auto_redirect: true (только Linux, поверх auto_route). Добавляет правила nftables, перенаправляющие трафик в sing-box, — лучше маршрутизация и производительность, чем у чистого auto_route или tproxy, нет конфликтов с bridge-сетями Docker и есть автоматическая интеграция с OpenWrt fw4. Требует 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"
  }],
  "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_route": true,
    "auto_redirect": true,
    "auto_redirect_input_mark": "0x100",
    "auto_redirect_output_mark": "0x200",
    "address": ["172.16.0.1/30"]
  }]
}

Примечания ​

  • dns_mode по умолчанию (hijack) меняет состояние системы: sing-box задаёт нативный DNS TUN-интерфейса и устанавливает перехват порта 53. Чтобы не трогать DNS интерфейса и межсетевой экран, задайте "dns_mode": "disabled".
  • Поля inet4_address / inet6_address, их маршрутные варианты inet4_* / inet6_* и gso разбираются, но отклоняются при запуске; в таблице выше они скрыты. Используйте address, route_address и route_exclude_address.
  • Поля входящего, встроенные в эту структуру (sniff, sniff_override_dest, domain_strategy и т. д.), отклоняются при запуске — используйте действия правил маршрутизации sniff / resolve.
  • endpoint_independent_nat разбирается, но игнорируется. Поведение UDP NAT задаётся udp_mapping / udp_filtering (по умолчанию — независимо от конечной точки) и ограничивается udp_nat_max.
  • auto_redirect требует auto_route (только Linux) и конфликтует с route.default_mark и routing_mark уровня соединения.
  • При включённом auto_route strict_route делает неподдерживаемые сети недоступными; в Windows он также предотвращает утечки DNS из-за разрешения имён через несколько интерфейсов. В Linux вместе с auto_redirect он дополнительно направляет трафик SO_BINDTODEVICE через sing-box.

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

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

Исходный код: option/tun.go:14-72 · v1.14.2 (af6e64c)

Core Tutorial от Argsment