UCSPI-TCP方式

UCSPI-TCP方式

我想知道如何让 shell 脚本监听某个端口(也许使用 netcat?)。希望当消息发送到该端口时,脚本会记录该消息,然后运行一个函数。

例子:

  1. 计算机 1 在后台运行该脚本,该脚本向传入流量打开端口 1234

  2. 计算机2向计算机1的1234端口发送消息“hello world”

  3. 计算机 1 上的脚本将消息“hello world”记录到变量 $MESSAGE

  4. 现在变量 $MESSAGE 已设置,脚本运行函数

我该怎么做呢?

答案1

应该可以用socat.

编写这样一个脚本“getmsg.sh”以通过标准输入接收一条消息:

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

然后运行此socat命令为端口 7777 上的每个 tcp 连接调用我们的脚本:

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

从另一个 shell 发送测试消息:

echo "message 1" | netcat localhost 7777

答案2

UCSPI-TCP方式

除了 netcat 之外还有其他工具集。以下是其中一些的使用方法。他们都假设存在一个service运行您的脚本func,无论它是什么:

#!/bin/sh
读取时 -r MESSAGE
    echo 1>&2 "${TCPREMOTEIP}" "${TCPREMOTEPORT}" rx "${MESSAGE}"
    功能
完毕

TCPREMOTEIP和环境变量TCPREMOTEPORT由 UCSPI-TCP 协议定义。

该脚本是使用各种工具集作为每个 TCP 连接的单独进程生成的。接下来,这些工具将在一个简短的脚本中使用。这样的脚本通常称为run,是人们在 daemontools 系列服务管理器下运行它们的方式。当然可以直接调用它们。

伯恩斯坦 ucspi-tcp

使用 Daniel J. Bernstein 的 ucspi-tcp,tcpserver生成service脚本:

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

Bernstein ucspi-tcp 有支持 IPv6 的增强版本。 Erwin Hoffmantcpserver尝试将 IPv4 和 IPv6 合二为一(如果操作系统支持,有些操作系统不支持)并生成脚本service

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

Bercot s6-网络、s6 和 execline

使用 Laurent Bercot 的 s6 网络,分别s6-tcpserver4处理s6-tcpserver6IPv4 和 IPv6,并生成service脚本:

#!/command/execlineb
s6-tcpserver4 -v 0.0.0.0 7777
。/服务
#!/command/execlineb
s6-tcpserver6 -v ::0 7777
。/服务

人们可以通过在之前的链中插入诸如s6-tcpserver-access和 之类的工具来构建更复杂的服务器。s6-applyuidgid./service

nosh UCSPI 工具

使用 nosh 工具集,tcp-socket-listen侦听 TCP 套接字,如果操作系统支持,则再次同时处理 IPv4 和 IPv6,并tcp-socket-accept依次生成脚本service

#!/bin/nosh
tcp-socket-listen --combine4and6 :: 7777
tcp-socket-accept --verbose --localname 0
。/服务

或者在 OpenBSD 等操作系统上运行两个独立的进程:

#!/bin/nosh
TCP 套接字监听 0.0.0.0 7777
tcp-socket-accept --verbose --localname 0
。/服务
#!/bin/nosh
tcp-socket-监听::7777
tcp-socket-accept --verbose --localname ::
。/服务

人们可以通过在链中插入诸如ucspi-socket-rules-check和 等工具来构建更复杂的服务器。setuidgid

#!/bin/nosh
tcp-socket-listen --combine4and6 :: 7777
setuidgid 非特权用户
tcp-socket-accept --verbose --localname 0
ucspi 套接字规则检查 --verbose
。/服务

帕普 ipsvd

使用 Gerrit Pape 的 ipsvd,tcpsvd生成service脚本:

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

UCSPI-UDP

service当标准输入是一个时,通用脚本可以处理溪流插座。但您没有明确指定 TCP。

虽然前面提到的一些工具包可以用来构建 UDP 服务器,其方式与使用它们构建 TCP 服务器的方式类似(参见udp-socket-listennosh),但使用 shell 脚本构建实际的服务程序是很棘手的,因为 shell 的内置函数不支持这种方式。当标准输入是一个时,必然能够很好地应对数据报插座。

进一步阅读

答案3

udpsvd这也可以通过Ubuntu/Debian 上的可用工具来完成(参见联机帮助页)以及内置到 busybox 中。例子:

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

替换cat为要执行的 shell 脚本,stdin 是数据包。

使用netcat,您可以循环运行以继续监听,并将每个数据包传递到myscript

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

如果您想将所有收到的数据包作为流传递给脚本的单次调用:

# this will keep listening instead of terminating the process:
nc -kul 9998 |myscript.sh

相关内容