È possibile esporre il tunnel TCP in Linux come dispositivo a caratteri speciali?


10

Recentemente ho scoperto nella documentazione di QNX che consente di impostare un IPC basato su messaggi tra processi su macchine fisiche separate utilizzando il dispositivo seriale ( dev/serX) e mi ha fatto meravigliare:

In Linux è possibile creare dispositivi speciali a livello di sistema per tunnel TCP / UDP? Qualcosa come ncstdin / stdout esposto pubblicamente sotto / dev / qualcosa.

Alla fine mi piacerebbe poter scrivere qualcosa su tale file su una macchina e riceverlo sull'altra estremità, ad esempio:

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

#machine2:
cat < /dev/somedev

Ho dato un'occhiata a ncman ma non ho trovato alcuna opzione per specificare io source / destination oltre a stdio.



1
Menzione d'onore: i dispositivi tun / tap possono essere creati in / dev, ma è necessario eseguire l'incapsulamento IP su di essi. Estremamente utile per alcuni scopi.
pjc50,

Risposte:


19

socat può fare questo e molte altre cose con cose che assomigliano a "flussi"

Qualcosa che utilizza questa idea di base dovrebbe farlo per te:

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

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

(adattato dalla pagina degli esempi )

Se si desidera crittografare, è possibile utilizzare una variante di ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forksu machine1 e qualcosa di simile ssl:server-host:1443,cert=client.pem,cafile=server.crtsu machine2

(Maggiori informazioni su socat ssl )


7

Il passaggio dei messaggi deve essere implementato a un livello superiore; TCP non ha una nozione di messaggio: le connessioni TCP trasferiscono flussi di ottetti.

Puoi ottenere qualcosa di simile a quello che richiedi nce dai nomi alle pipe , vedi man mkfifo; oppure controlla socatcome indica Alex Stragies.

Senza un servizio di livello intermedio, i problemi di base sono (1) che i dati non possono essere scritti sulla rete a meno che non vi sia qualcuno all'altra estremità che li ascolta e (2) che le connessioni TCP siano bidirezionali.

Poiché non è possibile scrivere dati sulla rete a meno che qualcuno non li ascolti, è necessario avviare sempre l'ascoltatore prima di poter inviare i dati. (In un sistema che passa messaggi il processo che gestisce i messaggi fornirà una sorta di buffering.)

Il tuo esempio può essere facilmente riscritto:

  • Innanzitutto avvia un listener su machine2 (la destinazione):

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

    Nel tuo esempio, questo sarebbe

     nc -l 1234 | cat
    

    Questo bloccherà e attenderà che qualcuno invii alcuni dati alla porta 1234.

  • Quindi è possibile inviare alcuni dati da machine1 (l'origine):

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

    Nel tuo esempio, questo sarebbe

     echo "Hello" | nc machine2 1234
    

Se si desidera elaborare i dati ricevuti in qualche modo e rispondere, è possibile utilizzare la funzione di coprocessing della shell. Ad esempio, questo è un server web molto semplice (e molto testardo):

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

Guarda come viene raggiunta la comunicazione bidirezionale tra il corpo principale dello script e il coprocesso utilizzando i descrittori di file nell'array $ncfd.


Hai ragione, e l'ho riconosciuto nella risposta. Non è possibile avere un dispositivo a caratteri senza una sorta di software di mediazione.
AlexP

Sembra che tu abbia un UUOC lì.
Michael Hampton,

1
@MichaelHampton: quello era l'esempio fornito dall'OP. Suppongo che catsta per "alcuni processi di lettura per stdin".
AlexP,

5

Se vuoi semplicemente connettere due computer usando un programma base come nc puoi reindirizzare da / a /dev/tcp/<host>/<port>.

Questi non sono dispositivi reali ma una finzione creata da Bash, quindi cose come cat /dev/tcp/foo/19non funzioneranno, ma cat < /dev/tcp/foo/19funzioneranno.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.