Настройка цепочки wireguard+xray

Всех приветствую.

Пытаюсь настроить соединение по такой схеме - http://0x0.st/H_6K.jpg

Смысл такой организации: 1) российская ВПСка хостит “сервер” ваергарда, чтобы обеспечить доступ клиентом (пиров) между собой, в т.ч. подключенных к ней роутеров для доступа к устройствам за роутерами. 2) Настройка маршрутизации основного трафика для всех клиентов сразу делается в одном месте и удобно - на российской ВПСке. 3) Все, что должно идти не на .ru/.рф, идет на зарубежную (NL) ВПСку.

Дано: поднято две ВПС (ру и нл). На ру организован шлюз с ваергард, к нему подключены все нужные клиенты. Для клиентов данный шлюз - основной (0.0.0.0/0 и ::/0). На зарубежной ВПС поднят xray-server, настроенный на работу reality (конфигурация рабочая, пробовал подключаться напрямую с клиентов с помощью nekoray/foxray).
Нужно: правильно организовать редирект основного трафика на зарубежную ВПС через xray через терминал (потому что ГУИ на ВПС не будет).

Что я сделал: скачал xray-core, использовал такой конфиг - http://0x0.st/H_6P.json, поднял клиент на российской ВПСке с этим конфигом. xray не ругался на ошибки. Через ss вижу

ss -tunlp | grep xray
tcp   LISTEN 0      4096       127.0.0.1:10808      0.0.0.0:*    users:(("xray",pid=2522,fd=3))
tcp   LISTEN 0      4096       127.0.0.1:10809      0.0.0.0:*    users:(("xray",pid=2522,fd=7))

Вроде работает. Дальше мне надо как-то перевести весь трафик, который идет от “клиентов” (то есть пиров) ваергард “сервера” (пира-шлюза-российской ВПС) на зарубежную ВПС. Тут две проблемы: 1) как это сделать (пробовал iptables через цепочку прероутинга редиректить весь tcp/udp трафик с ваергард порта на порт 10808/9 - не вышло), 2) как при глобальном редиректе всего трафика фильтровать, куда пускать трафик к .ru/.рф, а куда остальной?

Прошу знатоков подсказать, куда копать.

ПыСы. В nekoray, например, есть некий tun mode, который создает интерфейс и делает его основным. Как это сделать через xray-core с его конфигом я не понял. Судя по всему, это как раз то, что мне нужно.

Во первых, не PREROUTING нужна, а FORWARD на первом сервере во второй.
Во вторых, нужен ipset со списком AS тех адресов, который пойдет в Нидерланды.

@Sofi,

Поясни подробнее, пожалуйста. Не понял, при чем тут форвардинг, если речь идет об перенаправлении трафика с порта wireguard (например, 51820) на порт local proxy xray (10808/10809). ЕЯПП это больше похоже на transparent proxy, для которой должно работать что-то вроде

iptables -t nat -A PREROUTING -p udp --dport 51820 -j REDIRECT --to-port 10808

Но это, очевидно, не работает.

По поводу AS серверов, разве эту задачу не выполняет сам xray? В доках описано, что можно избирательно пускать трафик в обход прокси, если есть совпадения по домену/regexp и т.д. У меня вопрос здесь в том, достаточно ли будет просто завернуть весь входящий трафик российской ВПС, который идет на порт 51820, в прокси, чтобы xray все сам разруливал, или нужны будут доп. действия (какие)?

UPD. Пока разбирался с проблемой перевода трафика на другой порт, оказалось что хотя xray запущен на российской ВПС и не ругается на ошибки, по traceroute весь трафик все равно идет напрямую, а не через прокси на зарубежной ВПС. Видимо, еще в конфиге клиента ошибка.

Насколько я поняла из вашего вопроса, вам нужно форвардить с РФ до Нидерландов тот трафик, который не должен проходить через сервера РФ, разве нет?
То есть при подключении к серверу РФ, трафик, который не попадает под некие правила, должен идти в Нидерланды.
Поправьте, если не права.
Насчёт прозрачного прокси - это не так, в вашем случае, правило другое:
iptables -t nat -A OUTPUT -p $tcp/udp --dport $port -j REDIRECT --to-ports $port
Чтобы работало в PREROUTING как прозрачный прокси, правило должно быть другим:
iptables -t mangle -A PREROUTING -j TPROXY --tproxy-mark $mark

Конкретнее задачу опишите, пожалуйста.

Я плохо объяснил. Исправляюсь.

Есть российская ВПС. У нее две задачи: 1) с помощью wireguard объединить в одну сеть множество устройств, чтобы можно было общаться между устройствами, 2) быть шлюзом для выхода в интернет с помощью xray (это важно, что это не просто шлюз, а именно шлюз через xray).

Шлюз через xray работает следующим образом. На российской ВПС стоит клиент (xray-core) с конфигом, который я публиковал в первом посте (который, судя по всему не работает). На зарубежной ВПС развернут xray-server с xtls-reality в качестве основного способа работы.

Сейчас у меня два вопроса: 1) как весь трафик от пиров wireguard, для который российская ВПС - шлюз для выхода в интерент, завернуть в xray (в локальный прокси, который открывается на порту 10808 или 10809, 2) как без GUI, то есть средствами только xray-core из терминала по ssh подключить российскую ВПС к зарубежной ВПС так, чтобы трафик, который идет от пиров wireguard и от самой российской ВПС шел по правилам, заданным в конфиге xray-core клиента, т.е. все, что идет на домены *.рф и *.ru - идет в обход прокси (НЕ через зарубежную ВПС), а весь остальной трафик только через зарубежную ВПС (то есть через xray xtls-reality сервер).

Сама маршрутизация по доменам осуществляется xray. Для меня не понятно, как это происходит через режим прокси.

redsocks
Заворот ip трафика на прокси работает лишь для tcp.
Я бы очень хорошо подумал, прежде чем связываться с прокси. Не лучше ли пробросить нормально через тоннель ip ?
Вариантов множество. Хоть тот же wireguard+ipobfs с уродованием IP фреймов, благо у ВПСок внешний ип есть. Нестандартный IP протокол и транспортный хедер, не похожий ни на что.
Это невозможно через NAT, требует рута, сложно, так что у цензоров руки еще не скоро доберутся (надеюсь)

Что касается доменов, то как вы собираетесь их распознавать и по ним принимать решение ? Это возможно для http, теоретически можно выдернуть SNI из ClientHello, то есть сделать для https, но что со всем остальным делать ?
К тому же домен никак не связан с местоположением сервера. Может все же geoip ?

Поднимается redsocks или подобный прокси.
В конфиге указывается порт и адреса с которого и на который будет идти редирект, затем правилом выше перекидываете трафик пиров на этот порт:
iptables -t nat -A PREROUTING -p udp --dport $wg_port -j REDIRECT --to-ports $proxy_port

По второму вопросу:
Без понятия что из себя вообще представляет x-ray.
В случае соединения двух vps, достаточно прокинуть туннель через тот же wg, а для пиров исключить вторую vps из правил маршрутизации для РФ.
P. S. Пропишите адрес шлюза на первой vps как адрес порта редиректа для прокси на который перенаправляете пиров.

пользуйся sing-box вместо xray, он поддерживает tun, в который весь wg трафик пойдёт без проблем, конфиг дам если надо. Протокол лучше используй ss, а не vless/vless/trojan т.к. он поддерживает udp, а не делает конвертацию в TCP (это медленно). Если к этому еще приделать rule по доменам, то сервак понадобится не слабый т.к. маршрутизировать будет sing-box (медленно)

Нужно использовать inbound dokodemo-door с соответствующими iptables/nftables-правилами.

Настройка не отличается от просто настройки v2fly/xray в качестве прокси-сервера/клиента. Только учтите, что это всё ещё прокси: вы сможете туннелировать только TCP/UDP-трафик, не сможете принимать входящие подключения, могут быть проблемы с VoIP/WebRTC.

В вашем конфигурационном файле нет правил на маршрутизации (routing → rules) через удалённый сервер.

geosite — специальный список IP-диапазонов или доменов. Вряд ли в вашей базе существует список ru. Если вы хотите маршрутизировать все диапазоны IP-адресов, закреплённые за Россией, нужно использовать routing → rules → "ip": ["geoip:ru"], если домены: "domains": ["domain:ru"] (все домены, заканчивающиеся на .ru).
Чтобы маршрутизация по доменам работала, в inbound нужно включить sniffing.
Обратите внимание, что директива (по крайней мере, в v2fly) называется domains, а не domain. Возможно, у вас ошибка.

Привет! Я вижу ты крутой спец, помоги пожалуйста с настройкой wireguard разобраться, заранее спасибо!

в плане? что нужно?

0ka буду признателен, если поделитесь примером конфига.
Задача один в один, как описывает топикстартер.
Сразу пошел по варианту tun интерфейса.
Подключение до заморской локации установлено успешно, по статическим маршрутам доступ к отдельным ресурсам есть.
Но как грамотно прокинуть клиентов WG RU до Xray NL сервера, через tun интерфейс, понять не могу.
Через дефолтный шлюз, WG клиенты в Интернет выходят без проблем.
Sing-box

{
    "log": {
        "level": "debug"
    },
    "inbounds": [
        {
            "type": "tun",
            "interface_name": "tun0",
            "domain_strategy": "ipv4_only",
            "inet4_address": "172.16.0.1/30",
            "stack": "gvisor",
            "endpoint_independent_nat": true,
            "auto_route": false,
            "strict_route": false,
            "sniff": true
        }
    ],
    "outbounds": [
        {
            "type": "vless",
            "server": "***",
            "server_port": 443,
            "uuid": "***",
            "flow": "xtls-rprx-vision",
            "network": "tcp",
            "tls": {
                "enabled": true,
                "disable_sni": false,
                "server_name": "www.nvidia.com",
                "insecure": false,
                "utls": {
                    "enabled": true,
                    "fingerprint": ""
                },
                "reality": {
                    "enabled": true,
                    "public_key": "***",
                    "short_id": "***"
                }
            }
        }
    ],
    "route": {
              "auto_detect_interface": true
            }
}

iptabels (выход через дефолтный шлюз)

*filter
-I FORWARD -i wg+ -j ACCEPT
COMMIT
*nat
-A POSTROUTING -o eth0 -j MASQUERADE
COMMIT

ip

2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc fq_codel state UP group default qlen 1000
    link/ether 00:16:5b:c1:b4:fd brd ff:ff:ff:ff:ff:ff
    altname enp0s3
    altname ens3
    inet 1.2.3.4/32 brd 1.2.3.253 scope global eth0
       valid_lft forever preferred_lft forever
    inet6 fe80::216:5bff:fec1:b4fd/64 scope link
       valid_lft forever preferred_lft forever
4: wg0: <POINTOPOINT,NOARP,UP,LOWER_UP> mtu 1420 qdisc noqueue state UNKNOWN group default qlen 1000
    link/none
    inet 172.17.0.1/24 scope global wg0
       valid_lft forever preferred_lft forever
49: tun0: <POINTOPOINT,MULTICAST,NOARP,UP,LOWER_UP> mtu 9000 qdisc fq_codel state UNKNOWN group default qlen 500
    link/none
    inet 172.16.0.1/30 brd 172.16.0.3 scope global tun0
       valid_lft forever preferred_lft forever
    inet6 fe80::d3cd:ff75:7334:8ddb/64 scope link stable-privacy
       valid_lft forever preferred_lft forever

route (прописан маршрут до 2ip.ru, все работает, вижу IP NL сервера)

Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
default         5.6.7.8      0.0.0.0         UG    0      0        0 eth0
5.6.7.8      0.0.0.0         255.255.255.255 UH    0      0        0 eth0
172.16.0.0      0.0.0.0         255.255.255.252 U     0      0        0 tun0
172.17.0.0      0.0.0.0         255.255.255.0   U     0      0        0 wg0
static.35.201.2 172.16.0.1      255.255.255.255 UGH   0      0        0 tun0

@Gamber если я равильно понял вас, то должно работать так:
Добавьте правило
-A POSTROUTING -s 172.17.0.0/24 -o tun0 -j MASQUERADE

Тогда клиенты должны видеть на сайте 2ip адрес NL сервера.
А это -I FORWARD -i wg+ -j ACCEPT можно убрать, если у вас глобально ACCEPT стоит.

попробуйте так

echo "5 sing-rt" >> /etc/iproute2/rt_tables #создаем новую таблицу маршрутов

ip route add default dev tun0 table sing-rt #добавляем шлюз sing-box в новую таблицу

ip rule add from 172.17.0.0/24 table sing-rt #добавляем правило: для source addr 172.17.0.0/24 (wg subnet) использовать новую таблицу маршрутов

iptables -t nat -A POSTROUTING -o tun0 -j MASQUERADE #

и проверка на сервере через

curl -v --interface wg0 2ip.ru

это всё без гарантий т.к. проверить не могу, если последняя команда фейлит то проверяйте на клиенте

https://serverfault.com/a/1073566

0ka khammatov Благодарю, все получилось.
0ka Во второй строчке небольшая опечатка, нужно tun0.
А так все ok, взлетело.
Dhohbr именно так и пробовал первоначально.
Как оказалась, вся изюминка именно в отдельной таблице маршрутов )

Наверное, не буду поднимать новую тему, так как это, по сути, продолжение истории.

После успешного тестирования вышеописанной связки на стороннем RU VPS, решил поднять его непосредственно у себя.

Дано:

Две локации в RU. На обеих Микротики в качестве маршрутизаторов.

Локация 1. За NAT провайдера.

Локация 2. Публичная статика.

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

В LAN Локации 2 поднят сервер на Debian, на котором развернут Sing-Box клиент, смотрящий в зарубежный NL сервер.

По конфигу клиента все в целом так же, только в Inbound включен auto_route.

В iptables, NAT на LAN интерфейсе сервера.

Клиент успешно поднимается, curl 2ip.ru отдает зарубежный IP. Дополнительных таблиц маршрутизации не создаю.

На роутере в Локации 1 поднят GRE туннель в Локацию 2 на Debain сервер. GRE добавлен в NAT, по BGP получаю список заблокированных подсетей в роуты, в качестве шлюза задаю IP GRE интерфейса на стороне Debian. Тут вопросов нет, все работает как нужно.

Проблемы начинаются в Локации 2. Первое, что я попытался сделать, повторить схему, реализованную в первой локации. Создал на Debian еще один GRE интерфейс, поднял туннель с роутером, добавил туннель на роутере в NAT, прописал маршруты до GRE Debian сервера. Вот с NAT и начинаются проблемы, первые пару минут все работает (хосты в LAN успешно ходят куда нужно через NL), но потом я вижу, как NAT правило для GRE начинает генерировать огромное количество трафика, процесс клиента Sing-Box уходит в 100% загрузку и падает. Есть стойкое подозрение, что получилась у меня петля или нечто подобное.

Попробовал выйти из ситуации так. Убрал GRE и NAT, в маршруты BGP прописал IP LAN интерфейса Debian сервера. Работает, но есть ощущение, что криво. При подключении с рабочего ПК к заблокированному ресурсу, есть явная и ощутимая задержка около 5-7 секунд. Если заменить в настройках сетевого адаптера шлюз с LAN IP роутера на LAN IP Debian сервера, все начинает работать адекватно.

Дайте пожалуйста совет, как наиболее грамотно выйти из этой ситуации?