UDP-трафик через SSH-туннель

66

Название в значительной степени подводит итог. Я хотел бы отправлять трафик UDP через туннель SSH. В частности, мне нужно иметь возможность отправлять UDP-пакеты через туннель и иметь возможность сервера отправлять их мне обратно на другой стороне. Я знаю, как это сделать для TCP-соединений. Это возможно с UDP?

heavyd
источник

Ответы:

36

В этом небольшом руководстве рассказывается, как отправлять UDP-трафик через SSH с помощью инструментов, которые входят в стандартную комплектацию (ssh, nc, mkfifo) с большинством UNIX-подобных операционных систем.

Выполнение туннелирования UDP через соединение SSH

Шаг за шагом Откройте порт пересылки TCP с вашим SSH-соединением

На локальном (локальном) компьютере подключитесь к удаленному компьютеру (серверу) по SSH с дополнительной опцией -L, чтобы SSH с переадресацией порта TCP:

local# ssh -L 6667:localhost:6667 server.foo.com

Это позволит перенаправлять TCP-соединения на порт 6667 вашего локального компьютера на порт 6667 на server.foo.com через защищенный канал. Настройте пересылку TCP на UDP на сервере

На сервере мы открываем прослушиватель на TCP-порту 6667, который перенаправляет данные на UDP-порт 53 указанного IP-адреса. Если вы хотите выполнить переадресацию DNS, как я, вы можете взять первый IP-адрес сервера имен, который вы найдете в /etc/resolv.conf. Но сначала нам нужно создать fifo. FIFO необходим для двусторонней связи между двумя каналами. Простая оболочка передает только стандартный ввод левого процесса «стандартный вывод в правый процесс».

server# mkfifo /tmp/fifo
server# nc -l -p 6667 < /tmp/fifo | nc -u 192.168.1.1 53 > /tmp/fifo

Это позволит перенаправлять трафик TCP через порт 6667 сервера на трафик UDP через порт 53 192.168.1.1 и получать ответы. Настройте переадресацию UDP на TCP на вашем компьютере

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

local# mkfifo /tmp/fifo
local# sudo nc -l -u -p 53 < /tmp/fifo | nc localhost 6667 > /tmp/fifo

Это позволит перенаправлять трафик UDP на порт 53 локальной машины на трафик TCP на порт 6667 локальной машины. Наслаждайтесь вашим локальным DNS-сервером :)

Как вы уже, наверное, догадались, когда DNS-запрос будет выполняться на локальном компьютере, например, на локальном UDP-порту 53, он будет перенаправлен на локальный TCP-порт 6667, затем на TCP-порт сервера 6667, затем на DNS-сервер сервера. UDP-порт 53 из 192.168.1.1. Чтобы пользоваться службами DNS на вашем локальном компьютере, укажите следующую строку в качестве первого сервера имен в вашем /etc/resolv.conf:

nameserver 127.0.0.1
Джон Т
источник
28
Это решение не безопасно. Не гарантируется, что потоки TCP сохраняют границы сообщений, поэтому одна дейтаграмма UDP может быть разделена на части, нарушая любой протокол.
Юхо Остман
2
Также было бы неплохо использовать порт 1153 вместо 6667 (из примера man SSH), который используется IRC.
Фил Пирожков
1
@ JuhoÖstman Спасибо за указание на эту ловушку. Зная о проблеме ... Вы нашли решение? Достаточно ли маленькие сообщения, чтобы заставить его работать?
человечествоANDpeace
4
Решение заключается в добавлении длины каждому пакету до его отправки через поток TCP и восстановлении исходных пакетов из этого. Для этого было бы легко написать C-скрипт, но я не уверен, что существует легкодоступное решение. На практике TCP обычно сохраняет границы сообщений в этом случае, но странные сбои могут возникнуть в любое время.
Юхо Остман
Я столкнулся с еще одной проблемой: труба и fifo буферизуются, поэтому границы кадра теряются. Столько UDP-кадров можно объединить в один TCP-кадр.
Хулио Герра
26

Этот пример (я думаю, что ответ Джона указывает на то же самое в другом месте), описывает, как получить доступ к службам UDP / DNS другого компьютера через соединение TCP / SSH.

Мы будем перенаправлять локальный трафик UDP / 53 в TCP, затем трафик TCP с помощью механизма переадресации портов SSH на другую машину, затем TCP в UDP / 53 на другом конце.
Как правило, вы можете сделать это с openvpn.
Но здесь мы сделаем это с более простыми инструментами, только openssh и netcat.

В конце этой страницы есть еще один комментарий со ссылкой на ' socat'.
Тот же доступ UDP / DNS сделан с помощью,

Сторона сервера: socat tcp4-listen:5353,reuseaddr,fork UDP:nameserver:53
сторона клиента:socat udp4-listen:53,reuseaddr,fork tcp:localhost:5353

См. Примеры сокатов для большего.

Nik
источник
3
Этот кажется мне гораздо более полезным, чем принятый ответ. Мне нужно было однонаправленным перенаправление видеопотока (TS / UDP) ... ssh orig_strm_src socat udp4-listen:4003,reuseaddr,fork STDOUT| socat STDIN udp-sendto:localhost:4003
nhed
FWIW, я написал более подробное руководство на моей домашней странице, описывающее, как настроить socat через SSH для пересылки UDP. Он использует SNMP в качестве примера.
Питер В. Мёрч
20

SSH (по крайней мере, OpenSSH) поддерживает простые VPN. Используя опцию -wили Tunnelв sshклиенте, вы можете создать tunустройство на обоих концах, которое можно использовать для пересылки любого вида IP-трафика. (См. Также Tunnelна странице руководства ssh_config(5).) Обратите внимание, что для этого требуется OpenSSH (и, вероятно, привилегии root) на обоих концах.

grawity
источник
Это требует привилегий суперпользователя на удаленной машине даже для UDP-туннелирования непривилегированных портов, а PermitRootLogin имеет значение «нет». Жаль.
Фил Пирожков
@grawity Спасибо, что указали на эту опцию, которая, даже если филпирожков указал нужную учетную запись root. Интересно, может ли быть способ обмануть его, чтобы он не нуждался в руте?
человечествоANDpeace
4
@humanityANDpeace: вы можете создавать устройства tun / tap и делать их принадлежащими определенному пользователю, используя ip tuntap add.
Гравитация
Привет, @ Grawity. Мне нравится ваше решение, но я не могу заставить его работать. Я подготовил tunустройство следующим образом: sudo ip tuntap add mode tunно когда-либо использовал -wопцию, подобную этой: ssh $Server -w $portя получаю Tunnel device open failed. Could not request tunnel forwarding.Что я делаю не так?
Лукас Аймаретто
16

Или вы можете просто использовать ssf (который был разработан для этого варианта использования) с помощью простой команды:


Сторона клиента:

#>./ssfc -U 53:192.168.1.1:53 server.foo.com

Эта команда перенаправляет локальный порт 53 (dns) на порт 192.168.1.1 через безопасный туннель между localhost и server.foo.com.


Вам понадобится ssf-сервер (вместо вашего сервера ssh или рядом с ним ):

#>./ssfs

Кстати, клиентская и серверная части ssf работают на Windows / Linux / Mac. Это пользовательское приложение, поэтому вам не нужно настраивать / подключать или использовать VPN.

Чтобы перенаправить порт 53, вам потребуются права администратора - независимо от того, какой инструмент вы используете.

Для получения дополнительной информации, подробностей, варианта использования или загрузки: https://securesocketfunneling.github.io/ssf/

SSF-разработчики
источник
Пожалуйста, будьте осторожны, отвечая: «Вот мой продукт», это пограничный спам. Я предлагаю прочитать и следовать инструкциям справочного центра .
тяжелый
7
В большинстве случаев это бесстыдная вилка. В любом случае решение может соответствовать вашему запросу. Кстати, SSF это OpenSource и некоммерческая.
ssf-developers
11
@heavyd: Если бы он опубликовал кучу хакерских скриптов, это было бы приемлемо, но потому что он создал зрелый инструмент с открытым исходным кодом, не так ли? Он отлично отвечает на оригинальный вопрос.
Synthead
Я должен неохотно признать, что это именно тот инструмент, который я искал, даже если это был бесстыдный штекер.
Therealrootuser
9

Я не смог заставить ncработать SNMP, потому что клиенты SNMP продолжают выбирать новый исходный порт UDP, и несколько из них могут быть активны одновременно.

Вместо этого я написал пост, описывающий, как это сделать socatв этом посте , используя SNMP в качестве примера. По сути, используя два терминала, начиная с обзора:

обзор

Терминал один:

client$ ssh -L 10000:localhost:10000 server
server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161

Это создает пересылку SSH TCP-порта 10000 и запускает socat на сервере. Обратите внимание, как IP-адрес коммутатора упоминается в командной строке socat как «коммутатор».

Терминал два:

client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000

Это настраивает сокат на клиенте. Это должно сделать это.

Петр В. Мёрч
источник
это сработало для меня :)
Пол Фенни
4

VPN - лучшее решение, если у вас есть доступ к порту UDP.

Если у вас есть доступ только к TCP-порту SSH, то SSH-туннель так же хорош, как VPN, по крайней мере, для проверки связи и обратного отслеживания пакетов.

Майкл
источник