当我输入匹配字符串的 iptables 规则时,--to
选项是>= 52
例子
iptables -I FORWARD 1 -m string --string anypattern --algo bm --to 100 -j DROP
上述代码正常运行,并阻止包含“anypattern”字符串的 IP 数据包。
现在,如果我将更改为--to
某个值< 52
,那么它将不起作用
iptables -I FORWARD 1 -m string --string anypattern --algo bm --to 50 -j DROP
而且ip包不会被拦截!
我是否遗漏了什么?或者这是一个 iptables 问题?
例子:
linux:~$ sudo iptables -I OUTPUT 1 -m string --algo bm --string 7oula --to 52 -j DROP
linux:~$ echo 7oulaaaaaaaaaaa | nc 212.227.247.109 80
^C #<---- Blocked here
linux:~$ sudo iptables -I OUTPUT 1 -m string --algo bm --string coula --to 51 -j DROP
linux:~$ echo coulaaaaaaaaaaa | nc 212.227.247.109 80
HTTP/1.1 400 Bad Request
Server: nginx
Date: Sun, 26 Jan 2020 15:35:55 GMT
Content-Type: text/html
Content-Length: 150
Connection: close
<html>
<head><title>400 Bad Request</title></head>
<body>
<center><h1>400 Bad Request</h1></center>
<hr><center>nginx</center>
</body>
</html>
答案1
请记住,偏移量不是相对于数据包有效负载部分的开始,而是包括数据包的标头部分。以下是示例数据包之一的 tcpdump 捕获,即:
echo zoulaaaaaaaaaaa | nc 192.168.111.1 80
导致:
2020-01-26 11:51:10.606417 IP 192.168.111.122.43372 > 192.168.111.1.80: Flags [P.], seq 1:17, ack 1, win 502, options [nop,nop,TS val 3518227831 ecr 86824426], length 16: HTTP
0x0000: 4500 0044 048c 4000 4006 d65b c0a8 6f7a E..D..@.@..[..oz
src-ip--
0x0010: c0a8 6f01 a96c 0050 8a87 b04c 40e2 7841 [email protected]
dst-ip-- spt dpt
0x0020: 8018 01f6 ad1e 0000 0101 080a d1b3 e577 ...............w
0x0030: 052c d5ea 7a6f 756c 6161 6161 6161 6161 .,..zoulaaaaaaaa
^
|_ Offset 52
0x0040: 6161 610a aaa.
通过修改你的实验性 iptables 规则如下:
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string boula --from 46 --to 51 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string coula --from 47 --to 52 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string doula --from 48 --to 53 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string eoula --from 49 --to 54 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string foula --from 50 --to 55 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string goula --from 51 --to 56 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string houla --from 52 --to 57 -j DROP
$ sudo iptables -I OUTPUT 1 -m string --algo bm --string ioula --from 53 --to 58 -j DROP
$ sudo iptables -v -x -n -L
Chain INPUT (policy ACCEPT 23 packets, 1800 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 11 packets, 1816 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "ioula" ALGO name bm FROM 53 TO 58
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "houla" ALGO name bm FROM 52 TO 57
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "goula" ALGO name bm FROM 51 TO 56
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "foula" ALGO name bm FROM 50 TO 55
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "eoula" ALGO name bm FROM 49 TO 54
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "doula" ALGO name bm FROM 48 TO 53
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "coula" ALGO name bm FROM 47 TO 52
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "boula" ALGO name bm FROM 46 TO 51
to
我们可以尝试更深入地了解和参数的解释from
:
doug@rpi01:~ $ echo boulaaaaaaaaaaa | nc 192.168.111.1 80
Worked...
doug@rpi01:~ $ echo coulaaaaaaaaaaa | nc 192.168.111.1 80
^C HTTP packet blocked
doug@rpi01:~ $ echo doulaaaaaaaaaaa | nc 192.168.111.1 80
^C HTTP packet blocked
doug@rpi01:~ $ echo eoulaaaaaaaaaaa | nc 192.168.111.1 80
^C HTTP packet blocked
doug@rpi01:~ $ echo foulaaaaaaaaaaa | nc 192.168.111.1 80
^C HTTP packet blocked
doug@rpi01:~ $ echo goulaaaaaaaaaaa | nc 192.168.111.1 80
^C HTTP packet blocked
doug@rpi01:~ $ echo houlaaaaaaaaaaa | nc 192.168.111.1 80
^C HTTP packet blocked
doug@rpi01:~ $ echo ioulaaaaaaaaaaa | nc 192.168.111.1 80
Worked...
doug@rpi01:~ $ sudo iptables -v -x -n -L
Chain INPUT (policy ACCEPT 742 packets, 71452 bytes)
pkts bytes target prot opt in out source destination
Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
pkts bytes target prot opt in out source destination
Chain OUTPUT (policy ACCEPT 509 packets, 59196 bytes)
pkts bytes target prot opt in out source destination
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "ioula" ALGO name bm FROM 53 TO 58
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "houla" ALGO name bm FROM 52 TO 57
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "goula" ALGO name bm FROM 51 TO 56
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "foula" ALGO name bm FROM 50 TO 55
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "eoula" ALGO name bm FROM 49 TO 54
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "doula" ALGO name bm FROM 48 TO 53
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "coula" ALGO name bm FROM 47 TO 52
0 0 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "boula" ALGO name bm FROM 46 TO 51
从手册页中:
--from offset
Set the offset from which it starts looking for any matching. If not passed, default is 0.
--to offset
Set the offset up to which should be scanned. That is, byte offset-1 (counting from 0) is the last one that is scanned. If not passed, default is the packet size.
我假设这to
意味着要检查数据包的最后一个字节。因此,我本来预计这些数据包中只有一个被阻止,而不是 6 个。但是,根据手册页描述,当匹配窗口中包含字节 52(字符串起始字符)时,结果大多是有意义的。但是,这一行:
11 748 DROP all -- * * 0.0.0.0/0 0.0.0.0/0 STRING match "coula" ALGO name bm FROM 47 TO 52
这没有意义,因为字节 52 应该被排除作为模式起始字节。
编辑:我调查了一下。我回答中的示例来自 5.2 版之前的内核。这个问题似乎已在内核 5.2-rc1 中得到修复,上面的行现在不会阻止数据包。