因此,我打开了一个 SSH 反向隧道,并使用tail
管道将 sshd 日志的输出传输到其中,awk
以检测某些登录事件并触发操作。它看起来像这样:
ssh -NR 2222:127.0.0.1:22 server &
tail -fn 0 /var/log/auth.log | \
awk '/Invalid user [a-z]+ from 127.0.0.1/
{system("rsync -a source dest")}'
(需要明确的是,我自己有意从服务器启动这些失败的登录,作为在客户端计算机上触发 rsync 的一种方式,正如我在这个线程.)
我现在想做的是能够暂停整个检测过程,以便我可以让它忽略给定的登录尝试。我的想法是做三件事之一:
- 防止
ssh
产生“无效用户”消息, - 阻止
tail
输出它,或者 - 防止
awk
看到它。
我尝试暂停然后恢复所有三个进程,结果如下:
SSH:当隧道暂停时,服务器在尝试连接回客户端时会无限期等待。如果我ConnectionTimeout
在从服务器连接时指定一个选项,我可以使连接失败并让它产生不同的错误消息 – 成功! – 但我觉得这种方法是在竞争条件上自找麻烦。
尾部和 awk:当这些程序暂停时,输入会被累积,而不是被忽略。输出仅被抑制,直到进程恢复为止。
有什么办法可以实现我所追求的目标吗?
答案1
您只能暂停awk
并冲洗正在从其脚下读取的管道,然后再恢复。在基于 Linux 的系统和 GNU 上dd
:
$pid
PID是awk
:
kill -s STOP "$pid"
阻止它并且
dd iflag=nonblock if="/proc/$pid/fd/0" > /dev/null; kill -s CONT "$pid"
恢复。
这是假设管道没有满(Linux 上默认为 64KiB),否则tail
也可能被阻止。要解决这个问题,您可以使用以下方法冲洗管道:
socat -T0.2 -u "/proc/$pid/fd/0" /dev/null
这将刷新管道中当前的内容并继续读取,直到 0.2 秒内不再有任何内容,以便能够tail
赶上尚未从文件中读取的内容(如果有)。