Jak ustawić skrypt, który będzie wykonywany, gdy port odbierze komunikat

12

Zastanawiam się, jak zdobyć skrypt powłoki, aby nasłuchiwał na określonym porcie (może używając netcata?). Mamy nadzieję, że gdy wiadomość zostanie wysłana do tego portu, skrypt nagrywa wiadomość, a następnie uruchamia funkcję.

Przykład:

  1. Komputer 1 ma skrypt działający w tle, skrypt otworzył port 1234 dla ruchu przychodzącego

  2. Komputer 2 wysyła komunikat „witaj świecie” na porcie 1234 komputera 1

  3. Skrypt na komputerze 1 rejestruje komunikat „witaj świecie” w zmiennej $ MESSAGE

  4. Skrypt działa teraz, gdy ustawiono zmienną $ MESSAGE

Jak mam to zrobić?

Daniel
źródło

Odpowiedzi:

12

Powinno być możliwe z socat.

Napisz taki skrypt „getmsg.sh”, aby otrzymać jedną wiadomość przez stdin:

#!/bin/bash
read MESSAGE
echo "PID: $$"
echo "$MESSAGE"

Następnie uruchom to socatpolecenie, aby wywołać nasz skrypt dla każdego połączenia TCP na porcie 7777:

socat -u tcp-l:7777,fork system:./getmsg.sh

Wyślij wiadomość testową z innej powłoki:

echo "message 1" | netcat localhost 7777
rudimeier
źródło
Przetestowałeś to?
Przepisane i przetestowane teraz;)
rudimeier
1
Zainspirowałem się twoim rozwiązaniem i znalazłem sposób, który działa z netcat: nc -l 7777 | ./getmsg.sh
Daniel
Cieszę się, że to słyszę. Ale netcatistnieje po jednym połączeniu. socatzrobiłby to samo, jeśli usuniesz „, fork” z mojej linii poleceń.
rudimeier
7

Sposób UCSPI-TCP

Istnieją zestawy narzędzi inne niż netcat. Oto jak korzystać z kilku z nich. Wszyscy zakładają istnienie serviceskryptu, który uruchamia twój func, cokolwiek to może być:

#! / bin / sh
podczas odczytu -r WIADOMOŚĆ
zrobić
    echo 1> i 2 "$ {TCPREMOTEIP}" "$ {TCPREMOTEPORT}" rx "$ {MESSAGE}"
    func
gotowy

Te TCPREMOTEIPi TCPREMOTEPORTśrodowisko zmienne są zdefiniowane przez protokół ucspi-TCP.

Skrypt jest spawany jako osobny proces dla każdego połączenia TCP przy użyciu różnych zestawów narzędzi. W dalszej części narzędzia są pokazane jako używane w krótkim skrypcie. Taki skrypt, konwencjonalnie nazwany run, jest sposobem, w jaki można go uruchomić w menedżerze usług daemontools-family. Można je oczywiście wywoływać bezpośrednio.

Bernstein ucspi-tcp

Dzięki ucspi-tcp Daniela J. Bernsteina tcpserverspawnuje serviceskrypt:

#! / bin / sh -e
exec tcpserver -v -P -R -H-l 0 0.0.0.0 7777 ./service

Istnieją ulepszone wersje Bernstein ucspi-tcp z obsługą IPv6. W przypadku Erwina Hoffmana tcpserverpróbuje on obsługiwać zarówno IPv4, jak i IPv6 w jednym (jeśli system operacyjny to obsługuje, kilka nie) i uruchamia serviceskrypt:

#! / bin / sh -e
exec tcpserver -v -P -R -H-l 0 :: 0 7777 ./service

Bercot s6-networking, s6 i execline

Laurent Bercot za s6 dostępem do sieci, s6-tcpserver4a s6-tcpserver6uchwyt IPv4 i IPv6 oddzielnie i ikra serviceskrypt:

#! / command / execlineb
s6-tcpserver4 -v 0.0.0.0 7777 
./usługa
#! / command / execlineb
s6-tcpserver6 -v :: 0 7777 
./usługa

Można budować bardziej złożone serwery, interpretując narzędzia takie jak s6-tcpserver-accessiw s6-applyuidgidłańcuchu bezpośrednio przed nim ./service.

Narzędzia UCSPI firmy nosh

Dzięki zestawowi narzędzi nosh tcp-socket-listennasłuchuje na gnieździe TCP, ponownie obsługując jednocześnie IPv4 i IPv6, jeśli system operacyjny to obsługuje, i łańcuchy, do tcp-socket-acceptktórych z kolei spawnuje serviceskrypt:

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
tcp-socket-accept --verbose - nazwa_lokalna 0
./usługa

Lub jeden uruchamia dwa osobne procesy w systemach operacyjnych takich jak OpenBSD:

#! / bin / nosh
tcp-socket-listen 0.0.0.0 7777
tcp-socket-accept --verbose - nazwa_lokalna 0
./usługa
#! / bin / nosh
tcp-socket-listen :: 7777
tcp-socket-accept --verbose - nazwa_lokalna ::
./usługa

Można budować bardziej złożone serwery, interpretując narzędzia takie jak ucspi-socket-rules-checki setuidgidw łańcuchu.

#! / bin / nosh
tcp-socket-listen --combine4and6 :: 7777
setuidgid nieuprzywilejowany użytkownik
tcp-socket-accept --verbose - nazwa_lokalna 0
ucspi-socket-rules-check --verbose
./usługa

Pape ipsvd

Z ipsvd Gerrit Pape, tcpsvdspawnuje serviceskrypt:

#! / bin / sh -e
exec tcpsvd -v 0.0.0.0 7777 ./service

UCSPI-UDP

Wspólny serviceskrypt może obsłużyć, gdy standardowym wejściem jest gniazdo strumienia . Ale nie określiłeś jawnie TCP.

Chociaż niektóre z wyżej wymienionych zestawów narzędzi mogą być używane do budowania serwerów UDP w podobny sposób, jak można ich używać do budowania serwerów TCP (por. udp-socket-listenNosh), trudno jest zbudować rzeczywisty program usługowy za pomocą skryptu powłoki, ponieważ wbudowane powłoki nie koniecznie radzą sobie dobrze, gdy standardowym wejściem jest gniazdo datagramu .

Dalsza lektura

JdeBP
źródło
0

Można to również zrobić za pomocą tego, udpsvdktóry jest dostępny na Ubuntu / Debian ( patrz strona man ), a także wbudowany w busybox. Przykład:

# simple UDP "echo" on port 9998
udpsvd 0.0.0.0 9998 cat

Zastąp catskryptem powłoki, aby wykonać, stdin to pakiet.

Za pomocą netcatmożesz biegać w pętli, aby słuchać i przekazywać każdy pakiet do myscript:

 while true; do nc -ul 9998 | myscript.sh; done

Jeśli chcesz przekazać wszystkie otrzymane pakiety jako strumień do pojedynczego wywołania skryptu:

# this will keep listening instead of terminating the process:
nc -kul 9998 |myscript.sh
thom_nic
źródło