LinuxではTCPトンネルを特殊文字デバイスとして公開できますか?

LinuxではTCPトンネルを特殊文字デバイスとして公開できますか?

QNXのドキュメントでは、シリアルデバイス()を使用して別の物理システム上のプロセス間でメッセージベースのIPCを設定できることがわかりましたdev/serX

LinuxでTCP / UDPトンネリング用のシステム全体の特別なデバイスを作成することは可能ですか? stdin/stdout のようなものはnc/dev/something の下に公に公開されます。

最終的には、あるコンピュータでそのようなファイルに何かを書き、もう一方の端でそれを受け取ることを望みます。たとえば、次のようになります。

#machine1:
echo "Hello" > /dev/somedev

#machine2:
cat < /dev/somedev

私はmanを見ましたが、ncstdio以外のioソース/ターゲットを指定するオプションが見つかりませんでした。

答え1

socat「ストリーム」のようなものを使用すると、この操作と他の多くのことを実行できます。

この基本的なアイデアを使用すると、次のことを行うことができます。

Machine1$ socat tcp-l:54321,reuseaddr,fork pty,link=/tmp/netchardev,waitslave

Machine2$ socat pty,link=/tmp/netchardev,waitslave tcp:machine1:54321

(で適応サンプルページ)

暗号化したい場合は、ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forkmachine1でバリアントを使用でき、ssl:server-host:1443,cert=client.pem,cafile=server.crtmachine2ではこのようなものを使用できます。

(詳細はソカートSSL)

答え2

メッセージ転送は上位層で実装する必要があります。 TCP にはメッセージの概念はありません。 TCP接続はオクテットストリームを転送します。

要求したものと同様のものを実装できますnc名前付きパイプ、視聴するman mkfifoか、socatAlex Stragiesの指示に従って確認してください。

中間層サービスがなければ、基本的な問題は、(1)誰かが相手から受信しない限り、ネットワークにデータを書き込むことができないこと、および(2)TCP接続が双方向であることです。

誰かが聞いていない場合は、ネットワークにデータを書き込めないため、常に受信機を起動する必要があります。今後データを送信できます。 (メッセージングシステムでメッセージを処理するプロセスは、ある種のバッファリングを提供します。)

あなたの例は簡単に書き直すことができます。

  • まず、machine2(ターゲット)でリスナーを起動します。

     nc -l 1234 | ...some processing with the received data...
    

    あなたの例では、

     nc -l 1234 | cat
    

    これにより、誰かがポート1234にいくつかのデータを送信するのをブロックして待機します。

  • その後、machine1(ソース)からいくつかのデータを送信できます。

    ...make up some data... | nc machine2 1234
    

    あなたの例では、

     echo "Hello" | nc machine2 1234
    

受信したデータを処理して何らかの方法で応答するには、シェルの共同処理機能を使用できます。たとえば、以下は非常にシンプルで頑固なWebサーバーです。

#! /bin/bash

while :; do
  coproc ncfd { nc -l 1234; }
  while :; do
    read line <&${ncfd[0]} || break
    line="$(
      echo "$line" |
      LC_ALL=C tr -cd ' -~'
    )"
    echo >&2 "Received: \"$line\""
    if [ "$line" = "" ]; then
      echo >&${ncfd[1]} "HTTP/1.0 200 OK"
      echo >&${ncfd[1]} "Content-Type: text/html"
      echo >&${ncfd[1]} "Connection: close"
      echo >&${ncfd[1]} ""
      echo >&${ncfd[1]} "<title>It works!</title>"
      echo >&${ncfd[1]} "<center><b>It works!</b></center>"
      echo >&${ncfd[1]} "<center>-- $(date +%Y-%m-%d\ %H:%M:%S) --</center>"
      break
    fi
  done
  kill %%
  sleep 0.1
done

配列内のファイル記述子を使用して、スクリプト本文と共同プロセス間の双方向通信を実装する方法を学びます$ncfd

答え3

ncなどのネイティブプログラムを使用して2台のコンピュータを接続したい場合は、から/にリダイレクトできます/dev/tcp/<host>/<port>

これは実際のデバイスではなくbashによって作成された仮想デバイスなので、これと同様のものは機能しませcat /dev/tcp/foo/19んが、cat < /dev/tcp/foo/19機能します。

関連情報