Название в значительной степени подводит итог. Я хотел бы отправлять трафик UDP через туннель SSH. В частности, мне нужно иметь возможность отправлять UDP-пакеты через туннель и иметь возможность сервера отправлять их мне обратно на другой стороне. Я знаю, как это сделать для TCP-соединений. Это возможно с UDP?
UDP-трафик через SSH-туннель
6 ответов
В этом небольшом руководстве рассказывается, как отправлять 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 Также было бы неплохо использовать порт 1153 вместо 6667 (из примера man SSH), который используется IRC.
@ JuhoÖstman Спасибо за указание на эту ловушку. Зная о проблеме ... Вы нашли решение? Достаточно ли маленькие сообщения, чтобы заставить его работать?
Решение состоит в том, чтобы добавить длину каждому пакету до его отправки через поток TCP и восстановить исходные пакеты из этого. Для этого было бы легко написать C-скрипт, но я не уверен, что существует легкодоступное решение. На практике TCP обычно сохраняет границы сообщений в этом случае, но странные сбои могут возникнуть в любое время.
Я столкнулся с еще одной проблемой: труба и fifo буферизуются, поэтому границы кадра теряются. Столько UDP-кадров можно объединить в один TCP-кадр.
Mac OS Sierra nc жалуется на это sudo nc -l -u -p 53 / tmp / dnsfifo, говоря «nc: отсутствует порт с параметром -l», но, как ни странно, каждая команда без канала работает нормально, так что это довольно странно. Конечно, они на самом деле не функционируют, если они не работают друг с другом, так что ...
Этот пример (я думаю, что ответ Джона указывает на то же самое в другом месте), описывает, как получить доступ к службам 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
См. Примеры сокатов для большего.
Этот кажется мне гораздо более полезным, чем принятый ответ. Мне нужно было однонаправленное перенаправление видеопотока (TS / UDP) ... ssh orig_strm_src socat udp4-listen: 4003, reuseaddr, fork STDOUT | socat STDIN udp-sendto: localhost: 4003
FWIW, я написал более подробное руководство на моей домашней странице, описывающее, как настроить socat через SSH для пересылки UDP. Он использует SNMP в качестве примера.
SSH (по крайней мере, OpenSSH) поддерживает простые VPN. Используя опцию -wили Tunnelв sshклиенте, вы можете создать tunустройство на обоих концах, которое можно использовать для пересылки любого вида IP-трафика. (См. Также Tunnelна странице руководства ssh_config(5).) Обратите внимание, что для этого требуется OpenSSH (и, вероятно, привилегии root) на обоих концах.
Это требует привилегий root на удаленной машине даже для UDP-туннелирования непривилегированных портов, а PermitRootLogin имеет значение не «нет». Очень плохо.
@ grawity Спасибо, что указали на эту опцию, которая, даже если филпирожков указал нужную учетную запись root. Интересно, может ли быть способ обмануть его, чтобы он не нуждался в руте?
@humanityANDpeace: вы можете создать устройства tun / tap и сделать их принадлежащими определенному пользователю, используя ip tuntap add.
Привет, @ Grawity. Мне нравится ваше решение, но я не могу заставить его работать. Я создал устройство tun следующим образом: sudo ip tuntap add mode tun, но когда я когда-либо использовал опцию -w, например: ssh $ Server -w $ port, я получаю `Ошибка открытия устройства туннеля. Не удалось запросить пересылку туннеля. Что я делаю не так?
Или вы можете просто использовать 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 является OpenSource и некоммерческой.
@heavyd: Если бы он опубликовал кучу хакерских скриптов, это было бы приемлемо, но потому что он создал зрелый инструмент с открытым исходным кодом, не так ли? Он отлично отвечает на оригинальный вопрос.
Я должен неохотно признать, что это именно тот инструмент, который я искал, даже если это был бесстыдный штекер.
I couldn't get nc to work for SNMP, because SNMP clients keep choosing a new source UDP port, and several can be active at once.
Instead, I've written a post describing how to do it with socat in this blog post, using SNMP as an example. Essentially, using two terminals, starting with an overview:
Terminal one:
client$ ssh -L 10000:localhost:10000 server server$ socat -T10 TCP4-LISTEN:10000,fork UDP4:switch:161 This creates the SSH forwarding of TCP port 10000 and runs socat on the server. Notice how the switch’s IP address is mentioned in the socat command line as “switch”.
Terminal two:
client$ sudo socat UDP4-LISTEN:161,fork TCP4:localhost:10000 That sets up socat on the client. That should do it.
это сработало для меня :)
VPN - лучшее решение, если у вас есть доступ к порту UDP.
Если у вас есть доступ только к TCP-порту SSH, то SSH-туннель так же хорош, как VPN, по крайней мере, для проверки связи и обратного отслеживания пакетов.

Это решение не безопасно. Не гарантируется, что потоки TCP сохраняют границы сообщений, поэтому одна дейтаграмма UDP может быть разделена на части, нарушая любой протокол.