Чи можна виставити тунель TCP в Linux як спеціальний пристрій символів?


10

Нещодавно в документації QNX я виявив, що вона дозволяє налаштовувати IPC на основі повідомлень між процесами на окремих фізичних машинах за допомогою послідовного пристрою ( dev/serX), і це змусило мене замислитись:

Чи можливо в Linux створити загальносистемний спеціальний пристрій для тунелю TCP / UDP? Щось на зразок ncstdin / stdout публічно викрито під / dev / щось.

Зрештою, я хотів би мати можливість написати щось у такий файл на одній машині та отримати його на іншому кінці, наприклад:

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

#machine2:
cat < /dev/somedev

Я поглянув на ncлюдину, але не знайшов жодного варіанту вказувати джерело / місце призначення, окрім stdio.



1
Почесна згадка: Пристрої налаштування тон / дотику можна створити в / dev, але вам доведеться робити інкапсуляцію IP-адрес на них самостійно. Надзвичайно корисний для деяких цілей.
pjc50

Відповіді:


19

socat можна зробити це та багато іншого з речами, що нагадують "потоки"

Щось із використанням цієї основної ідеї має зробити це за вас:

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

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

(адаптовано зі сторінки прикладів )

Якщо ви хочете зашифрувати, ви можете скористатись варіантом ssl-l:54321,reuseaddr,cert=server.pem,cafile=client.crt,forkна machine1 і щось подібне ssl:server-host:1443,cert=client.pem,cafile=server.crtна machine2

(Більше про socat ssl )


7

Повідомлення потрібно реалізувати на більш високому рівні; TCP не має поняття повідомлення - TCP-з'єднання передають потоки октетів.

Ви можете домогтися чогось подібного до того, що ви запитуєте ncі назвали труби , див man mkfifo. або перевірте, socatяк вказує Алекс Страгі.

Без сервісу середнього рівня основними проблемами є (1) те, що дані не можна записувати в мережу, якщо хтось на іншому кінці не прослуховує її, і (2), що з'єднання TCP мають двонаправлений характер.

Оскільки ви не можете записувати дані в мережу, якщо хтось не слухає їх, ви завжди повинні запускати слухача, перш ніж ви зможете надсилати дані. (У системі передачі повідомлень процес обробки повідомлень забезпечить певний тип буферизації.)

Ваш приклад можна легко переписати:

  • Спочатку запустіть слухача на machine2 (пункт призначення):

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

    У вашому прикладі це було б

     nc -l 1234 | cat
    

    Це заблокує і чекатиме, коли хтось надішле деякі дані до порту 1234

  • Тоді ви можете надіслати деякі дані з machine1 (джерело):

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

    У вашому прикладі це було б

     echo "Hello" | nc machine2 1234
    

Якщо ви хочете якимось чином обробити отримані дані та відповісти, ви можете скористатися засобом оброблення оболонки. Наприклад, це дуже простий (і дуже впертий) веб-сервер:

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

Подивіться, як досягається двонаправлена ​​комунікація між основним кодом сценарію та копроцесом за допомогою дескрипторів файлів у масиві $ncfd.


Ви праві, і я визнав це у відповіді. Неможливо мати символьний пристрій без якогось програмного забезпечення посередництва.
AlexP

Схоже, у вас там є UUOC.
Майкл Хемптон

1
@MichaelHampton: Це був приклад ОП. Я припускаю, що це catозначає "деякий процес читання для stdin".
AlexP

5

Якщо ви просто хочете підключити два комп'ютери за допомогою базової програми, наприклад nc, ви можете перенаправлятись з / на /dev/tcp/<host>/<port>.

Це не фактичні пристрої, а фантастика, створена bash, тож такі речі cat /dev/tcp/foo/19не працюватимуть, але cat < /dev/tcp/foo/19будуть.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.