Linux Iptables字符串模块与所有数据包都不匹配

时间:2012-11-16 08:35:03

标签: linux debian firewall iptables netfilter

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

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

现在详细说明。

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 : " 

这个想法很明智 - 将请求匹配到包含字符串/index.php的任何ip到端口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。这个网址只是举例说明。 所以这是浏览器中唯一的请求网址。 我得到以下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的ither机器上,它提供了不同的计数器,比如6个匹配的字符串。

我也使用ubuntu 12.04对家用笔记本进行了相同的简单测试,我得到了2个清晰的匹配。

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

更新

非常简单的实验,如果有人可以解释那一刻它会给出一个提示。

现在有两个pc,服务器centos 6.3,它使用netcat回听端口80并回答字符串:

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

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

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

我在SERVER SIDE上进行数据交换后:

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。

0 个答案:

没有答案