Ist es möglich, den TCP-Tunnel unter Linux als Sonderzeichengerät verfügbar zu machen?

10

Kürzlich habe ich in der QNX-Dokumentation festgestellt, dass es das Einrichten eines nachrichtenbasierten IPC zwischen Prozessen auf separaten physischen Computern mithilfe des seriellen Geräts ( dev/serX) ermöglicht, und ich habe mich gefragt:

Ist es unter Linux möglich, ein systemweites Spezialgerät für den TCP / UDP-Tunnel zu erstellen? So etwas wie ncstdin / stdout wird öffentlich unter / dev / Something veröffentlicht .

Am Ende möchte ich in der Lage sein, etwas in eine solche Datei auf einem Computer zu schreiben und es am anderen Ende zu empfangen, zum Beispiel:

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

#machine2:
cat < /dev/somedev

Ich habe mir den ncMann angesehen, aber keine andere Option gefunden, um eine andere Quelle / ein anderes Ziel als stdio anzugeben.

Lapsio
quelle
Siehe Warum sind Netzwerkschnittstellen nicht in / dev wie bei anderen Geräten? welches den "warum nicht" Teil abdeckt.
Gilles 'SO - hör auf böse zu sein'
1
Lobende Erwähnung: Die Tun / Tap-Geräte können in / dev erstellt werden, aber Sie müssen die IP-Kapselung selbst vornehmen. Für einige Zwecke äußerst nützlich.
pjc50

Antworten:

19

socat kann dies und viele andere Dinge mit Dingen tun, die "Streams" ähneln

Etwas, das diese Grundidee verwendet, sollte es für Sie tun:

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

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

(angepasst von der Beispielseite )

Wenn Sie verschlüsseln möchten, können Sie eine Variation von ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forkauf Maschine1 und so etwas wie ssl:server-host:1443,cert=client.pem,cafile=server.crtauf Maschine2 verwenden

(Mehr über socat ssl )

Alex Stragies
quelle
7

Das Weiterleiten von Nachrichten muss auf einer höheren Ebene implementiert werden. TCP hat keine Vorstellung von einer Nachricht - die TCP-Verbindungen übertragen Oktettströme.

Sie können so etwas wie das erreichen, was Sie mit ncund benannten Pipes anfordern , siehe man mkfifo; oder überprüfen Sie, socatwie Alex Stragies angibt.

Ohne einen Middle-Layer-Dienst bestehen die Grundprobleme darin, (1) dass Daten nur dann in das Netzwerk geschrieben werden können, wenn jemand am anderen Ende darauf wartet, und (2) dass TCP-Verbindungen bidirektional sind.

Da Sie keine Daten in das Netzwerk schreiben können, ohne dass jemand darauf wartet, müssen Sie den Listener immer starten, bevor Sie Daten senden können. (In einem Nachrichtenübermittlungssystem stellt der Prozess, der die Nachrichten verarbeitet, eine Art Pufferung bereit.)

Ihr Beispiel kann einfach umgeschrieben werden:

  • Starten Sie zuerst einen Listener auf Maschine2 (dem Ziel):

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

    In Ihrem Beispiel wäre dies

     nc -l 1234 | cat
    

    Dies blockiert und wartet darauf, dass jemand Daten an Port 1234 sendet.

  • Dann können Sie einige Daten von Maschine1 (der Quelle) senden:

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

    In Ihrem Beispiel wäre dies

     echo "Hello" | nc machine2 1234
    

Wenn Sie die empfangenen Daten auf irgendeine Weise verarbeiten und antworten möchten, können Sie die Coprozessierungsfunktion der Shell verwenden. Dies ist beispielsweise ein sehr einfacher (und sehr hartnäckiger) Webserver:

#! /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

Sehen Sie anhand der Dateideskriptoren im Array, wie die bidirektionale Kommunikation zwischen dem Hauptteil des Skripts und dem Coprozess erreicht wird $ncfd.

AlexP
quelle
Sie haben Recht, und das habe ich in der Antwort bestätigt. Ohne eine Vermittlungssoftware kann kein Charaktergerät vorhanden sein.
AlexP
Sieht so aus, als hätten Sie dort eine UUOC.
Michael Hampton
1
@ MichaelHampton: Das war das Beispiel des OP. Ich nehme an, das catsteht für "einige Prozesslesungen für stdin".
AlexP
5

Wenn Sie einfach zwei Computer mit einem Basisprogramm wie nc verbinden möchten, können Sie von / nach umleiten /dev/tcp/<host>/<port>.

Dies sind keine tatsächlichen Geräte, sondern eine Fiktion, die durch Bash erstellt wurde. Dinge wie cat /dev/tcp/foo/19funktionieren also nicht, werden es aber cat < /dev/tcp/foo/19.

Engel
quelle