É possível expor o túnel TCP no Linux como dispositivo de caractere especial?

10

Recentemente, achei na documentação do QNX que ele permite configurar o IPC baseado em mensagens entre processos em máquinas físicas separadas usando o dispositivo serial ( dev/serX ) e isso me fez pensar:

É possível no Linux criar um dispositivo especial para todo o sistema para o túnel TCP / UDP? Algo como nc stdin / stdout exposto publicamente em / dev / something.

No final, eu gostaria de poder escrever algo em tal arquivo em uma máquina e recebê-lo na outra ponta, por exemplo:

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

#machine2:
cat < /dev/somedev

Eu dei uma olhada em nc man, mas não encontrei nenhuma opção para especificar a origem / destino do io além do stdio.

    
por Lapsio 04.12.2016 / 23:10

3 respostas

19

socat pode fazer isso e muitas outras coisas com coisas parecidas com "streams"

Algo usando essa ideia básica deve fazer isso para você:

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

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

(adaptado de Página de exemplos )

Se você deseja criptografar, pode usar uma variação de ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,fork em machine1 e algo como ssl:server-host:1443,cert=client.pem,cafile=server.crt em machine2

(Mais sobre socat ssl )

    
por 05.12.2016 / 00:53
7

A passagem de mensagens precisa ser implementada em uma camada superior; O TCP não tem noção de uma mensagem - as conexões TCP transferem fluxos de octetos.

Você pode conseguir algo parecido com o que solicita com nc e pipes nomeados , veja man mkfifo ; ou verifique socat como Alex Stragies indica.

Sem um serviço de camada intermediária, os problemas básicos são: (1) que os dados não podem ser gravados na rede a menos que haja alguém na outra ponta procurando por ele e (2) que as conexões TCP sejam bidirecionais. / p>

Como você não pode gravar dados na rede a menos que alguém esteja ouvindo, você deve sempre iniciar o ouvinte antes para enviar dados. (Em um sistema de transmissão de mensagens, o processo que manipula as mensagens fornecerá algum tipo de buffer.)

Seu exemplo pode ser facilmente reescrito:

  • Primeiro inicie um ouvinte na máquina2 (o destino):

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

    No seu exemplo, isso seria

     nc -l 1234 | cat
    

    Isso bloqueará e aguardará que alguém envie alguns dados para a porta 1234.

  • Depois, você pode enviar alguns dados da máquina1 (a origem):

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

    No seu exemplo, isso seria

     echo "Hello" | nc machine2 1234
    

Se você quiser processar os dados recebidos de alguma forma e responder, poderá usar o recurso de coprocessamento do shell. Por exemplo, este é um servidor web muito simples (e muito teimoso):

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

Veja como a comunicação bidirecional é obtida entre o corpo principal do script e o coprocess usando os descritores de arquivo na matriz $ncfd .

    
por 05.12.2016 / 01:09
5

Se você quiser simplesmente conectar dois computadores usando um programa básico como nc, você pode redirecionar de / para /dev/tcp/<host>/<port> .

Estes não são dispositivos reais, mas uma ficção criada pelo bash, então coisas como cat /dev/tcp/foo/19 não funcionarão, mas cat < /dev/tcp/foo/19 será.

    
por 05.12.2016 / 16:30