web-dev-qa-db-ja.com

PXEブートオーバーの方法WAN

現在、ルーターの背後にあるホームネットワークにDebianPCとRaspbianRaspberryPiがあります。ルーターにはポートが開いており、離れているときにrPiにSSHで接続できます。ネットワークに接続すると、ホームネットワークでやりたいことが何でもできます。

旅行中に、私のDebianPCのハードドライブが故障したようです。少なくとも、起動を拒否しています。

必要なBOOTPイメージとTFTPイメージを提供するためにラップトップのVMを指すように構成されたTomatoホームルーターを使用して、常にPXE経由でボックスをブートしたため、誰もが挿入できるブートCDを残しませんでした。 Linuxインストーラー、System Rescue CD、またはTrinity RescueKitを起動します。

そのラップトップは今私と一緒に旅行中です。

自宅のrPiに接続するときにラップトップからSSHポート転送を設定し、IPアドレスを一時的に[I think] dhcp-bootに再構成して、DebianPCがリモートラップトップを使用してPXEブートできるようにすることはできますかVMインターネット経由?

8月3日更新:以下のマットの提案に従うことは良いスタートでしたが、まだ完了していません。私はまだ以前よりも進んでいません。

TFTPサーバーはUDPポート69でリッスンしますが、-Rオプションを使用してsshにTCPのみを転送しているように見えます。

This および this 続行する1つの方法を提供し、トンネルの周りにtranslateUDPトラフィックを_に設定します。TCPはトンネルの前に、TCPはトンネルの後にUDPに戻りますが、コメントはこれが最善の方法ではないことを示しています。また、これは私にとってはうまくいきませんでした。

パイプの代わりに socat を使用すると、物議を醸すことが少なくなったように思われたので、試してみようと思いましたが、これもうまくいきませんでした。

これまでに行ったことをキャプチャするために、次のようにラップトップでローカルに問題を再現しようとしました。

VMがポート69でTFTPサーバーを実行していて、少なくともpxelinux.0ファイルを提供できます。

System Rescue CDISOイメージを起動する新しいVMを作成しました。このVMを起動したときに、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

注:これで、この「外部」ネットワーク上に2つのDHCPサーバーがあります。ラップトップにIPアドレスを提供したルーターであり、現在はVM電源が切れるまで。これにより、PXEブートVMがいずれかのDHCPサーバーから応答を受信する可能性があるため、競合状態が発生します。上記のnext-serverディレクティブを取得できるように、VMの応答が最初にPXE VMに到達することを期待しています。

私の限られたエクササイズでの実際には、それは問題ではないように見えますが、私はVMを長時間放置したくないので、ここにいる他の人の邪魔をしません。

前述のように、DHCPサーバーを実行した状態で、PXEブートプロセスを実行するためにPXEブート用にセットアップされた3番目のディスクレスVMをブートしました。

.252ホストは私のPXEサーバーだったので、PXE-boot VMがそれに到達し、TFTP経由で必要なファイルを取得し、通常どおり起動を開始しました。

主格が機能しているので、マットが提案したように、SSHトンネルをミックスに導入することにしました。

# vi /etc/dhcp/dhcpd.conf

next-serverをSystemRescue CD VM自体のIPアドレスに変更しました。

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ブートVMが起動に失敗しました。 DHCPサーバーからIPアドレスを受信しましたが、TFTPブートイメージを取得できませんでした。

PXEサーバーの公開鍵を持ってきて、ルートauthorized_keysファイルに配置しました。

PXEサーバーVMから、トンネルを作成しました。

$ ssh -R 69:localhost:69 -R 2049:localhost:2049 [email protected]

現時点ではポート2049を転送する必要はありませんでしたが、NFSでは後で転送する必要があります。

PXE VMの起動時の同じ問題: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 CD VMの場合:

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

一方、PXEサーバーVMでは:

$ ssh -R 6964:localhost:6965 [email protected]
$ 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
connect to [127.0.0.1] from sysresccd.gentoo [127.0.0.1] 51072
too many output retries : Broken pipe

これでもうまくいかなかったので、もう一度トンネルを方程式から外してみました。

System Rescue CD VM:

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

PXEサーバーVM:

$ 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トンネルを方程式から外しましたが、同じ結果になりました。

今回は、socatがインストールされていないため、System Rescue CD VMを使用できなかったため、別のVMを使用しました。

まず、実際の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

8月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

そこで、UDPトラフィック、特にTFTPトラフィックを調べて.7ボックスと.252ボックスの両方でWiresharkを実行しました。

2つのWiresharkインスタンスのキャプチャフィルタは次のとおりです。

  • 。7:udpおよびホスト192.168.1.252およびポートは123ではありません
  • 。252:udpおよびホスト192.168.1.7およびポートは123ではありません

これを実行すると、69以外のポートで大量のTFTPトラフィックが発生しました。この場合、データパケットは送信元ホストのポート60862から宛先の44792に送信され、これらのポートで確認応答が逆に返されました。

ウィキペディア によると:

転送要求は常にポート69をターゲットとして開始されますが、データ転送ポートは転送の初期化中に送信者と受信者によって個別に選択されます。ポートは、ネットワークスタックのパラメータに従って、通常はエフェメラルポートの範囲からランダムに選択されます。

これを正しく理解している場合は、ポート69だけでなく、トンネリングする必要があります。これらのポートを転送するには、どのような追加コマンドが必要ですか。これを行う簡単な方法はありますか?

8月5日更新:この前に別の問題が発生する可能性があります。

上記の項目については、TFTPでもう少し遊んで、Wiresharkでパケットを見てみました。ランダムな送信元ポートからポート69で最初のパケットを取得しているようです。最後のケースでは、これはポート48723でした。

TFTPサーバーは、別のポートからこのポートを介してUDPパケットを送り返します。ポート69への最初のパケットを監視できれば、これを確認できます。タイムアウトになる前に、このポートに同様に別のトンネルをすばやく設定できると期待しているので、プロセスは少し手動になりますが、それをやってのけることができます。

よく見ると、最初のパケットがsocat全体で取得されていないようです。

トンネルがない場合、ポート69に問題なく最初のパケットが表示されます。

代わりに、次のようにSSHトンネルを使用せずに直接socatを設定すると、パケットが表示されません。

ウィンドウ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:*

また、両側で1つのWiresharkインスタンスを実行しています。どちらもまったく何も表示しません。これが両側のキャプチャフィルターです。

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

開いた 別の質問 これについて。

更新:小さな一歩。 socatコマンドに問題があると思われます。

私は自分のラップトップだけで別の簡単なテストを試しました。

ウィンドウ1:

$ Sudo nc -v -l -u 69

Wireshark:

  • インターフェイスloで聞く
  • キャプチャフィルター: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

ウィンドウ1にメッセージが表示されていたのに、Wiresharkでパケットがキャプチャされなかったことがわかりました。しばらく前に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でパケットをキャプチャしています。

読み取り要求メッセージがキャプチャされているのがわかりますが、5回の試行/再試行はすべて同じ送信元ポートからのものであることがわかりました。

次に、この送信元ポートで追加の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ループは単に便宜上のものであるため、コマンドでポート番号を1回指定するだけで済みます。)

PXE get pxelinux.0コマンドを何度実行しても、各送信元ポートは同じであることがわかります。 TFTPを終了してTFTPを再実行すると、送信元ポート番号が変わります。

ラップトップとTFTPボックスの両方でWiresharkを実行しています。ラップトップのWiresharkにパケットが表示されていますが、TFTPWiresharkには表示されていません。

socatコマンドに問題があると思いますが、それが何であるかわかりません。

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

更新:netcatの基本を理解したので、socatをに導入してステップアップすると思いました。混合しますが、まだsshトンネルはありません。

私はローカルラップトップを持っています。今のところ、ラップトップのVMだけですが、TFTPサーバーをリモートボックスと呼びましょう。

ウィンドウ1:

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

ウィンドウ2:

local$ nc -4u localhost 69

UDPトラフィックをキャプチャするリモートボックスで実行されているWireshark。

ウィンドウ2で、「1」、「2」、「3」の3行を入力し、それぞれの後にEnterキーを押しました。

Wiresharkでは、TFTPポートに3つのパケットが表示されるため、TFTPサーバーがこのガベージデータを取得している必要があります。ここで興味深いのは、3つのパケットのそれぞれに異なる送信元ポートがあることです。

次に、netcatを終了し、代わりに「localhost」の代わりにローカルIPアドレスを指定してTFTPクライアントを実行しました。これは、今日までに burned を取得したためです。

local$ tftp 127.0.0.1
tftp> get pxelinux.0

NowローカルラップトップからTFTP読み取り要求パケットを取得しています!!

(ここでメモをとる前に、「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

Wiresharkでキャプチャされた読み取り要求パケットと、送信元ポートを介して戻るトンネルがないためにどこにも取得できない最初のデータパケットを取得していますが、少なくともトンネルを介してTFTPサーバーへのUDPパケットを取得しています!!

さて、これは私にその帰りの旅行について少し考えさせました。中央にsocatがあると、タイムアウトする前に、このTFTPクライアントから5回の転送が試行されているようです。 NICファームウェアのTFTPクライアントがどのように動作するかわかりません。

TFTPサーバーへの接続はラップトップのTFTPクライアントではなく、socatから行われているため、これらの試行ごとに、異なる送信元ポートを取得しているようです。繰り返しますが、NICファームウェアに組み込まれているTFTPクライアントがどのように動作するかわかりません。

トラフィックを監視し、十分な速度でリターントンネルを設定したとしてもafterWiresharkでトラフィックを確認しても、手遅れかどうかはわかりません。

socatの代わりにパイプを使用した場合も、同じことが当てはまると思います。

更新:私はこれをあきらめる準備ができていると思いますが、楽しみのために、元のボックスに戻って試してみようと思いました少なくとも1回の旅行を開始するのに十分な量が得られたので、いくつかのパケットをキャプチャします。

TFTPサーバーがローカルであるのに対し、死んだPCはリモートであるため、「ローカル」と「リモート」の概念が逆になりました。

ウィンドウ1:

laptop$ ssh [email protected]
local$ socat tcp4-listen:6901,reuseaddr,fork udp:127.0.0.1:69

ウィンドウ2:

laptop$ ssh -R 6901:127.0.0.1:6901 [email protected]
remote$ ping -i 60 8.8.8.8

(pingは、必要な場合に備えて接続を維持するためのものです。)

ウィンドウ3:

laptop$ ssh [email protected]
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 [email protected]
local$ mkfifo /tmp/fifo
local$ nc -lp 6901 < /tmp/fifo | nc -u 127.0.0.1 69 > /tmp/fifo

ウィンドウ2:

laptop$ ssh [email protected]
local$ ssh -R 6901:127.0.0.1:6901 [email protected]
remote$ ping -i 60 8.8.8.8

(pingは、必要な場合に備えて接続を維持するためのものです。)

ウィンドウ3:

laptop$ ssh [email protected]
remote$ mkfifo /tmp/fifo
remote$ Sudo -i
remote$ nc -lup 69 < /tmp/fifo | nc 127.0.0.1 6901 > /tmp/fifo

PCを起動すると、Wiresharkによると1つのTFTPパケットがPXEサーバーに到達しましたが、再試行は行われませんでした。私も再試行を取得したいと思っていました、そしてそれらのすべてが同じ送信元ポートを持つことを望みました。

パイプの左側にあるncを変更して、キープアライブを行うために-kも指定してから再起動しましたが、それでも最初のパケットしか取得できませんでした。

パイプを掃除する必要があります:

local$ rm /tmp/fifo
remote$ Sudo rm /tmp/fifo
2
jia103

このshouldは、 ssh docs から機能します。

-R remote_socket:local_socket
指定されたTCPポートまたはリモート(サーバー)ホスト上のUnixソケットへの接続を指定されたホストおよびポートに転送することを指定します

ポート69は特権ポートであるため、次のことも知っておく必要があります。

特権ポートは、リモートマシンにrootとしてログインしている場合にのみ転送できます。


最初にdnsmasq.confを変更し、dhcp-bootオプションを変更します。宛先ポートはRaspberryPiになります。

ローカルラップトップから、

$ ssh [email protected] -R 69:69

このポートフォワードが確立されたら、Debianマシンの再起動を試みます。

PXEブートでは、マシンはpiを指すDHCPブートオプションを取得する必要があります。

ポート69を介したTFTP要求は、SSHトンネルによって開かれたポートに入り、そのパケットをローカルラップトップの127.0.0.1:69に送信します。

ポート69でTFTPサーバーを実行していると仮定すると、イメージをダウンロードする必要があります。

1
Matt Clark