Пытаюсь понять, как работает xray туннелирование в режиме с tun интерфейсом. Понятно, что поднимается локальный прокси, но мне интересно, какими способами xray добивается того, что весь трафик идёт через tun интерфейс, а не через физический. Первое предположение - это указание шлюзом по умолчанию этот самый tun, но вбив ip route со включенном туннелированием я увидел следующее:
default via 192.168.0.1 dev wlo1 proto dhcp src 192.168.0.106 metric 600
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 linkdown
172.18.0.0/30 dev tun0 proto kernel scope link src 172.18.0.1
172.18.0.0/16 dev br-67cf890c8ff5 proto kernel scope link src 172.18.0.1 linkdown
192.168.0.0/24 dev wlo1 proto kernel scope link src 192.168.0.106 metric 600
Но это конечно мэйн таблица, поэтому я полез в правила маршрутизации:
0: from all lookup local
9000: from all to 172.18.0.0/30 lookup 2022
9001: from all lookup 2022 suppress_prefixlength 0
9002: not from all dport 53 lookup main suppress_prefixlength 0
9002: from all iif tun0 goto 9010
9003: not from all iif lo lookup 2022
9003: from 0.0.0.0 iif lo lookup 2022
9003: from 172.18.0.0/30 iif lo lookup 2022
9010: from all nop
32766: from all lookup main
32767: from all lookup default
Содержимое таблицы 2022:
default via 172.18.0.2 dev tun0
Но тут я не совсем понял, исходя из моих познаний в сетях, пакет, проходясь по всем этим правилам, должен был все равно остановиться на правиле с приоритетом 32766, ибо единственный роут в таблице 2022 - это шлюзовый, следовательно все правила с suppress_prefixlength 0 будут скипаться, а все остальные не подходят, так как адреса источника в большей части запросов не в сети 172.18.0.0/30 и не 0.0.0.0 . Можете подсказать, что я понял не так?
ip rule show не показывает все селекторы. not from all скрывает uidrange или fwmark — то правило 9003 на деле что-то вроде not uidrange 1000-1000 iif lo lookup 2022, то есть весь локальный трафик кроме процесса xray уходит в 2022 → tun0. Сам xray свой трафик выводит через физический интерфейс напрямую (sockopt.interface в конфиге), поэтому loop не случается. ip -j rule show | python3 -m json.tool покажет все поля включая скрытые.
Да, чисто — значит не uidrange. Глянь iptables: iptables-save | grep -E "mark|TPROXY" — xray скорее всего перехватывает через mangle/TPROXY, а не через ip rule.