¿Es posible exponer el túnel TCP en Linux como dispositivo de caracteres especiales?

10

Recientemente encontré en la documentación de QNX que permite configurar IPC basado en mensajes entre procesos en máquinas físicas separadas usando un dispositivo serie ( dev/serX) y me hizo preguntarme:

¿Es posible en Linux crear un dispositivo especial en todo el sistema para el túnel TCP / UDP? Algo como ncstdin / stdout expuesto públicamente bajo / dev / something.

Al final, me gustaría poder escribir algo en dicho archivo en una máquina y recibirlo en el otro extremo, por ejemplo:

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

#machine2:
cat < /dev/somedev

ncEché un vistazo a man pero no encontré ninguna opción para especificar io fuente / destino que no sea stdio.

Lapsio
fuente
Consulte ¿Por qué las interfaces de red no están en / dev como otros dispositivos? que cubre la parte "por qué no".
Gilles 'SO- deja de ser malvado'
1
Mención de honor: los dispositivos tun / tap se pueden crear en / dev, pero usted mismo debe realizar la encapsulación de IP. Extremadamente útil para algunos propósitos.
pjc50

Respuestas:

19

socat puede hacer esto y muchas otras cosas con cosas que se asemejan a "transmisiones"

Algo que use esta idea básica debería hacerlo por usted:

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

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

(adaptado de la página de ejemplos )

Si desea cifrar, puede usar una variación de ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forken machine1 y algo así como ssl:server-host:1443,cert=client.pem,cafile=server.crten machine2

(Más sobre socat ssl )

Alex Stragies
fuente
7

El paso de mensajes debe implementarse en una capa superior; TCP no tiene una noción de mensaje: las conexiones TCP transfieren secuencias de octetos.

Puede lograr algo parecido a lo que solicita ncy las canalizaciones con nombre , vea man mkfifo; o verifique socatcomo lo indica Alex Stragies.

Sin un servicio de capa intermedia, los problemas básicos son (1) que los datos no pueden escribirse en la red a menos que haya alguien en el otro extremo que lo escuche y (2) que las conexiones TCP son bidireccionales.

Debido a que no puede escribir datos en la red a menos que alguien lo esté escuchando, siempre debe iniciar el escucha antes de poder enviar datos. (En un sistema de paso de mensajes, el proceso que maneja los mensajes proporcionará algún tipo de almacenamiento en búfer).

Su ejemplo puede reescribirse fácilmente:

  • Primero inicie un oyente en machine2 (el destino):

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

    En su ejemplo, esto sería

     nc -l 1234 | cat
    

    Esto bloqueará y esperará que alguien envíe algunos datos al puerto 1234.

  • Luego puede enviar algunos datos de machine1 (la fuente):

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

    En su ejemplo, esto sería

     echo "Hello" | nc machine2 1234
    

Si desea procesar los datos recibidos de alguna manera y responder, puede usar la función de coprocesamiento del shell. Por ejemplo, este es un servidor web muy simple (y muy terco):

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

Vea cómo se logra la comunicación bidireccional entre el cuerpo principal del script y el coproceso utilizando los descriptores de archivo en la matriz $ncfd.

AlexP
fuente
Tienes razón, y lo he reconocido en la respuesta. No puede tener un dispositivo de caracteres sin algún tipo de software de mediación.
AlexP
Parece que tienes un UUOC allí.
Michael Hampton
1
@MichaelHampton: Ese fue el ejemplo proporcionado por el OP. Supongo que eso catsignifica "algún proceso de lectura para stdin".
AlexP
5

Si simplemente desea conectar dos computadoras usando un programa básico como nc, puede redirigir desde / hacia /dev/tcp/<host>/<port>.

Estos no son dispositivos reales, sino una ficción creada por bash, por lo que cosas como cat /dev/tcp/foo/19no funcionarán, pero lo cat < /dev/tcp/foo/19harán.

Ángel
fuente