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

Вы правильно сделали, что отключили “strict_route”, про нее мало информации в документации, в моём понимании она нужна в тех случаях, когда sing-box используется в качестве клиента на конечных устройствах типа Android для предотвращения утечек IP. Когда sing-box выступает в роли шлюза для других хостов, её нужно отключать, иначе ничего работать не будет.

Окей, спасибо :slight_smile: ip_is_private установил да. Ещё почитаю подробнее справку по sing-box на тему маршрутов и DNS, всё руки не доходили, видимо пора.

It works! :slight_smile:

Если кому интересно, на доисторической Raspberry Pi 1B все это работает далеко от идеала, но работает. Железо в ней очень слабое, и если в режиме прокси в sing-box все выглядит пристойно, то более тяжелый tun просаживает скорость по speedtest до 6,5 - 8 Mbps, и даже банальный веб-серфинг становится довольно тормозным. Но потом вспомнил, что можно активировать разгон через sudo raspi-config. В режиме Turbo тормоза уходят, а speedtest выдает уже 12,5 Mbps. Youtube в статистике для сисадминов почему-то показывает чуть более высокую скорость и работает хорошо вплоть до 1440p@60fps (но 4K уже нет). Температура не поднимается выше 55 градусов (без радиатора).

В /etc/sysctl.conf прописал:

net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv4.ip_forward = 1

Конфиг для sing-box в итоге такой (домены для обхода блокировок взял из файла russia-youtube.txt в архиве с GoodbyeDPI). Логи отключил, чтобы лишний раз не дергать карту памяти.

{
	"log": {
		"disabled": true,
		"level": "warn",
		"output": "/tmp/sing-box.log",
		"timestamp": true
	},
	"dns": {
		"servers": [
			{
				"tag": "google",
				"address": "https://8.8.8.8/dns-query"
			},
			{
				"tag": "local",
				"address": "192.168.1.1",
				"detour": "direct"
			},
			{
			"tag": "block",
			"address": "rcode://success"
			}
		],
		"strategy": "ipv4_only"
	},
	"inbounds": [
		{
			"type": "tun",
			"interface_name": "tun0",
			"domain_strategy": "ipv4_only",
			"inet4_address": "172.16.250.1/30",
			"mtu": 9000,
			"auto_route": true,
			"strict_route": false,
			"sniff": true,
			"sniff_override_destination": true
		}
	],
	"outbounds": [
		{
			"type": "vless",
			"tag": "vless-out",
			"server": "IP_ADDRESS",
			"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"
		},
		{
			"type": "direct",
			"tag": "direct"
		},
		{
			"type": "block",
			"tag": "block"
		},
			{
			"type": "dns",
			"tag": "dns-out"
		}
	],
	"route": {
		"rules": [
			{
				"protocol": "dns",
				"outbound": "dns-out"
			},
			{
                "ip_is_private": true,
                "outbound": "direct"
            },
			{
                "domain_suffix": ".youtube.com",
                "outbound": "vless-out"
            },
			{
                "domain_suffix": ".youtu.be",
                "outbound": "vless-out"
            },
			{
                "domain_suffix": ".ytimg.com",
                "outbound": "vless-out"
            },
			{
                "domain_suffix": ".googlevideo.com",
                "outbound": "vless-out"
            }
		],
	"final": "direct",
	"auto_detect_interface": true
	}
}

Обращу внимание на директиву "final": "direct" в секции route, без нее весь трафик пойдет на удаленный сервер, а нам это не нужно. Еще я пытался вынести домены в отдельный файл, чтобы не вводить для каждого новую секцию в конфиге (хотя вот сейчас дошло, что секцию можно оставить одну, а суффиксы вписать массивом, но все равно хотелось бы вынести их из конфига в отдельный файл). И я даже успешно создал srs файл через

sing-box rule-set compile [--output <file-name>.srs] <file-name>.json

Но пока так и не понял, как этот srs файл подключить в конфиг. Пытался через rule_set, но видимо неправильно, потому что sing-box наотрез отказывается запускаться, и в логах почему-то пусто (хотя были включены). Если кто-то знает, пожалуйста подскажите.

для большей производительности добавь в tun

"gso": true

или можно перейти на iptables redirect, сделать его нетрудно:

{
  "type": "redirect",
  "tag": "redirect-in",
  "listen": "0.0.0.0",
  "listen_port": 100
}
iptables -t nat -A PREROUTING -s tv_ip/32 -p tcp -j REDIRECT --to-port 100

Правильно будет вот так:
Содержимое youtube.json файла с правилами:

{
    "version": 1,
    "rules": [
        {
            "domain_suffix": [
                ".googlevideo.com",
                ".youtube.com",
                ".ggpht.com",
                ".ytimg.com",
                ".googleapis.com",
                ".youtu.be"
            ]
        }
    ]
}

Подключение его в правилах конфига:

    "route": {
        "auto_detect_interface": true,
        "final": "direct",
        "rules": [
            {
                "protocol": "dns",
                "outbound": "dns-out"
            },
            {
                "ip_is_private": true,
                "outbound": "direct"
            },
            {
                "rule_set": "youtube",
                "outbound": "vless-out"
            }
        ],
        "rule_set": [
            {
                "tag": "youtube",
                "type": "local",
                "format": "source",
                "path": "/etc/sing-box/rule-set/youtube.json"
            }
        ]

Если сконвертили в .srs через sing-box rule-set compile, то тогда "format": "binary"
Правда .srs скорее нужно для оптимизации огромных наборов правил, вроде списков antizapret с миллионом строк, как у этого товарища - GitHub - savely-krasovsky/antizapret-sing-box: Пример конфига

@MasterYoba а, значит я просто одно лишнее правило добавлял. Попробую как вы сказали, спасибо.

Это кстати пробовал, но заметных изменений не дало. Возможно, потому что ethtool -k eth0 выдаёт generic-segmentation-offload: off [requested on], принудительно включить не удалось.

Вообще любопытно. Если правильно понял, inbound типа redirect слушает на 100 порту, на который мы переводим запросы с ТВ. Спасибо, попробую так сделать.

Здравствуйте! А подскажите может есть успешные кейсы с Docker контейнером?

У меня есть хост докера, у него есть macvlan я этому контейнеру прописываю статический айпишник в локальной сети:
versi

on: "3.8"
services:
  sing-box:
    image: ghcr.io/sagernet/sing-box
    container_name: sing-box
    restart: always
    volumes:
      - $PWD/:/etc/sing-box/
    command: -D /var/lib/sing-box -C /etc/sing-box/ run
    networks:
      macnet8:
        ipv4_address: 192.168.50.6
    cap_add:
      - NET_ADMIN
    devices:
      - /dev/net/tun
networks:
  macnet8:
    external: true

Конфиг уже использую практически полностью такой же как финальный у xofamim548

Вроде всё запускается, в логах чисто:

+0000 2024-08-08 17:03:01 INFO router: updated default interface eth0, index 406
+0000 2024-08-08 17:03:01 INFO inbound/tun[0]: started at tun0
+0000 2024-08-08 17:03:01 INFO sing-box started (0.00s)

Но когда у себя указываю в качестве дефолт гейтвея этот контейнер, то у меня всё умирает, никакого интернета нет. Что-то уже не знаю куда копать)) Собираюсь доставать физическую распбери уже))

попробуйте

sysctl -w net.ipv4.conf.default.rp_filter=0
sysctl -w net.ipv4.conf.all.rp_filter=0
sysctl -w net.ipv4.ip_forward=1

Поменял, запустил контейнер в привилегированном режиме, но картина та же. В логах пустота…

У меня такого опыта именно с docker macvlan не было, если команды @0ka не помогут, я бы попробовал посмотреть через tcpdump -v, что происходит с трафиком внутри контейнера, что он не попадает в петлю и не дропается например. Как вариант, попробовать добавить в контейнер второй интерфейс с маршрутом default, чтобы трафик от устройств заходил в один интерфейс (который будет их шлюзом), а выходил в интернет через другой.

Бросил докер, убил на него уже часов 5, достал распберри 4, но не могу даже простой роутинг что-то настроить, или туплю или там ещё что-то нужно сделать кроме как включить:
net.ipv4.ip_forward = 1

Чтобы просто без впн через него трафик хотя бы начал ходить?

После этого выполнить (если ещё не)
sudo sysctl -p
и возможно
sudo systemctl restart NetworkManager.

По идее больше ничего. После этого указываете малину как шлюз, в качестве DNS роутер или 8.8.8.8. У меня работает так.

Странно но дело было в DNS. Но теперь ютуб просто какими-то скачками работает))) как буто супер ускоренный

Скачками это в смысле немного потормозит и резко раздупляется?) На youtube включите статистику для сисадминов, посмотрите что там с буферизацией происходит. И на малине посмотрите что происходит в htop. По идее в качестве шлюза она вообще без проблем должна работать.

На телевизоре нормально показывает в 4к, на компе что-то стало с буферизацией как будто сразу на несколько секунд вперед прыгает, но я ещё изучу! Спасибо всем за помощь! Кстати, в докере тоже заработало, когда DNS прописал. Но блин когда я просто пинговать пробовал по адресу, а не по имени никакого пинга не проходило. На компе от браузера зависит, в хроме большой дроп кадров, в сафари нет звука, при этом на телеке нормально и изображение и звук

Бегло потестировал с ПК - работает! Нагрузка значительно меньше, чем в режиме tun, видео в 4k летают. Прямо вау.

Чот какой-то был глюк уже на замученном компе походу с ютубом. Сейчас перезагрузился и через докер нормально показывает 4к!

Эх… сколько нам открытий чудных) Здорово! Надо будет тоже попробовать

Я выше оставил в команде только tcp, и если вы убрали tun, то udp трафик (quic) будет идти напрямую. Но можно заблокировать udp (reject) на 443 порту чтобы не работал quic, тогда будет еще меньше нагрузка на железо

Все работает, большое спасибо!