Ник Пост Дата
jubilantWhiting1

Друзья, нужен реверсный прокси-сервер для UDP. То, что делает ssh-опция -R, только для UDP. Я как не старался, найти не смог.

Дополнительным бонусом была бы возможность прикидываться каким-нибудь “легитимным” протоколом, например, dtls, ну, или хотя бы просто XOR с ключом. Ну, или “настоящий” dtls реверс-прокси.

Именно реверс, а не прямой нужен из-за того, что целевая машина находится за NAT.

2022-07-01T10:39:25.135Z
vanyaindigo

Shadowsocks не подходит?

2022-07-01T16:32:34.477Z
jubilantWhiting1

Я не нашёл такого функционала в shadowsocks. Не подскажете, как именно это сделать?

Ну, и вы же сами спрашивали два года назад, и выяснялось, что обфускации тоже нет:

2022-07-02T07:26:32.816Z
vanyaindigo

Вам шашечки или ехать? С обфускацией UDP сейчас нигде нет вроде бы.

2022-07-02T07:59:45.603Z
jubilantWhiting1

Обфускация – это не шашечки, это иногда очень нужно.

Но даже если считать её “шашечками”, всё равно shadowsocks не умеет обратное проксирование, только прямое.

2022-07-02T08:19:29.048Z
ValdikSS

Какую вы решаете задачу? Почему ищете именно реверс-прокси, а не хотите применить стандартные методы, вроде VPN?
VPN идеально подходит для вашей задачи.

2022-07-02T17:40:06.359Z
soloway(Solo Way)

Задача выглядит тривиальной. Это примерно уровень университетской лабораторной работы. Кажется будет проблемно найти готовое решение промышленного качества. Впрочем, несложно сделать самому или нанять кого-нибудь.

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

Не совсем понятно что вы понимаете под обратным прокси применительно к UDP. В соединениях UDP стороны практически равнозначны. Просто два узла попеременно шлют друг другу дейтаграммы. Нет состояний, рукопожатий и прочего. Конечно, для того чтобы временно открыть на прием порт через NAT необходимо чтобы самую первую дейтаграмму отправил узел за NAT. Так же стоит учитывать то, что NAT автоматически закроет порт через 1…2 минуты если в течение этого срока не будет получено входящих дейтаграм.

Здесь можно найти нескольколько простых примеров работы через UDP: UDP/datagram sockets | Node.js v18.4.0 Documentation

2022-07-02T21:34:13.568Z
jubilantWhiting1
  1. VPN и есть задача, которую я решаю.
  2. Мой VPN-сервер за NAT’ом, машина – это релей.
  3. Для прохождения NAT нужен реверс-прокси.
  4. Обфускация нужна, чтобы провайдер релея не забанил.
  5. UDP нужен, потому что TCP-VPN это дрянь.

VPN идеально подходит для вашей задачи.

Я не хочу гонять VPN-over-VPN, и я не хочу держать сервер VPN на релее.

2022-07-03T02:19:41.411Z
jubilantWhiting1

Задача выглядит тривиальной.

Вы готовы за неё взяться? Сколько это будет стоить? Более конкретно, вы готовы добавить опцию -R и/или DTLS в UDPspeeder?

2022-07-03T02:23:29.156Z
szq4

https://securesocketfunneling.github.io/ssf/

2022-07-03T05:45:56.162Z
jubilantWhiting1

ssf туннелирует через tls, а не dtls, то есть, через tcp. Не годится.

2022-07-03T05:48:50.147Z
soloway(Solo Way)

Вряд ли у нас что-то получится. Но если будут вопросы, конечно, обращайтесь.

2022-07-03T23:17:21.920Z
ValdikSS

В таком случае, как вы представляете архитектуру реверс-прокси для UDP без установки какой-либо программы и на релее, и на сервере? Чем это принципиально отличается от установки какого-либо туннеля (хоть fou) и на релее, и на сервере?

Мне кажется, у вас проблема проблема XY: вы описываете не задачу, а ваше видение её решения.

2022-07-04T11:38:13.474Z
jubilantWhiting1

В таком случае, как вы представляете архитектуру реверс-прокси для UDP без установки какой-либо программы и на релее, и на сервере?

Почему без установки? На релее устанавливается сервер udp-ssh-R и открывает два слушающих сокета (один для клиента udp-ssh-R, один для входящих соединений), на VPN-машине клиент udp-ssh-R, и раз в 2 минуты шлёт на релей keepalive. При подключении к сокету на релее, он принимает “коннект”, и пересылает пакет udp-ssh-R клиенту (за NAT), и тот уже подключается к слушающему сокету VPN-процесса.

Естественно, нужен ещё и сервер прямого прокси на релее, например, тот же самый shadowsocks, который будет деобфусцировать входящее соединение с клиента.

Что на релее не делается, это не создаётся нового VPN-интерфейса, не хранится ценных (более-менее) приватных ключей, и не производится лишних хопов маршрутизации. И с MTU меньше трудностей.

Чем это принципиально отличается от установки какого-либо туннеля (хоть fou) и на релее, и на сервере?

Я не знаю, как работает fou. Спасибо за наводку, я почитаю. Хотя беглым взглядом я не вижу, как это должно работать.

2022-07-04T15:45:46.505Z
soloway(Solo Way)

Но куда релей должен отправлять ответ сервера, если сервер не знает и, соответственно, не сообщает адрес клиента, а на релей, допустим, пришло пять клиентов? Все-таки нужен или VPN или в более общем виде программа-мультиплексор умеющая передавать несколько UDP-соединений через одно. VPN проще. Я бы попытался прикрутить wireguard. Там каждый узел может работать и как клиент и как сервер для разных подключений. Ваш серевер может установить соединение с релеем как клиент, а уже через него принимать подключения клиентов (не раскрывая при этом ключи). Не пробовал такую схему, но вроде должно работать.

Если клиенты подклчаются через shadowsocks, то может быть проще проксировать необработанный shadowsocks через релей?

2022-07-05T22:01:45.153Z
jubilantWhiting1

Но куда релей должен отправлять ответ сервера, если сервер не знает и, соответственно, не сообщает адрес клиента, а на релей, допустим, пришло пять клиентов?

У меня всего один клиент, мне достаточно одного.

Все-таки нужен или VPN или в более общем виде программа-мультиплексор умеющая передавать несколько UDP-соединений через одно.

Как ssh передаёт? Вот так же и передавать. Да, видимо, добавлять свой заголовок к пакету, а может быть, вообще если два маленьких пакета пришло, уложившись в буфер, упаковывать их в один UDP пакет, а на сервере распаковывать.

VPN проще. Я бы попытался прикрутить wireguard. Там каждый узел может работать и как клиент и как сервер для разных подключений.

Это не проще. Это VPN-over-VPN, лишний хоп маршрутизации, лишний интерфейс на сервере, лишние айпи в файрволе, проблемы с MTU. Собственно, сейчас оно так и работает, только VPN это ssh-VPN.

Ваш серевер может установить соединение с релеем как клиент, а уже через него принимать подключения клиентов (не раскрывая при этом ключи). Не пробовал такую схему, но вроде должно работать.

Работать будет, но хочется более прямолинейного решения. Собственно, таким решением мог бы являться socat, но socat не сохраняет границы пакетов, из-за чего половина пакетов не проходит.

2022-07-06T04:29:06.566Z
ValdikSS

В таком случае, если IP-адреса клиента и сервера заранее известны (если у вас стационарный клиент) и NAT не симметричный, вы можете установить соединение без релея, отправляя UDP-пакеты в обе стороны с фиксированными портами. OpenVPN, например, можно настроить в таком режиме: задайте port и lport фиксированными и на клиенте, и на сервере.
Если адрес клиента или сервера заранее не известен, но клиент всё ещё стационарный и NAT не симметричный, можете использовать ваш релей-сервер для их согласования.

Если у вас нет ограничений на ОС/протокол, то попробуйте, например, weron — это VPN поверх WebRTC (DTLS), с «пробивом» NAT. Или, например, tinc, или zerotier, или tailscale.

Софт для UDP reverse proxy мне неизвестен. Ближе всего в этому был бы v2fly, но он не поддерживает режим reverse proxy на UDP-порт, а только на TCP-сервисы (хоть и трафик туннелировать может через UDP, например, через QUIC).
Не зная, чего в действительности вы хотите добиться, посоветовать вам что-то обстоятельно не представляется возможности — вы не рассказываете о задаче.

2022-07-06T08:52:25.352Z
jubilantWhiting1

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

Reverse UDP прокси, такой же как ssh -R, только для udp, сохраняющий границы пакетов при доставке.

weron tinc zerotier, tailscale.

Я ещё раз поковыряюсь со всем этим, но для тупого проксирования UDP это все кажется оверкиллом.

2022-07-06T09:16:40.106Z
ValdikSS

Простой рабочий вариант для одного клиента, с OpenVPN.

На стороне релея:

  1. Скомпилировать GitHub - TLINDEN/udpxd: A general purpose UDP relay/port forwarder/proxy
  2. Запустить: ./udpxd -l 0.0.0.0:1194 -b 0.0.0.0:12498 -t 1.1.1.1:1194, где 1.1.1.1 — IP-адрес сервера.

На стороне сервера (за несимметричным NAT):

  1. Запустить OpenVPN на порту 1194 UDP
  2. Запустить sudo nping --udp -g 1194 -p 12498 2.2.2.2 -c1, где 2.2.2.2 — IP-адрес relay-сервера.

Готово. Клиент может подключаться к 2.2.2.2:1194. Команду с nping нужно выполнять каждые пару минут при отсутствии клиента. Также в OpenVPN следует настроить keepalive на 30-40 секунд.
Обфускации в этом способе нет, установка дополнительного ПО на VPN-сервер не требуется.

2022-07-06T10:02:34.405Z
ValdikSS

Это опять не похоже на задачу, а на ваше видение её решения. Ранее вы говорили о VPN. Вы хотите соеденить двух клиентов VPN, оба из которых находятся за NAT? В таком случае, рассмотрите VPN-решения, упомянутые выше, они позволят это сделать без промежуточного сервера.

2022-07-06T10:18:56.253Z
jubilantWhiting1

Это опять не похоже на задачу, а на ваше видение её решения.

ssh -R – это тоже метод решения, а не проблема. Почему вас удивляет, что я хочу удочку, а не рыбу? Ну сегодня мне нужно пробрасывать VPN, завтра форварднуть порт для RTMP сервера для стримов, послезавтра пробросить QUIC.

Зачем полагаться на отдельные костыли, которые в каждом конкретном случае могут и работать, но все вместе будут требовать ежедневного внимания, потому что будут постоянно ломаться? grep придуман в 70е годы, и будет работать пока существуют текстовые файлы. Wireguard послезавтра умрёт, потому что в chacha-poly найдут бэкдор от NSA, а OpenVPN Inc завтра разорится и перестанет выпускать свой продукт. А туннели UDP будут даже при повсеместном внедрении ipv6, потому что файрволы всё равно в том или ином виде будут.

2022-07-07T09:59:55.503Z
ValdikSS

Меня это не удивляет: я бы и сам хотел видеть такую программу, потому что у неё есть применения, а описанные вами недостатки VPN-туннелей верны.
Только программа с такой функциональностью мне неизвестна, а поиск не выдаёт ничего подобного: встречаются реверс-прокси с поддержкой UDP, но без туннелирования сквозь NAT.

Поэтому остаётся предлагать только альтернативные решения вашей задачи, предполагая, что она заключается в подключении к VPN-серверу за NAT.

2022-07-07T10:23:25.413Z
ValdikSS

Похоже, нашел программу, удовлетворяющую требованиям: это юзерспейсный клиент/сервер WireGuard: GitHub - aramperes/onetun: User space WireGuard proxy in Rust

2022-07-17T17:09:18.620Z
jubilantWhiting1

Спасибо, посмотрю.

Хотя если кто-нибудь хочет сделать настоящий реверс-прокси для UDP, то предложение согласовать требования и заплатить всё ещё в силе.

2022-07-18T03:32:02.040Z
jubilantWhiting1

Кажется, я нашёл ещё более прямолинейное решение. GitHub - 2xsaiko/udptun: Multi-socket UDP tunnel

На релее:

udptun --listen 42.42.42.42:53 --entry 127.0.0.1:10000

На машине за NAT:

udptun --remote 42.42.42.42:53 --target 127.0.0.1:10000

И, кажется, должно пробрасывать порт 10000 с релея на машину за NAT.
Минусы – нет ни обфускации, ни шифрования, ни даже авторизации. То есть, man-in-the-middle может прикинуться машиной за NAT, и начать получать пакеты, предназначенные для сервиса за NAT. Также ничего не написано про keepalive.

Но в любом случае, пример неплохой, мысли автора шли в нужном направлении. Быть может быть, добавить реализацию AEAD PSK не так и сложно окажется.

2022-11-20T13:46:26.912Z