Raspberry Pi + xray между роутером и телевизором

Есть VPS с настроенным vless reality.
В доме стоит роутер, на который openwrt встанет со скрипом, и уж точно без поддержки проксирования через vless.
Есть телевизор Samsung, на котором хочется смотреть youtube.
И есть лежащая без дела Raspberry Pi ранних ревизий, к которой есть парочка совместимых wifi usb адаптеров.

Напрашивается такая схема:
Роутер --(ethernet)-- Raspberry Pi --(usb wifi)-- Телевизор

Попробовал накатить последнюю Raspbian, подключил к роутеру кабелем (wifi пока не трогал), установил xray-core в режиме клиента для vless, в inbound listen прописал 0.0.0.0:1080. То есть xray-core создаёт прокси-сервер на порту 1080, всё что к нему подключается — заворачивается в vless. Потестировал с компа через FoxyProxy — работает на удивление неплохо, 4K поток тянет без проблем, особо не греется даже.

Но дальше я не понимаю, как настроить связку с телевизором. Подключил usb wifi адаптер к малине. Не прошло и года, как поднял точку доступа на wlan0 через NetworkManager, прописал

sudo iptables -t nat -A POSTROUTING -o eth0 -j MASQUERADE

и нормально, устройства подключаются к малине по wifi и получают доступ в интернет. Но у меня вообще никак не получается завернуть трафик в прокси, вот совсем. Гуглом ничего подходящего не нашёл, chatgpt говорит что-то про redsocks и/или разные правила в iptables — в лучшем случае эти предложения ничего не делают, а в худшем ломают подключение.

Может, кто-то посоветует, как лучше сделать? Может, кто-то уже делал подобное? Ещё видел, что для малины есть openwrt - не будет ли проще использовать этот вариант? (Никогда не пользовался openwrt и не знаю, позволит ли она реализовать задуманное.)

https://kubuntu.ru/nat-iptables

Возможно туплю, поправьте если так. Но по ссылке вроде говорится о том, что у меня уже работает, а именно раздача интернета на другие устройства, которые подключаются к wi-fi точке доступа (ну, в моём случае к ней). POSTROUTING в iptables прописан, net.ipv4.ip_forward = 1 тоже включил. Интернет раздаётся, всё окей.

Только я не могу понять, как мне вот этот раздаваемый интернет завернуть в socks5 на порту 1080. Есть ощущение, что вот так напрямую это нельзя сделать, но я не понимаю, как можно и куда смотреть. Пробовал поменять на http и прописать системный прокси для http и https через raspi-config. После этого curl с малины начинает работать через vless, но подключенные устройства по-прежнему работают в обход прокси. Не понимаю, как этот момент настроить.

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

Может лучше поднять вместо x-ray поставить sing-box. Он может поднимать интерфейс, а не как прокси работать. И уже между ними пересылку делать.

Об этом не думал, спасибо, завтра будет время почитаю об этом подробнее. Но думаю вы правы, что мой подход с xray-core и прокси изначально дурацкий :grinning:

Наверно проще использовать какой-нибудь VPN.
Если прям xray нужен, можно через tun2socks завернуть его в tun интерфейс, и с ним уже настраивать маршрутизацию.

Тебе нужно маркировать весь трафик и заворачивать его часть с помощью tproxy на inbound dokodemo-door в xray.
Почитать про это можно здесь, на русском Прозрачное проксирование TProxy (ipv4 и ipv6) | Project X и здесь, на китайском 透明代理(TPROXY) | 新 V2Ray 白话文指南

Честно говоря, ваша схема подключения довольно странная. Я решительно не понимаю, зачем тут usb wifi адаптер, и зачем подключать телевизор именно физически через Raspberry? Все ведь решается простыми сетевыми настройками на уровне L3.
Я бы сделал так: Raspberry подключен к роутер по ethernet, телевизор тоже подключен к роутеру любым способом (ethernet/wifi). Далее пошагово:

  1. Сносите с Raspberry xray-core и ставите sing-box. Это гораздо более производительный клиент/сервер, и обладает очень богатым функционалом. И что немаловажно, имеет качественную документацию на английском языке (Client - sing-box).
  2. Настраиваете конфиг sing-box. В интернете полно примеров, можно гуглить sing-box example config, если настраивали xray-core думаю разберётесь. В Inbounds создаёте инбаунд типа tun, обязательно с опцией “auto_route”: true. В outbounds ваш конфиг vless reality по сути такой же, как в xray. В Route создаёте правила, что именно вы хотите завернуть в туннель, например для телевизора рекомендую завернуть только “domain_suffix” = “.googlevideo.com”. Этого будет достаточно, чтобы вылечить ютуб. Но можно завернуть и весь трафик, только будьте осторожны с российскими стриминговыми сервисами, если пользуетесь ими! И обязательно опцию “auto_detect_interface”: true, без неё работать не будет у вас!
  3. В настройках телевизора вы ставите шлюз по умолчанию = ip адрес Raspberry.
    Итог: трафик с телевизора роутится на Raspberry, попадает на tun интерфейс, далее либо заворачивается sing-boxом в vless туннель и идёт на роутер и далее в интернет, либо просто сразу на роутер и в интернет напрямую, в зависимости от правил в разделе Routes.

У меня в целом похожая схема дома реализована, только вместо Raspberry классическая x86 платформа, и заворачиваю я туда трафик с избранных устройств не через шлюз по умолчанию, а отдельным маршрутом на маршрутизаторе. А в sing-box я использую список всех заблоченных РКН доменов, то есть проксирую только “запрещенку”. Если интересно, могу потом рассказать подробнее.

Интересно, может быть, сделаете отдельную подробную статью?

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

На телевизоре есть поддержка прокси ⇒ настроить HTTP-прокси-сервер на компьютере/Raspberry (xray input), настроить прокси на телевизоре.

На телевизоре нет поддержки прокси, хочется обойтись только отдельными программами

  1. настроить беспротокольный прокси-порт (в v2ray называется dokodemo-door) на компьютере/Raspberry на портах 80 и 443, в нём настроить sniffing трафика (определение домена/IP-адреса из содержимого запроса, а не из метаданных подключения)
  2. настроить DNS-сервер на компьютере/raspberry с отдачей IP-адреса компьютера/raspberry для доменов, которые необходимо проксировать (возможно, DNS можно поднять и средствами xray/v2ray, но не уверен)
  3. указать IP-адрес компьютера/rasbperry в качестве DNS-сервера на телевизоре

// Обход блокировки YouTube для любых Smart TV с GoodbyeDPI + V2ray + MaraDNS

На телевизоре нет поддержки прокси и VPN ⇒ настраивать компьютер/raspberry как шлюз, как пишет @MasterYoba. Можно сделать на компьютере в виртуальной машине с Linux, отдельное устройство не обязательно.

На телевизоре нет поддержки прокси, есть поддержка VPN (любого протокола)

  1. настроить VPN-сервер для этого протокола на компьютере/raspberry
  2. настроить перенаправление трафика на беспротокольный прокси-порт (dokodemo-door) v2ray/xray с VPN-интерфейса
  3. настроить телевизор на VPN-подключение к компьютеру/raspberry

Преимущество перед настройкой шлюзом (способ выше) только в удобстве настройки/соединения/разъединения VPN-подключения.

См. описание реализации VPN-подхода: hoogmoon-testing/TECH.md at master · ValdikSS/hoogmoon-testing · GitHub
Файлы: hoogmoon-testing/build/files/etc/v2ray at master · ValdikSS/hoogmoon-testing · GitHub — там много всего дополнительного, но как пример подобной настройки, надеюсь, будет полезно.

Приветствую @ValdikSS и @MasterYoba , благодарю за подробные ответы!

На всякий случай уточню, что телевизор не поддерживает VPN и вот это всё. Настройки ограничены вот этим списком (картинка из интернета, но у меня так же).
samsung-ip-settings

Если я правильно понял идею, нужно просто подключить Raspberry Pi кабелем к роутеру и не городить из него точку доступа, а использовать малину как шлюз в настройках телевизора. Это дельная мысль, она не пришла мне в голову потому что я нуб и всегда всё усложняю :grinning: Вечером попробую настроить sing-box под это дело.

Окей, вот я на свежей raspbian os прописал net.ipv4.ip_forward=1, телевизор нормально использует малину в качестве шлюза и ходит в интернет. Больше ничего не делал.

sing-box поставил, правда не без приключений. Raspberry Pi 1B это armv6, а в репозитории sagernet видимо только для v7. Долго думал, почему процесс вылетает со status=4/ILL сразу после запуска, но в итоге собрал из исходников, всё запускается.

Сейчас проблема в том, что сразу после sudo systemctl start sing-box я теряю связь с малиной по SSH, и как шлюз она тоже отваливается на подключенных устройствах. Пробовал добавлять direct маршруты в routes для локальных IP или для 22 порта, но то ли я неправильно добавляю, то ли дело не в маршрутах. При log level=“debug” в логе только это (в systemd тоже ничего интересного):

+0300 2024-08-06 22:45:09 INFO router: updated default interface eth0, index 2
+0300 2024-08-06 22:45:09 INFO inbound/tun[tun-in]: started at tun0
+0300 2024-08-06 22:45:09 INFO sing-box started (0.100s)

Вопросы:

  1. Всё ли верно в конфиге из того, что заполнено помимо routes?
  2. Что прописывать в routes для базового тестирования? Я имею в виду, пусть он вообще всё, кроме локальных маршрутов, заворачивает в туннель, для наглядности. Если заработает, то пропишу для отдельных доменов.
  3. Что-то ещё нужно делать, помимо конфигурации sing-box?
{
	"log": {
		"disabled": false,
		"level": "warn",
		"output": "/tmp/sing-box.log",
		"timestamp": true
	},
	"dns": {
		"servers": [
			{
				"tag": "google",
				"address": "tls://8.8.8.8"
			},
			{
			"tag": "block",
			"address": "rcode://success"
			}
		],
		"final": "google",
		"strategy": "ipv4_only"
	},
	"inbounds": [
		{
			"type": "tun",
			"tag": "tun-in",
			"interface_name": "tun0",
			"stack": "system",
			"inet4_address": "172.19.16.1/30",
			"auto_route": true,
			"strict_route": true,
			"sniff": true
		}
	],
	"outbounds": [
		{
			"type": "vless",
			"tag": "vless-out",
			"server": "IP_ADDR",
			"server_port": 443,
			"uuid": "UUID",
			"flow": "xtls-rprx-vision",
			"network": "tcp",
			"tls": {
				"enabled": true,
				"server_name": "DOMAIN_NAME",
				"alpn": ["h2"],
				"utls": {
					"enabled": true,
					"fingerprint": "chrome"
				},
				"reality": {
					"enabled": true,
					"public_key": "PUBLIC_KEY",
					"short_id": "SHORT_ID"
				}
			},
			"packet_encoding": "xudp"
		},
		{
			"type": "direct",
			"tag": "direct"
		},
		{
			"type": "block",
			"tag": "block"
		},
			{
			"type": "dns",
			"tag": "dns-out"
		}
	],
	"route": {
		"rules": [
			{
				"protocol": "dns",
				"outbound": "dns-out"
			}
		],
	"auto_detect_interface": true
	}
}

Я брал конфиг из этой статьи и все взлетело Поднимаем на OpenWrt клиент прокси VLESS, Shadowsocks, Shadowsocks2022. Настройка sing-box и tun2socks | ITDog.info

Отключите авто роутинг в конфиге и работайте с отдельной таблицей маршрутов (rt_tables), добавьте в неё вручную default route dev singbox_tun, и затем ip rule add from tv_ip/32 table second_route_table

Пример команд после запуска singbox
ip route add default tun0 table 100
ip rule add from 192.168.1.100/32 table 100

Можно попробовать, но в свете последних тестов не уверен, что в этом есть смысл, вроде бы можно настроить и через sing-box. Слегка измененный минималистичный конфиг по ссылкам от @Texsis действительно работает, хотя и своеобразно. Некоторые сайты показывают удалённый IP, а некоторые домашний.

{
  "log": {
    "disabled": false,
    "level": "debug",
    "output": "/tmp/sing-box.log",
    "timestamp": true
  },
  "inbounds": [
    {
      "type": "tun",
      "interface_name": "tun0",
      "domain_strategy": "ipv4_only",
      "inet4_address": "172.16.250.1/30",
      "auto_route": true,
      "strict_route": false,
      "sniff": true
    }
  ],
  "outbounds": [
    {
      "type": "vless",
      "tag": "vless-out",
      "server": "IP_ADDR",
      "server_port": 443,
      "uuid": "UUID",
      "flow": "xtls-rprx-vision",
      "network": "tcp",
      "tls": {
        "enabled": true,
        "server_name": "DOMAIN",
        "alpn": [
          "h2"
        ],
        "utls": {
          "enabled": true,
          "fingerprint": "chrome"
        },
        "reality": {
          "enabled": true,
          "public_key": "PUBLIC_KEY",
          "short_id": "SHORT_ID"
        }
      },
      "packet_encoding": "xudp"
    }
  ],
  "route": {
    "auto_detect_interface": true
  }
}

Опытным путём выяснил, что всё падает, если задать "strict_route": true. Буду разбираться дальше.

Перезагрузите тв, возможно в кеше остался старый маршрут для некоторых айпи адресов

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

По поводу strict_route не особо понимаю, насколько нужна эта опция. В справке вижу вот это:

Всё равно не понимаю :slight_smile: Это описание того, что оно делает, или описание того, что я должен сделать, чтобы оно работало? И насколько вообще нужно включать эту опцию? Под Windows для всех клиентов обычно советуют включать, но здесь не знаю. auto_route у меня таки включен.

Сейчас у вас всё идёт по умолчанию в первый по списку outbound - vless-out. Добавьте в rules такое правило, чтобы направить локальный трафик мимо прокси:

            {
                "ip_is_private": true,
                "outbound": "direct"
            }

auto_route отключать не обязательно, на машине с одним интерфейсом, вроде той же малины, с ним будет прекрасно работать. Его отключают обычно, когда настраивают sing-box на роутере, чтобы не мешать работе маршрутизации на нём.