3

这是我第一次为 iptables 使用匹配字符串模块并且遇到了一些我无法克服的奇怪行为。

简而言之,看起来 iptables 将“修剪”的数据包传递给模块,因此模块无法将整个数据包解析为字符串。我在网上找不到有关此类行为的任何信息。所有示例和导师都应该像魅力一样工作,但事实并非如此。

现在详细介绍。

OS: debian testing, kernel 3.2.0-3-686-pae
IPTABLES: iptables v1.4.14
OTHER:

 tcpdump version 4.3.0,
 libpcap version 1.3.0

# lsmod|grep ipt
ipt_LOG                12533  0
iptable_nat            12800  0
nf_nat                 17924  1 iptable_nat
nf_conntrack_ipv4      13726  3 nf_nat,iptable_nat
nf_conntrack           43121  3 nf_conntrack_ipv4,nf_nat,iptable_nat
iptable_filter         12488  0
ip_tables              17079  2 iptable_filter,iptable_nat
x_tables               18121  6
ip_tables,iptable_filter,iptable_nat,xt_string,xt_tcpudp,ipt_LOG

我已将所有规则重置为默认规则,并按以下顺序仅添加了两条规则:

iptables -t filter -A OUTPUT --protocol tcp --dport 80 --match string --algo bm --from 0 --to 1500 --string "/index.php" --jump LOG --log-prefix "matched :"
iptables -t filter -A OUTPUT --protocol tcp --dport 80 --jump LOG --log-prefix "OUT : " 

这个想法很糟糕 - 将任何 ip 的请求匹配到包含字符串 /index.php 的端口 80 并将它们打印到日志中,并将所有传递到 80 端口的数据记录下来。

所以 iptables -L -xvn :

Chain INPUT (policy ACCEPT 3 packets, 693 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 3 packets, 184 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       0        0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "/index.php" ALGO name bm TO 1500 LOG flags 0 level 4 prefix "matched :"
       0        0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 LOG flags 0 level 4 prefix "OUT : "

规则计数器清零。

好的,现在浏览器转到 www.gentoo.org/index.php。此网址仅作说明之用。所以这是浏览器中唯一的请求 url。对于 iptables -t filter -L -xvn,我得到以下信息:

Chain INPUT (policy ACCEPT 61 packets, 16657 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 63 packets, 4394 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       1      380 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "/index.php" ALGO name bm TO 1500 LOG flags 0 level 4 prefix "matched :"
      13     1392 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 LOG flags 0 level 4 prefix "OUT : "

所以我们只有一个匹配第一条规则。但这是错误的。这是用于连接输出的 tcpdump。第一个ip请求89.16.167.134:

<handshake omitted>
16:56:38.440308 IP 192.168.66.106.54704 > 89.16.167.134.80: Flags [P.], seq 1:373, ack 1, win 913, 
options [nop,nop,TS val 85359 ecr 3026115253], length 372
<...>
    0x0030:  b45e dab5 4745 5420 2f69 6e64 6578 2e70  .^..GET./index.p
    0x0040:  6870 2048 5454 502f 312e 310d 0a48 6f73  hp.HTTP/1.1..Hos
    0x0050:  743a 2077 7777 2e67 656e 746f 6f2e 6f72  t:.www.gentoo.or
    0x0060:  670d 0a55 7365 722d 4167 656e 743a 204d  g..User-Agent:.M
    0x0070:  6f7a 696c 6c61 2f35 2e30 2028 5831 313b  ozilla/5.0.(X11;

在这里,我们在 HTTP GET 中看到了一个匹配项。好的一些数据包稍后我们请求更多内容到 ip 140.211.166.176:

16:56:38.772432 IP 192.168.66.106.59766 > 140.211.166.176.80: Flags [P.], seq 1:329, ack 1, win 913, 
options [nop,nop,TS val 85442 ecr 110101513], length 328
<...>
    0x0030:  0690 0409 4745 5420 2f20 4854 5450 2f31  ....GET./.HTTP/1
<...>
    0x0130:  6566 6c61 7465 0d0a 436f 6e6e 6563 7469  eflate..Connecti
    0x0140:  6f6e 3a20 6b65 6570 2d61 6c69 7665 0d0a  on:.keep-alive..
    0x0150:  5265 6665 7265 723a 2068 7474 703a 2f2f  Referer:.http://
    0x0160:  7777 772e 6765 6e74 6f6f 2e6f 7267 2f69  www.gentoo.org/i
    0x0170:  6e64 6578 2e70 6870 0d0a 0d0a            ndex.php....

在这里,我们再次看到“/index.php”。

但是 LOG 规则给出了以下信息:

kernel: [  641.386182] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=89.16.167.134 LEN=60
kernel: [  641.435946] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=89.16.167.134 LEN=52
kernel: [  641.436226] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=89.16.167.134 LEN=424
kernel: [  641.512594] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=89.16.167.134 LEN=52
kernel: [  641.512762] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=89.16.167.134 LEN=52
kernel: [  641.512819] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=89.16.167.134 LEN=52
kernel: [  641.567496] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=60
kernel: [  641.767707] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=52
kernel: [  641.768328] matched :IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=380 <--
kernel: [  641.768352] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=380
kernel: [  641.990287] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=52
kernel: [  641.990455] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=52
kernel: [  641.990507] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=52
kernel: [  641.990559] OUT : IN= OUT=eth0 SRC=192.168.66.106 DST=140.211.166.176 LEN=52

所以我们只有一个数据包匹配,到 140.211.166.176。但是第一场比赛在哪里?对我来说更奇怪的是,在装有 ubuntu 的机器上,它给出了不同的计数器,比如字符串的 6 个匹配项。

我还在使用 ubuntu 12.04 的家用笔记本上进行了同样的简单测试,我得到了 2 个明确的匹配项。

Mb 有一些选项来调整模块数据传递或 smth?

更新:

非常简单的实验 mb 如果有人能解释那一刻它会给出提示。

现在两台电脑,服务器 centos 6.3 使用 netcat ans 监听端口 80 回答字符串:

# echo "List-IdServer"|nc -l 80
List-Id

客户端(debian)连接到服务器并使用 nc 发送数据并读取答案:

% echo "List-Id"|nc butorabackup 80
List-IdServer

数据交换后,我在服务器端:

Chain INPUT (policy ACCEPT 33 packets, 2164 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       1       60 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80 STRING match "List-Id" ALGO name bm TO 6500 LOG flags 0 level 4 
       5      276 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80 LOG flags 0 level 4 

Chain FORWARD (policy DROP 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 23 packets, 4434 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       0        0 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp spt:80 STRING match "List-Id" ALGO name bm TO 6500 LOG flags 0 level 4 
       5      282 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp spt:80 LOG flags 0 level 4 

在客户端:

Chain INPUT (policy ACCEPT 28 packets, 2187 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       1       66 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:80 STRING match  "List-Id" ALGO name bm TO 6500 LOG flags 0 level 4
       5      282 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp spt:80 LOG flags 0 level 4

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
    pkts      bytes target     prot opt in     out     source               destination         

Chain OUTPUT (policy ACCEPT 23 packets, 1721 bytes)
    pkts      bytes target     prot opt in     out     source               destination         
       1       60 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 STRING match  "List-Id" ALGO name bm TO 6500 LOG flags 0 level 4
       5      276 LOG        tcp  --  *      *       0.0.0.0/0            0.0.0.0/0            tcp dpt:80 LOG flags 0 level 4

所以服务器没有输出规则匹配。服务器匹配 IN,客户端匹配 IN 和 OUT。

我不明白它是如何工作的:(

提前Tnx。

4

0 回答 0