使用 IP 表进行 URL 过滤

使用 IP 表进行 URL 过滤

我一直在尝试使用Iptables.我设置了两个接口。流量从一个接口流入,从另一个接口流出。

以下是Iptables我已经配置的:

*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:TCPFILTER - [0:0]
:URLFILTER - [0:0]
#######################
-A INPUT -i lo -j ACCEPT
-A INPUT -p icmp -m icmp --icmp-type any -j ACCEPT
-A INPUT -m state --state ESTABLISHED,RELATED,NEW -j ACCEPT

#BGP
-A INPUT -p tcp -m state --state NEW -m tcp --dport 179 -j ACCEPT

# Pass traffic to filters which have TCP Flags PSH,ACK and DST Port 80

-A FORWARD -p tcp --tcp-flags PSH,ACK PSH,ACK --dport 80 -j TCPFILTER
-A FORWARD -p tcp --dport 80 -j TCPFILTER
-A FORWARD -j ACCEPT

# Further process only packets with HTTP Get Request

-A TCPFILTER -m string --string "GET /" --algo bm --from 1 --to 70 -j URLFILTER
-A TCPFILTER -j ACCEPT
-A URLFILTER -m string --algo bm --to 500 --string "Host: www.tutorialspoint.com" -p tcp -j REJECT --reject-with tcp-reset
-A URLFILTER -j ACCEPT
COMMIT

根据收到的数据包的 Wireshark 输出如下所示

在此输入图像描述

我相信它应该有效,但我没有在链上得到任何点击,URLFILTER如下所示:

    # iptables -L -v -n
Chain INPUT (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
    0     0 ACCEPT     all  --  lo     *       0.0.0.0/0            0.0.0.0/0
    7   352 ACCEPT     icmp --  *      *       0.0.0.0/0            0.0.0.0/0           icmp type 255
  108  6621 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW,RELATED,ESTABLISHED
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:2002
    0     0 ACCEPT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           state NEW tcp dpt:179

Chain FORWARD (policy ACCEPT 0 packets, 0 bytes)
 pkts bytes target     prot opt in     out     source               destination
   39 34674 TCPFILTER  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80 flags:0x18/0x18
  253 13392 TCPFILTER  tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           tcp dpt:80
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain OUTPUT (policy ACCEPT 75 packets, 13141 bytes)
 pkts bytes target     prot opt in     out     source               destination

Chain TCPFILTER (2 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 URLFILTER  all  --  *      *       0.0.0.0/0            0.0.0.0/0           STRING match "GET /" ALGO name bm FROM 1 TO 70
  292 48066 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

Chain URLFILTER (1 references)
 pkts bytes target     prot opt in     out     source               destination
    0     0 REJECT     tcp  --  *      *       0.0.0.0/0            0.0.0.0/0           STRING match "Host: www.tutorialspoint.com" ALGO name bm TO 500 reject-with tcp-reset
    0     0 ACCEPT     all  --  *      *       0.0.0.0/0            0.0.0.0/0

流量被接受并传递到TCPFILTER但无法与GET /字符串匹配。

任何帮助将不胜感激。

答案1

我找到了这不起作用的原因。

您不能依赖 netfilter 检查单个数据包上的整个 HTTP 请求。同一数据包不会匹配“GET /”和“Host:*”,因为该有效负载通过多个数据包传播。

考虑以下规则列表:

-A OUTPUT -p tcp -m tcp --dport 80 -j URLFILTER # would be FORWARD in your case
-A URLFILTER -m string --string "Host: www.kernel.org" --algo bm --from 1 --to 500 --icase -j LOG --log-prefix UF_MATCHHOST
-A URLFILTER -m string --string "GET /" --algo bm --from 1 --to 500 --icase -j LOG --log-prefix UF_MATCHGET

像这样对 www.kernel.org 的 HTTP 调用

GET / HTTP/1.0
Host: www.kernel.org

将以相反的顺序匹配两条规则,证明 URLFILTER 链被多个数据包遍历;第一个携带 GET 字符串,第二个携带主机字符串。因此,如果不进行进一步的工作,您就无法同时匹配 GET 和 Host。

[471493.767020] UF_MATCHGETIN= OUT=enp0s31f6 SRC=192.168.20.204 DST=147.75.205.195 LEN=67 TOS=0x00 PREC=0x00 TTL=64 ID=65494 DF PROTO=TCP SPT=51624 DPT=80 WINDOW=229 RES=0x00 ACK PSH URGP=0 
[471499.761216] UF_MATCHHOSTIN= OUT=enp0s31f6 SRC=192.168.20.204 DST=147.75.205.195 LEN=73 TOS=0x00 PREC=0x00 TTL=64 ID=65495 DF PROTO=TCP SPT=51624 DPT=80 WINDOW=229 RES=0x00 ACK PSH URGP=0 

也许您可以跟踪与 GET / 匹配的每个连接并匹配以下数据包,我认为这是可能的。

Netfilter 可以为您做到这一点,但它远不是完成这项工作的最佳工具。

原答案:

你的

-A TCPFILTER -m string --string "GET /" --algo bm --from 1 --to 70 -j URLFILTER

条目不匹配,您确定可以将字符串与原始 HTTP 流量进行匹配吗?您可以使用 tcpdump -vv 看到该字符串吗?你可以尝试一个更简单的匹配,看看是否有效?

您显示的wireshark输出是解析后的数据包,而不是iptables所看到的。您想要查看数据包的十六进制/ascii 有效负载以进行双重检查。

相关内容