Apakah mungkin untuk mengekspos terowongan TCP di Linux sebagai perangkat karakter khusus?

10

Baru-baru ini saya menemukan dalam dokumentasi QNX bahwa memungkinkan untuk mengatur IPC berbasis pesan antara proses pada mesin fisik yang terpisah dengan menggunakan perangkat serial ( dev/serX) dan itu membuat saya bertanya-tanya:

Apakah mungkin di Linux untuk membuat perangkat khusus seluruh sistem untuk terowongan TCP / UDP? Sesuatu seperti ncstdin / stdout diekspos secara publik di bawah / dev / something.

Pada akhirnya saya ingin dapat menulis sesuatu ke file tersebut di satu mesin dan menerimanya di ujung lain misalnya:

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

#machine2:
cat < /dev/somedev

Saya melihat ncpria tetapi saya tidak menemukan opsi untuk menentukan sumber io / tujuan selain stdio.

Lapsio
sumber
Lihat Mengapa antarmuka jaringan tidak di / dev seperti perangkat lain? yang mencakup bagian "kenapa tidak".
Gilles 'SO- stop being evil'
1
Sebutan terhormat: Perangkat tun / tap dapat dibuat di / dev, tetapi Anda harus melakukan enkapsulasi IP sendiri. Sangat berguna untuk beberapa keperluan.
pjc50

Jawaban:

19

socat dapat melakukan ini dan banyak hal lain dengan hal-hal yang menyerupai "aliran"

Sesuatu yang menggunakan ide dasar ini harus melakukannya untuk Anda:

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

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

(diadaptasi dari Halaman Contoh )

Jika Anda ingin mengenkripsi, Anda bisa menggunakan variasi ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forkpada machine1, dan sesuatu seperti ssl:server-host:1443,cert=client.pem,cafile=server.crtpada machine2

(Lebih lanjut tentang socat ssl )

Alex Stragies
sumber
7

Penyampaian pesan perlu diimplementasikan pada lapisan yang lebih tinggi; TCP tidak memiliki gagasan tentang pesan - koneksi TCP mentransfer aliran oktet.

Anda dapat mencapai sesuatu seperti apa yang Anda minta ncdan beri nama pipa , lihat man mkfifo; atau periksa socatseperti yang ditunjukkan Alex Stragies.

Tanpa layanan lapisan tengah, masalah dasarnya adalah (1) bahwa data tidak dapat ditulis ke jaringan kecuali ada orang di ujung lain yang mendengarkannya, dan (2) bahwa koneksi TCP bersifat dua arah.

Karena Anda tidak dapat menulis data ke jaringan kecuali seseorang mendengarkannya, Anda harus selalu memulai pendengar sebelum Anda dapat mengirim data. (Dalam sistem pesan lewat proses penanganan pesan akan memberikan semacam buffering.)

Contoh Anda dapat dengan mudah ditulis ulang:

  • Pertama mulai pendengar di machine2 (tujuan):

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

    Dalam contoh Anda, ini akan menjadi

     nc -l 1234 | cat
    

    Ini akan memblokir dan menunggu seseorang mengirim beberapa data ke port 1234.

  • Kemudian Anda dapat mengirim beberapa data dari machine1 (sumber):

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

    Dalam contoh Anda, ini akan menjadi

     echo "Hello" | nc machine2 1234
    

Jika Anda ingin memproses data yang diterima dengan cara tertentu dan meresponsnya, Anda dapat menggunakan fasilitas pemrosesan shell. Sebagai contoh, ini adalah server web yang sangat sederhana (dan sangat keras kepala):

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

Lihat bagaimana komunikasi dua arah dicapai antara badan utama skrip dan proses-proses menggunakan deskriptor file dalam array $ncfd.

AlexP
sumber
Anda benar, dan saya telah mengakui hal itu dalam jawabannya. Tidak dapat memiliki perangkat karakter tanpa semacam perantaraan perangkat lunak.
AlexP
Sepertinya Anda memiliki UUOC di sana.
Michael Hampton
1
@MichaelHampton: Itu adalah contoh yang diberikan oleh OP. Saya kira itu catsingkatan dari "beberapa proses membaca untuk stdin".
AlexP
5

Jika Anda hanya ingin menghubungkan dua komputer menggunakan program dasar seperti nc Anda dapat mengalihkan dari / ke /dev/tcp/<host>/<port>.

Ini bukan perangkat yang sebenarnya tetapi sebuah fiksi yang dibuat oleh bash, jadi hal-hal seperti cat /dev/tcp/foo/19tidak akan berfungsi, tetapi cat < /dev/tcp/foo/19akan.

Malaikat
sumber