![使用 grep 和 sed 的 tail -f 输出作为参数源进行命令替换,放入 'at' 命令中](https://linux22.com/image/984127/%E4%BD%BF%E7%94%A8%20grep%20%E5%92%8C%20sed%20%E7%9A%84%20tail%20-f%20%E8%BE%93%E5%87%BA%E4%BD%9C%E4%B8%BA%E5%8F%82%E6%95%B0%E6%BA%90%E8%BF%9B%E8%A1%8C%E5%91%BD%E4%BB%A4%E6%9B%BF%E6%8D%A2%EF%BC%8C%E6%94%BE%E5%85%A5%20'at'%20%E5%91%BD%E4%BB%A4%E4%B8%AD.png)
这是用于家庭监控系统、运行 Ubuntu 15.04 的无头服务器,我希望它的安全性堪称典范。我设想了一个命令行解决方案(如果绝对必要,可以使用可选脚本)监控记录在我的 ufw.log 中的旁观者/黑客的 IP 探测,如果他们没有及时正确地进行端口敲击,则实时将其列入黑名单。到目前为止,我已经:
tail -n+1 -F /var/log/ufw.log |
grep -v --line-buffered '0.0.0.0' |
sed -e 's/BLOCK/&/g' -e 's/.*SRC\=//g' -e 's/\ DST.*//g'
它将实时探测命中 IP 流输出到 stdout。这些是我想从“现在”开始 x (3?) 分钟内列入黑名单的 IP。这让合法用户有时间通过端口敲击首先被列入白名单。我使用 ufw insert 命令进行黑名单和白名单,这意味着先列入名单的 IP 占主导地位。
白名单部分现在运行良好。接下来我想开发“at”命令,以正确执行ufw insert 1 deny from x.x.x.x
xxxx 来自上述 tail 命令的命令。
我的第一次尝试是这样的
ufw insert 1 deny from $(tail -n+1 -F /var/log/ufw.log |
grep -v --line-buffered '0.0.0.0' |
sed -e 's/BLOCK/&/g' -e 's/.*SRC\=//g' -e 's/\ DST.*//g');
ufw reload |
at now +3 minute`
但at
如图所示,没有生成任何命令at -l
。有人能看出我在该命令中做错了什么吗?
新想法 - 我认为该tail -F
命令必须是开头。任何其他方法似乎都只能处理 ufw 日志文件中的一行。
您可能已经好奇了,我现在制定的端口敲击规则可以并且确实会列入黑名单,但非常有限,因为我必须在规则中提前定义探测行为。因此,如果他们两次访问端口 22 或两次访问端口 21 或两次访问端口 443,他们现在就会被列入黑名单。但我看到对 55xxx 范围内的端口进行探测,对不同端口进行 4 或 5 次探测。我不明白如何在防火墙规则中合理地描述这些,但我肯定能要做的是使用 ufw 将所有通过白名单和黑名单的探测记录到最后的拒绝+日志部分。我想给他们 x 分钟的时间来正确地进行端口敲击,然后由“at”部分安排的此命令的“ufw”部分将执行。
谢谢你!
muru 让我非常接近了。这是当前的进展状态,但请注意,ufw 容易出现此错误: 因此,我认为它与 iptables 配合得不够好,无法很好地处理此集成。我认为最好直接使用 iptable 命令,而不是让 ufw 解释。ERROR: initcaps
[Errno 2] iptables: Chain already exists.
tail -F /var/log/ufw.log |
grep -v --line-buffered '0.0.0.0' |
sed -e 's/BLOCK/&/g' -e 's/.*SRC\=//g' -e 's/\ DST.*//g' |
while read IP; do
echo ufw insert 1 deny from "$IP" |
at now +3 minute;
echo ufw reload | at now +3 minute;
done
请注意,反引号不会显示在此文本中,但我认为我需要添加它们。它们位于每个 ECHO 命令之前和每个 MINUTE 关键字之后。
现在失败的原因与“tail -F”通过管道传输到“while”结构有关:每行附加到 ufw.log 文件时,整个文件都会重新输入到“while”循环中,而不仅仅是新附加的行。我费尽心机也找不到解决这个问题的方法。请帮忙。
答案1
除非ufw reload
输出ufw insert
一组重新加载防火墙的命令,否则将其通过管道传输at
并不是您想要的。
你的意思:
echo ufw insert 1 deny from $(tail -n+1 -F /var/log/ufw.log |
grep -v --line-buffered '0.0.0.0' |
sed -e 's/BLOCK/&/g' -e 's/.*SRC\=//g' -e 's/\ DST.*//g') | at now +3 minute
echo ufw reload | at now +3 minute
或者合并起来:
at now +3 minute <<EOF
ufw insert 1 deny from $(tail -n+1 -F /var/log/ufw.log | grep -v --line-buffered '0.0.0.0' | sed -e 's/BLOCK/&/g' -e 's/.*SRC\=//g' -e 's/\ DST.*//g')
ufw reload
EOF
答案2
我需要的修复:stdbuf -o0
针对命令行中包含的 sed 和 awk,如下所示:
尾部-F /var/log/ufw.log | grep --line-buffered ......|标准库-o0sed......|标准库-o0哎......|
也可以与 grep 一起使用stdbuf -o0
,而不是 --line-buffered。这就是它的作用stdbuf -o0
- 它使用行缓冲区,而这正是我的情况中命令所需要的。当然,命令的其余部分需要组装并回显到“at”,但一旦我掌握了行缓冲方面,这部分对我来说就足够简单了(大量使用 awk)。我最终需要一个脚本来轻松手动输入这些要列入黑名单的 IP 地址,以及下面提到的一两个额外任务。
我使用 crontab 中上述命令启动进程 @reboot,其中 iptables 记录探测数据包。该命令将每个探测 IP 地址连同时间和数据包详细信息发送到 bash 脚本中。该 bash 脚本在构建最终的 iptables 黑名单命令时,跟踪 /var/log/knockd.log 以查找敲击序列是否已成功开始(“第 n 阶段”),在这种情况下,它会将脚本构建的 blacklist-IP 命令版本发送到 'at',以便在 3 分钟后进入黑名单。否则,脚本构建的 blacklist-IP 命令将立即运行。如果端口敲击成功,则 IP 将被列入白名单 [FUTURE - 这会阻止计划的 blacklist-IP 命令成功执行(“at”中计划的命令版本将首先检查白名单中是否存在 IP)]。
我正在进行最后的润色,比如使用“at”计划版本来检查白名单是否存在。我停止使用 ufw,通过直接控制 iptables 来简化我的生活。也没有 fail2ban,因为对我来说,它太臃肿了,只是为了保护一个私有的、仅限白名单的系统。现在,只要我的系统上的任何端口被探测一次,该 IP 地址就会被列入黑名单。以下是我的 iptables 中的几行,黑名单在白名单之后,未显示的是末尾的 LOG 和 DROP 规则(仅当策略 = ACCEPT 时才需要 DROP)。稍后我会在需要时将其压缩到子网中。
(抱歉,格式丢失了)链输入(策略接受 0 个数据包,0 字节)num pkts 字节目标协议选择加入出源目标
1 0 0 接受所有 -- eth0 * xxx.72.26.233 0.0.0.0/0
2 592 53357 接受所有 -- * * 0.0.0.0/0 0.0.0.0/0 ctstate RELATED,ESTABLISHED 3 98 5922 接受所有 -- lo * 0.0.0.0/0 0.0.0.0/0
4 0 0 接受所有 -- eth1 * 0.0.0.0/0 0.0.0.0/0
5 1 60 接受所有 -- eth0 * xx.179.31.188 0.0.0.0/0 /* 已于 10 月 25 日星期日关闭2015 年 16:33:53 CDT */ 6 0 0 接受全部 -- eth0 * xxx.32.31.196 0.0.0.0/0 /* isp 服务器 2015 年 10 月 26 日星期一 12:43:59 CDT */ 7 0 0 接受全部 -- eth0 * xxx.142.225.5 0.0.0.0/0 /* isp 服务器 2015 年 10 月 26 日星期一 12:43:45 CDT */ 8 0 0 接受全部 -- eth0 * xxx.32.31.195 0.0.0.0/0 /* isp 服务器 2015 年 10 月 26 日星期一 12:43:31 CDT */ 9 0 0 接受全部 -- eth0 * xxx.72.26.254 0.0.0.0/0 /* isp 服务器 2015 年 10 月 26 日星期一 12:43:11 CDT */ 10 1 118 DROP 全部 -- eth0 * 185.86.148.68 0.0.0.0/0 /* kern.log 10 月 27 日 22:29:53 PROTO=UDP SPT=56177 DPT=1900 */ 11 0 0 DROP 全部 -- eth0 * 184.105.247.220 0.0.0.0/0 /* kern.log 10 月 27 日 22:22:30 PROTO=UDP SPT=53700 DPT=53413 */ 12 0 0 DROP 全部 -- eth0 * 195.211.154.179 0.0.0.0/0 /* kern.log 10 月 27 日22:21:49 PROTO=TCP SPT=48465 DPT=21320 */ 13 2 120 DROP 全部 -- eth0 * 75.111.59.88 0.0.0.0/0 /* kern.log 十月 27 22:21:37 PROTO=TCP SPT=35727 DPT=23 */ 14 0 0 DROP 全部 -- eth0 * 74.82.47.16 0.0.0.0/0 /* kern.log 十月 27 22:17:34 PROTO=TCP SPT=38695 DPT=27017 */ 15 0 0 DROP 全部 -- eth0 * 1.93.3.124 0.0.0.0/0 /* kern.log 十月 27 22:16:33 PROTO=TCP SPT=1414 DPT=1433 */ 16 0 0 全部删除 -- eth0 * 184.105.139.96 0.0.0.0/0 /* kern.log 十月 27 22:12:42 PROTO=UDP SPT=51153 DPT=123 */ 17 0 0 全部删除 -- eth0 * 121.230.163.125 0.0.0.0/0 /* kern.log 十月 27 21:57:06 PROTO=ICMP */ 18 0 0 全部删除 -- eth0 * 120.132.50.66 0.0.0.0/0 /* kern.log 十月 27 21:53:30 PROTO=TCP SPT=51864 DPT=1023 */