2

В настоящее время у меня есть компьютер Debian и Raspberry Raspberry Pi в моей домашней сети за маршрутизатором. Маршрутизатор имеет открытый порт для меня, в котором я могу подключиться по ssh к rPi, когда меня нет, а затем, находясь в сети, я могу делать все, что захочу, в домашней сети.

Во время путешествия жесткий диск моего компьютера Debian, похоже, умер; по крайней мере, он отказывается загружаться.

Я не оставлял ни одного загрузочного компакт-диска для вставки, поскольку я всегда загружал коробку через PXE, с моим домашним маршрутизатором Tomato, настроенным для указания на виртуальную машину на моем ноутбуке для обслуживания образов BOOTP и TFTP, необходимых для загрузки любого установщика Linux, Компакт-диск восстановления системы или Trinity Rescue Kit.

Этот ноутбук теперь со мной в путешествии.

Могу ли я настроить перенаправление портов SSH со своего ноутбука, когда я подключаюсь к своему домашнему rPi, и временно перенастроить IP-адрес на [я думаю] dhcp-boot , чтобы мой компьютер Debian мог загружаться через PXE с помощью виртуальной машины удаленного ноутбука через Интернет?

ОБНОВЛЕНИЕ 3 августа: После предложения Мэтта ниже было хорошее начало, но все еще не завершено. Я все еще не дальше, чем раньше.

TFTP-сервер прослушивает UDP-порт 69, но, используя опцию -R что ssh перенаправляет только TCP.

Это и это обеспечили один из способов продолжения, установив каналы вокруг туннеля для преобразования UDP-трафика в TCP до туннеля и TCP обратно в UDP после туннеля, но комментарии показали, что это не лучший способ. Кроме того, это не сработало для меня.

Использование socat вместо каналов, казалось, вызвало меньше противоречий, поэтому я подумал, что попробую, но это тоже не сработало.

Чтобы понять, что я сделал до сих пор, я попытался повторить проблему локально на своем ноутбуке следующим образом.

У меня уже есть виртуальная машина, на которой запущен TFTP-сервер через порт 69, который может по крайней мере обслуживать файл pxelinux.0 .

Я создал новую виртуальную машину, загружающую ISO-образ компакт-диска System Rescue. Когда я загрузил эту виртуальную машину, я настроил ее как DHCP-сервер:

# vi /etc/dhcp/dhcpd.conf

В файле я указал следующее:

subnet 192.168.1.0 netmask 255.255.255.0 {
   range 192.168.1.251 192.168.1.253;
   option routers 192.168.1.1;
   filename "pxelinux.0";
   next-server 192.168.1.252;
}

Затем я перезапустил сервер DHCP:

# /etc/init.d/dhcpd restart

Примечание: у меня теперь есть два DHCP-сервера в этой "чужой" сети - маршрутизатор, который предоставил моему ноутбуку свой IP-адрес, и теперь эта виртуальная машина, пока он не выключится. Это приводит к состоянию гонки, поскольку моя виртуальная машина с загрузкой PXE может получить ответ от любого DHCP-сервера; Я надеюсь, что ответ моей виртуальной машины первым достигнет виртуальной машины PXE, чтобы она могла получить указанную выше директиву next-server .

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

Как уже говорилось, с запущенным сервером DHCP я загрузил свою третью бездисковую виртуальную машину, настроенную для загрузки PXE, чтобы выполнить процесс загрузки PXE.

Хост .252 был моим PXE-сервером, поэтому виртуальная машина PXE-boot смогла добраться до него, получить необходимые файлы через TFTP и начать загрузку как обычно.

С номинальным случаем я решил ввести SSH туннель в микс, как предложил Мэтт.

# vi /etc/dhcp/dhcpd.conf

Я изменил next-server на IP-адрес самой виртуальной машины System Rescue CD:

subnet 192.168.1.0 netmask 255.255.255.0 {
   range 192.168.1.251 192.168.1.253;
   option routers 192.168.1.1;
   filename "pxelinux.0";
   next-server 192.168.1.13;
}

Затем я перезапустил сервер DHCP:

# /etc/init.d/dhcpd restart

Я также проверил, что на этом поле не запущен TFTP-сервер:

# netstat -an | grep 69

Теперь моя ВМ с PXE-загрузкой не загрузилась. Он получил IP-адрес от сервера DHCP, но не смог получить загрузочный образ TFTP.

Я привез открытый ключ моего PXE - сервера и поместил его в корневом файл authorized_keys

Из виртуальной машины PXE-сервера я создал свой туннель:

$ ssh -R 69:localhost:69 -R 2049:localhost:2049 root@192.168.1.13

Обратите внимание, что мне не нужно было переадресовывать порт 2049 в это время, но мне нужно будет сделать это позже для NFS.

Та же проблема при загрузке виртуальной машины PXE: не удалось получить образ по TFTP.

Сервер TFTP прослушивал порт UDP 69:

udp        0      0 0.0.0.0:69              0.0.0.0:*

Тем не менее, перенаправленный порт прослушивает TCP:

tcp        0      0 127.0.0.1:69            0.0.0.0:*               LISTEN
tcp6       0      0 ::1:69                  :::*                    LISTEN

Пробовал первоначальный подход с использованием труб. На компакт-диске System Rescue:

# mkfifo /tmp/fifo
# nc -v -l -u -p 6963 < /tmp/fifo | nc -v -u 127.0.0.1 6964 > /tmp/fifo

Между тем на PXE-сервере ВМ:

$ ssh -R 6964:localhost:6965 root@192.168.1.13
$ nc -v -l -p 6965 < /tmp/fifo | nc -v -u localhost 69 > /tmp/fifo

С компакт-диска System Rescue я попытался передать файл вручную:

# tftp localhost 6963 -c get pxelinux.0
connect to [127.0.0.1] from sysresccd.gentoo [127.0.0.1] 51072
too many output retries : Broken pipe

Это все еще не сработало, поэтому я снова попытался вывести туннель из уравнения.

Система Rescue CD VM:

# nc -v -l -u -p 6963 < /tmp/fifo | nc -v -u 127.0.0.1 6965 > /tmp/fifo

ВМ PXE-сервера:

$ nc -v -l -p 6965 < /tmp/fifo | nc -v -u localhost 69 > /tmp/fifo

Перенос на System Rescue CD VM:

# tftp localhost 6963 -c get pxelinux.0

Это все еще не сработало, так что я убрал rm /tmp/fifo на обеих коробках.

Затем я продолжил попытку socat , но у нее были похожие результаты. Я также вывел SSH-туннель из уравнения, с теми же результатами.

На этот раз я не смог использовать компакт-диск System Rescue CD, так как он не поставлялся с установленным socat , поэтому я использовал другую виртуальную машину.

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

$ tftp 192.168.1.252
tftp> get pxelinux.0
tftp> quit

Конечно же, я скачал ненулевой байтовый файл.

Это не сработало, когда я использовал ящик, который ничего не слушал на порте TFTP:

$ tftp localhost
tftp> get pxelinux.0
Transfer timed out.

tftp> quit
boots$ rm pxelinux.0

Время положить socat в смесь.

На PXE-сервере:

$ ssh -p 22 -R 6969:localhost:6968 192.168.1.7
$ sudo socat UDP4-LISTEN:69,fork TCP4:localhost:6969

В другом окне на сервере PXE:

$ socat -T10 TCP4-LISTEN:6968,fork UDP4:localhost:69

Это все еще не работает:

$ tftp localhost
tftp> get pxelinux.0
Transfer timed out.

tftp> quit
boots$ rm pxelinux.0

Обновление 4 августа: я думаю, что нашел свою проблему, но я не уверен, как обойти ее.

Я сделал мою настройку еще более простой. Я полностью исключил туннель SSH и подключился к прямым портам UDP.

На моем локальном клиенте TFTP, просто это:

$ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69

Напомним, что поле .252 является сервером TFTP.

Это все еще не работает:

$ tftp localhost
tftp> get pxelinux.0
Transfer timed out.

tftp> quit
boots$ rm pxelinux.0

Поэтому я запустил Wireshark на блоках .7 и .252, просматривая UDP-трафик и, в частности, TFTP-трафик.

Вот мои фильтры захвата на двух экземплярах Wireshark:

  • .7: udp и хост 192.168.1.252 и порт не 123
  • .252: UDP и хост 192.168.1.7 и порт не 123

Когда я запустил это, я увидел много трафика TFTP на порте, отличном от 69. В этом случае пакеты данных шли от порта 60862 на исходном хосте до 44792 на месте назначения, и подтверждения возвращались на этих портах другим способом.

Согласно Википедии:

Запрос на передачу всегда инициируется для порта 69, но порты передачи данных выбираются независимо отправителем и получателем во время инициализации передачи. Порты выбираются случайным образом в соответствии с параметрами сетевого стека, обычно из диапазона эфемерных портов.

Если я правильно понимаю, мне нужно будет туннелировать больше, чем просто порт 69. Какие дополнительные команды мне нужны для перенаправления этих портов? Есть ли простой способ сделать это?

Обновление 5 августа: у меня может быть еще одна проблема до этого.

Что касается пункта, указанного выше, я попытался немного поиграться с TFTP и посмотреть пакеты в Wireshark. Похоже, я получаю первый пакет на порт 69 с порта случайного источника. В последнем случае это был порт 48723.

Оказывается, TFTP-сервер отправляет UDP-пакеты через этот порт с другого порта. Если я смогу отслеживать первый пакет на порт 69, я это вижу, и я ожидаю, что смогу быстро настроить аналогичный туннель на этом порту до истечения времени ожидания, поэтому процесс будет немного ручным, но я мог бы в состоянии осуществить это.

Теперь, когда я присматриваюсь, кажется, что я не получаю тот первый пакет через socat .

Когда у меня нет туннеля, я вижу начальный пакет на порту 69 без проблем.

Когда я вместо этого настраиваю прямой socat без SSH-туннеля следующим образом, я не вижу пакета.

Окно 1:

$ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69

Окно 2:

$ tftp localhost
tftp> get pxelinux.0
Transfer timed out.

Вот вывод из netcat:

$ netstat -an | grep 69 | grep udp
udp        0      0 0.0.0.0:69              0.0.0.0:*

У меня также есть один экземпляр Wireshark, работающий с обеих сторон; оба показывают абсолютно ничего. Вот мой фильтр захвата с обеих сторон:

udp and not (port 123 or port 5353 or port 1900)

Я открыл еще один вопрос по этому поводу.

Обновление: маленький шаг вперед. Я подозреваю, что у меня что-то не так с моей командой socat .

Я попробовал другой простой тест только на моем ноутбуке.

Окно 1:

$ sudo nc -v -l -u 69

Wireshark:

  • Слушай на интерфейсе
  • Фильтр захвата: UDP и порт 69

Окно 2:

$ nc -u 127.0.0.1 69

Когда я набрал в окне 2, я увидел выходные данные в окне 1 и увидел пакеты, захваченные в Wireshark.

Затем я повторил с сетевой картой моего ноутбука:

Окно 1:

$ sudo nc -v -l -u 69

Wireshark:

  • Слушай по интерфейсу wlan0
  • Фильтр захвата: UDP и порт 69

Окно 2:

$ nc -u 127.0.0.1 69

Оказывается, я не получал никаких пакетов, захваченных в Wireshark, хотя я получал сообщения, отображаемые в Окне 1. Я вспомнил, что некоторое время назад установил Docker, поэтому у меня был мост docker0; У меня также есть пара продуктов для виртуализации, так что, возможно, они мешали.

Я повторно запустил захват Wireshark с:

  • Слушай по интерфейсу любой
  • Фильтр захвата: UDP и порт 69

На этот раз я получал все, что хотел. Возможно, моей проблемой был интерфейс захвата Wireshark.

Остановил окна netcat и сделал шаг назад:

$ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69

Снова попробовал тест TFTP:

$ tftp localhost
tftp> get pxelinux.0

Вот и все! Теперь я получаю свои пакеты в Wireshark!

Я вижу захваченные сообщения «Запрос на чтение», и получается, что все пять попыток / повторных попыток приходят с одного и того же исходного порта.

Теперь пришло время посмотреть, смогу ли я вручную установить дополнительный сеанс socat на этом исходном порту. На самом сервере TFTP я дополнительно запустил:

$ for f in 52163; do socat -d -d -d -d udp4-recvfrom:${p},reuseaddr,fork udp:192.168.1.7:${p}; done

Обратите внимание, что это был IP-адрес моего ноутбука. (Цикл for просто для удобства, поэтому мне нужно указать номер порта только один раз в команде.)

Оказывается, что каждый из исходных портов одинаков, независимо от того, сколько раз я запускаю команду PXE get pxelinux.0 ; номер порта источника изменяется, когда я выхожу из TFTP и повторно запускаю TFTP.

У меня есть Wireshark, работающий как на моем ноутбуке, так и на коробке TFTP; Теперь я вижу пакеты на Wireshark моего ноутбука, но не на TFTP Wireshark.

Я думаю, что-то не так с моей командой socat , но я не знаю, что это:

$ sudo socat -d -d -d -d udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.252:69

Обновление: теперь, когда у меня есть основы для netcat, я решил сделать шаг вперед, введя socat в микс, но по-прежнему не используя ssh-туннель.

У меня есть локальный ноутбук, и сейчас давайте назовем TFTP-сервер удаленной коробкой, хотя это просто виртуальная машина на моем ноутбуке.

Окно 1:

local$ sudo socat udp4-recvfrom:69,reuseaddr,fork udp:192.168.1.13:69

Окно 2:

local$ nc -4u localhost 69

Wireshark работает на удаленном компьютере, перехватывающем трафик UDP.

В окне 2 я набрал три строки, нажимая Enter после каждой: "один", "два" и "три".

В Wireshark я вижу три пакета на порту TFTP, поэтому сервер TFTP должен получать эти данные мусора. Здесь интересно то, что каждый из трех пакетов имеет свой порт источника.

Затем я вышел из netcat и вместо этого запустил клиент TFTP, указав локальный IP-адрес вместо "localhost", так как сегодня меня это обожгло :

local$ tftp 127.0.0.1
tftp> get pxelinux.0

Теперь я получаю пакет TFTP Read Request с моего локального ноутбука !!

(К вашему сведению, перед тем, как записать свои заметки, я запустил "tftp localhost" и снова ничего не получил. Похоже, проблема IPv4/IPv6, упомянутая в моем другом вопросе.)

Теперь вернемся к туннелю SSH.

Окно 1:

remote$ socat tcp4-listen:6901,reuseaddr,fork udp:127.0.0.1:69

Окно 2:

local$ ssh -L 6901:127.0.0.1:6901 192.168.1.13

Окно 3:

local$ sudo socat udp4-recvfrom:69,reuseaddr,fork tcp:127.0.0.1:6901

Я получаю пакеты Read Read, захваченные в Wireshark, вместе с первым пакетом данных, который не может никуда попасть, поскольку туннель не возвращается через исходный порт, но, по крайней мере, я получаю UDP-пакеты по туннелю на TFTP-сервер !

Теперь это заставило меня задуматься об этом возвращении. С socat в середине, похоже, я получаю пять попыток передачи от этого TFTP-клиента до истечения времени ожидания; Я не знаю, как будет вести себя клиент TFTP в прошивке NIC.

Кажется, что для каждой из этих попыток я сейчас получаю другой исходный порт, так как соединение с TFTP-сервером происходит от socat а не от клиента TFTP моего ноутбука. Опять же, я понятия не имею, как будет вести себя клиент TFTP, встроенный в прошивку NIC.

Даже если я контролировать трафик и настроить обратный туннель достаточно быстро после просмотра трафика в Wireshark, я не уверен, что это слишком поздно.

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

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

Мое представление о "локальном" и "удаленном" теперь перевернуто, поскольку мой TFTP-сервер является локальным для меня, тогда как мой мертвый ПК является удаленным.

Окно 1:

laptop$ ssh user@192.168.1.13
local$ socat tcp4-listen:6901,reuseaddr,fork udp:127.0.0.1:69

Окно 2:

laptop$ ssh -R 6901:127.0.0.1:6901 user@remote.fqdn.net
remote$ ping -i 60 8.8.8.8

(Пинг должен поддерживать соединение в случае необходимости.)

Окно 3:

laptop$ ssh user@remote.fqdn.net
remote$ sudo socat udp4-recvfrom:69,reuseaddr,fork tcp:127.0.0.1:6901

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

Я сохраняю свои локальные и удаленные возможности для совместимости с производственной средой, хотя это и обратная сторона для моей тестовой среды.

Окно 1:

laptop$ ssh 192.168.1.13
local$ mkfifo /tmp/fifo
local$ nc -lp 6901 < /tmp/fifo | nc -u 127.0.0.1 69 > /tmp/fifo

Окно 2:

laptop$ ssh 192.168.1.13
local$ ssh -R 6902:127.0.0.1:6901 192.168.1.7
remote$ ping -i 60 8.8.8.8

Окно 3:

remote$ mkfifo /tmp/fifo
remote$ sudo nc -lup 69 < /tmp/fifo | nc 127.0.0.1 6902 > /tmp/fifo

Я попробовал простой TFTP получить от моего клиента TFTP снова. На этот раз я заметил в Wireshark, что порт источника одинаков для каждого пакета! Может быть, еще есть надежда!

Помните, предостережение для этого заключается в том, что UDP-пакеты остаются ниже размера MTU, что, я полагаю, я где-то читал, что они будут для TFTP.

Я должен очистить свои трубы:

local$ rm /tmp/fifo
remote$ rm /tmp/fifo

Я хотел попробовать это сейчас на производстве.

Окно 1:

laptop$ ssh user@192.168.1.13
local$ mkfifo /tmp/fifo
local$ nc -lp 6901 < /tmp/fifo | nc -u 127.0.0.1 69 > /tmp/fifo

Окно 2:

laptop$ ssh user@192.168.1.13
local$ ssh -R 6901:127.0.0.1:6901 user@remote.fqdn.net
remote$ ping -i 60 8.8.8.8

(Пинг должен поддерживать соединение в случае необходимости.)

Окно 3:

laptop$ ssh user@remote.fqdn.net
remote$ mkfifo /tmp/fifo
remote$ sudo -i
remote$ nc -lup 69 < /tmp/fifo | nc 127.0.0.1 6901 > /tmp/fifo

Когда я загрузил ПК, я получил один TFTP-пакет, который прошел весь путь до PXE-сервера в соответствии с Wireshark, но я не получил ни одной попытки. Я также надеялся получить повторные попытки, и что все они будут иметь один и тот же порт источника.

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

Я должен очистить свои трубы:

local$ rm /tmp/fifo
remote$ sudo rm /tmp/fifo

1 ответ1

0

Это должно работать, из документации ssh:

-R remote_socket:local_socket
Указывает, что соединения с данным портом TCP или сокетом Unix на удаленном (серверном) хосте должны быть перенаправлены на данный хост и порт

Поскольку порт 69 является привилегированным, вы также должны знать, что:

Привилегированные порты могут быть перенаправлены только при входе в систему как root на удаленной машине.


Сначала измените dnsmasq.conf и измените опцию dhcp-boot; порт назначения будет Raspberry Pi.

С вашего местного ноутбука,

$ ssh root@port.forwarded.pi -R 69:69

Как только этот порт переадресован, попытайтесь перезагрузить компьютер Debian.

При загрузке PXE на машине должна быть опция загрузки DHCP, указывающая на пи.

Запрос TFTP через порт 69 войдет в порт, открытый туннелем SSH, и отправит этот пакет на 127.0.0.1:69 на вашем локальном ноутбуке.

Предполагая, что вы используете TFTP-сервер на порту 69, образ должен быть загружен.

Всё ещё ищете ответ? Посмотрите другие вопросы с метками .