Как загрузить PXE через WAN

1603
jia103

В настоящее время у меня есть компьютер Debian и Raspberry Pi Raspbian в моей домашней сети за маршрутизатором. Маршрутизатор имеет открытый порт для меня, в котором я могу подключиться по 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-serverIP-адрес самой виртуальной машины 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, поскольку он не поставлялся с 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, хотя я получал сообщения, отображаемые в Window 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:$,reuseaddr,fork udp:192.168.1.7:$; 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 
2
/ edit: Неважно, мне кажется, я понял твой сценарий сейчас. Тем не менее, используйте правильный VPN. Может быть, вы можете заставить его работать, используя SSH. Но использование * правильного * инструмента для работы значительно облегчит эту задачу. Daniel B 6 лет назад 0

1 ответ на вопрос

0
Matt Clark

Это должно работать, из документации 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, образ должен быть загружен.

Поскольку я работаю в Debian, я думаю, что вместо этого мне понадобится `-R 69: localhost: 69`, но я столкнулся с проблемой, возникшей прошлой ночью: я считаю, что TFTP-сервер прослушивает UDP 69 в соответствии с` ps -ef | grep 69`, тогда как это указывает TCP 69. До сих пор это не работало. jia103 6 лет назад 0

Похожие вопросы