当 --to 选项小于 52 时,iptables 字符串匹配不起作用

当 --to 选项小于 52 时,iptables 字符串匹配不起作用

当我输入匹配字符串的 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 中得到修复,上面的行现在不会阻止数据包。

相关内容