ps:前面部分是问题描述,解决办法在最后
以下规则是openWrt(也是linux)默认规则,
配置大概是这样:这是一个宽带路由器(NAT设备),WAN网口使用DHCP获取ip,LAN口也作为DHCP服务器。配置了SNAT(MASQUERADE)。正常情况下,通过WAN口上行的数据的源ip被改成路由器WAN口ip,下行数据通过connect track自动把目的地址替换成内网IP。linux版本 Linux OpenWrt 3.10.49 #7 Tue Sep 30 16:53:52 CST 2014 mips GNU/Linux
那么,问题来了,(假设内网某主机ip是192.168.1.128,测试过程中这台主机不间断高速下载)
现象是:
1、通过SNAT上网正常
2、通过 iptables -I FORWARD -d 192.168.1.128 -j DROP 想达到禁止下载,不生效,电脑正常下载
3、针对2的现象作调试:通过iptables -L FORWARD -nv查看统计,发现[color=Red]filter表FORWARD链无明显的大流量通过[/color]
4、针对2的现象作调试, 通过iptables -t mangle -L FORWARD -nv查看统计,发现[color=Red]mangle表FORWARD有明显流量通过[/color],目测接近下载速度。
5、通过 iptables -I FORWARD -s 192.168.1.128 -j DROP,生效,电脑不能下载(因为连接是双向的)
个人理解:根据iptables处理顺序,在FORWARD中,先执行mangle表、再执行filter表,除非mangle处理结果为DROP,否则数据将无条件经过filter
问:为什么下载时数据不经过FORWARD链的filter表?
以下是iptables 规则
[hr][code]
root@OpenWrt:~#iptables -L
Chain INPUT (policy ACCEPT)
target prot opt source destination
delegate_input all -- anywhere anywhere
Chain FORWARD (policy DROP)
target prot opt source destination
DROP all -- anywhere PC201409180946.lan
p2pblock udp -- anywhere anywhere udp spts:1024:65535 dpts:1024:65535
p2pblock tcp -- anywhere anywhere tcp spts:1024:65535 dpts:1024:65535
delegate_forward all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
DROP all -- 192.168.1.90 anywhere
delegate_output all -- anywhere anywhere
Chain BCP38 (3 references)
target prot opt source destination
RETURN udp -- anywhere anywhere udp spts:bootps:bootpc dpts:bootps:bootpc
REJECT all -- anywhere anywhere match-set bcp38-ipv4 dst reject-with icmp-net-unreachable
DROP all -- anywhere anywhere match-set bcp38-ipv4 src
Chain MINIUPNPD (1 references)
target prot opt source destination
ACCEPT tcp -- anywhere 192.168.1.22 tcp dpt:10946
ACCEPT udp -- anywhere 192.168.1.22 udp dpt:10489
ACCEPT tcp -- anywhere PC201409180946.lan tcp dpt:10946
ACCEPT udp -- anywhere PC201409180946.lan udp dpt:10489
Chain delegate_forward (1 references)
target prot opt source destination
forwarding_rule all -- anywhere anywhere /* user chain for forwarding */
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
ACCEPT all -- anywhere 192.168.1.22 /* ddrop */
zone_lan_forward all -- anywhere anywhere
zone_wan_forward all -- anywhere anywhere
reject all -- anywhere anywhere
Chain delegate_input (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere
input_rule all -- anywhere anywhere /* user chain for input */
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
syn_flood tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN
zone_lan_input all -- anywhere anywhere
zone_wan_input all -- anywhere anywhere
Chain delegate_output (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere
output_rule all -- anywhere anywhere /* user chain for output */
ACCEPT all -- anywhere anywhere ctstate RELATED,ESTABLISHED
zone_lan_output all -- anywhere anywhere
zone_wan_output all -- anywhere anywhere
Chain forwarding_lan_rule (1 references)
target prot opt source destination
Chain forwarding_rule (1 references)
target prot opt source destination
BCP38 all -- anywhere anywhere
Chain forwarding_wan_rule (1 references)
target prot opt source destination
Chain input_lan_rule (1 references)
target prot opt source destination
Chain input_rule (1 references)
target prot opt source destination
BCP38 all -- anywhere anywhere
Chain input_wan_rule (1 references)
target prot opt source destination
Chain luci_splash_filter (1 references)
target prot opt source destination
REJECT tcp -- anywhere anywhere reject-with tcp-reset
REJECT all -- anywhere anywhere reject-with icmp-net-prohibited
Chain luci_splash_forwarding (0 references)
target prot opt source destination
RETURN all -- anywhere lvps176-28-11-93.dedicated.hosteurope.de
luci_splash_filter all -- anywhere anywhere
Chain output_lan_rule (1 references)
target prot opt source destination
Chain output_rule (1 references)
target prot opt source destination
BCP38 all -- anywhere anywhere
Chain output_wan_rule (1 references)
target prot opt source destination
Chain p2pblock (2 references)
target prot opt source destination
LOG all -- anywhere anywhere -m ipp2p --apple limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-apple:"
all -- anywhere anywhere -m ipp2p --apple recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --winmx limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-winmx:"
all -- anywhere anywhere -m ipp2p --winmx recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --soul limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-soul:"
all -- anywhere anywhere -m ipp2p --soul recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --ares limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-ares:"
all -- anywhere anywhere -m ipp2p --ares recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --bit limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-bit:"
all -- anywhere anywhere -m ipp2p --bit recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --gnu limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-gnu:"
all -- anywhere anywhere -m ipp2p --gnu recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --kazaa limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-kazaa:"
all -- anywhere anywhere -m ipp2p --kazaa recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --dc limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-dc:"
all -- anywhere anywhere -m ipp2p --dc recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere -m ipp2p --edk limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-seen-edk:"
all -- anywhere anywhere -m ipp2p --edk recent: SET name: P2PBLOCK side: dest mask: 255.255.255.255
LOG all -- anywhere anywhere recent: CHECK seconds: 60 hit_count: 3 name: P2PBLOCK side: dest mask: 255.255.255.255 limit: avg 1/min burst 5 LOG level warning prefix "P2PBLOCK-DROP:"
DROP all -- anywhere anywhere recent: CHECK seconds: 60 hit_count: 3 name: P2PBLOCK side: dest mask: 255.255.255.255
Chain reject (3 references)
target prot opt source destination
REJECT tcp -- anywhere anywhere reject-with tcp-reset
REJECT all -- anywhere anywhere reject-with icmp-port-unreachable
Chain syn_flood (1 references)
target prot opt source destination
RETURN tcp -- anywhere anywhere tcp flags:FIN,SYN,RST,ACK/SYN limit: avg 25/sec burst 50
DROP all -- anywhere anywhere
Chain zone_lan_dest_ACCEPT (2 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere
Chain zone_lan_forward (1 references)
target prot opt source destination
forwarding_lan_rule all -- anywhere anywhere /* user chain for forwarding */
zone_wan_dest_ACCEPT all -- anywhere anywhere /* forwarding lan -> wan */
ACCEPT all -- anywhere anywhere ctstate DNAT /* Accept port forwards */
zone_lan_dest_ACCEPT all -- anywhere anywhere
Chain zone_lan_input (1 references)
target prot opt source destination
input_lan_rule all -- anywhere anywhere /* user chain for input */
ACCEPT all -- anywhere anywhere ctstate DNAT /* Accept port redirections */
zone_lan_src_ACCEPT all -- anywhere anywhere
Chain zone_lan_output (1 references)
target prot opt source destination
output_lan_rule all -- anywhere anywhere /* user chain for output */
zone_lan_dest_ACCEPT all -- anywhere anywhere
Chain zone_lan_src_ACCEPT (1 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere
Chain zone_wan_dest_ACCEPT (2 references)
target prot opt source destination
ACCEPT all -- anywhere anywhere
Chain zone_wan_dest_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere
Chain zone_wan_forward (1 references)
target prot opt source destination
MINIUPNPD all -- anywhere anywhere
forwarding_wan_rule all -- anywhere anywhere /* user chain for forwarding */
ACCEPT all -- anywhere anywhere ctstate DNAT /* Accept port forwards */
zone_wan_dest_REJECT all -- anywhere anywhere
Chain zone_wan_input (1 references)
target prot opt source destination
input_wan_rule all -- anywhere anywhere /* user chain for input */
ACCEPT udp -- anywhere anywhere udp dpt:bootpc /* Allow-DHCP-Renew */
ACCEPT icmp -- anywhere anywhere icmp echo-request /* Allow-Ping */
ACCEPT all -- anywhere anywhere ctstate DNAT /* Accept port redirections */
zone_wan_src_REJECT all -- anywhere anywhere
Chain zone_wan_output (1 references)
target prot opt source destination
output_wan_rule all -- anywhere anywhere /* user chain for output */
zone_wan_dest_ACCEPT all -- anywhere anywhere
Chain zone_wan_src_REJECT (1 references)
target prot opt source destination
reject all -- anywhere anywhere
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#iptables -t mangle -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
luci_splash_mark_out all -- anywhere anywhere
mwan3_hook all -- anywhere anywhere
fwmark all -- anywhere anywhere
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain FORWARD (policy ACCEPT)
target prot opt source destination
mssfix all -- anywhere anywhere
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
mwan3_hook all -- anywhere anywhere
mwan3_output_hook all -- anywhere anywhere
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
luci_splash_mark_in all -- anywhere anywhere
Chain fwmark (1 references)
target prot opt source destination
Chain luci_splash_mark_in (1 references)
target prot opt source destination
Chain luci_splash_mark_out (1 references)
target prot opt source destination
Chain mssfix (1 references)
target prot opt source destination
TCPMSS tcp -- anywhere anywhere tcp flags:SYN,RST/SYN /* wan (mtu_fix) */ TCPMSS clamp to PMTU
Chain mwan3_connected (2 references)
target prot opt source destination
MARK all -- anywhere 127.0.0.0/8 MARK or 0xff00
MARK all -- anywhere base-address.mcast.net/3 MARK or 0xff00
MARK all -- anywhere 10.20.12.0/24 MARK or 0xff00
MARK all -- anywhere 192.168.1.0/24 MARK or 0xff00
Chain mwan3_hook (2 references)
target prot opt source destination
CONNMARK all -- anywhere anywhere CONNMARK restore mask 0xff00
mwan3_ifaces all -- anywhere anywhere mark match 0x0/0xff00
mwan3_connected all -- anywhere anywhere mark match 0x0/0xff00
mwan3_rules all -- anywhere anywhere mark match 0x0/0xff00
CONNMARK all -- anywhere anywhere CONNMARK save mask 0xff00
mwan3_connected all -- anywhere anywhere mark match ! 0xff00/0xff00
Chain mwan3_iface_wan (1 references)
target prot opt source destination
MARK all -- 10.20.12.0/24 anywhere mark match 0x0/0xff00 /* default */ MARK or 0xff00
MARK all -- anywhere anywhere mark match 0x0/0xff00 /* wan */ MARK xset 0x100/0xff00
Chain mwan3_ifaces (1 references)
target prot opt source destination
mwan3_iface_wan all -- anywhere anywhere mark match 0x0/0xff00
Chain mwan3_output_hook (1 references)
target prot opt source destination
mwan3_track_wan icmp -- anywhere anywhere icmp echo-request length 32
Chain mwan3_policy_balanced (1 references)
target prot opt source destination
MARK all -- anywhere anywhere mark match 0x0/0xff00 /* wan 3 3 */ MARK xset 0x100/0xff00
Chain mwan3_policy_wan2_only (0 references)
target prot opt source destination
MARK all -- anywhere anywhere mark match 0x0/0xff00 /* unreachable */ MARK xset 0xfe00/0xff00
Chain mwan3_policy_wan2_wan (1 references)
target prot opt source destination
MARK all -- anywhere anywhere mark match 0x0/0xff00 /* wan 3 3 */ MARK xset 0x100/0xff00
Chain mwan3_policy_wan_only (0 references)
target prot opt source destination
MARK all -- anywhere anywhere mark match 0x0/0xff00 /* wan 3 3 */ MARK xset 0x100/0xff00
Chain mwan3_policy_wan_wan2 (1 references)
target prot opt source destination
MARK all -- anywhere anywhere mark match 0x0/0xff00 /* wan 3 3 */ MARK xset 0x100/0xff00
Chain mwan3_rules (1 references)
target prot opt source destination
mwan3_policy_wan_wan2 tcp -- 0.0.0.0/0.0.0.1 anywhere multiport sports 0:65535 multiport dports https mark match 0x0/0xff00 /* sticky_even */
mwan3_policy_wan2_wan tcp -- 0.0.0.1/0.0.0.1 anywhere multiport sports 0:65535 multiport dports https mark match 0x0/0xff00 /* sticky_odd */
mwan3_policy_balanced all -- anywhere anywhere mark match 0x0/0xff00 /* default_rule */
Chain mwan3_track_wan (1 references)
target prot opt source destination
MARK all -- anywhere resolver2.opendns.com MARK or 0xff00
MARK all -- anywhere resolver1.opendns.com MARK or 0xff00
MARK all -- anywhere google-public-dns-a.google.com MARK or 0xff00
MARK all -- anywhere google-public-dns-b.google.com MARK or 0xff00
Chain qos_Default (0 references)
target prot opt source destination
CONNMARK all -- anywhere anywhere CONNMARK restore mask 0xf
qos_Default_ct all -- anywhere anywhere mark match 0x0/0xf
MARK udp -- anywhere anywhere mark match 0x0/0xf0 length 0:500 MARK xset 0x22/0xff
MARK icmp -- anywhere anywhere MARK xset 0x11/0xff
MARK tcp -- anywhere anywhere mark match 0x0/0xf0 tcp spts:1024:65535 dpts:1024:65535 MARK xset 0x44/0xff
MARK udp -- anywhere anywhere mark match 0x0/0xf0 udp spts:1024:65535 dpts:1024:65535 MARK xset 0x44/0xff
CONNMARK all -- anywhere anywhere CONNMARK save mask 0xf0
Chain qos_Default_ct (1 references)
target prot opt source destination
MARK tcp -- anywhere anywhere mark match 0x0/0xf tcp multiport ports ssh,domain /* ssh, dns */ MARK xset 0x11/0xff
MARK udp -- anywhere anywhere mark match 0x0/0xf udp multiport ports ssh,domain /* ssh, dns */ MARK xset 0x11/0xff
MARK tcp -- anywhere anywhere mark match 0x0/0xf tcp multiport ports ftp-data,ftp,smtp,www,pop3,https,imaps,pop3s /* ftp, smtp, http(s), imap */ MARK xset 0x33/0xff
MARK tcp -- anywhere anywhere mark match 0x0/0xf tcp multiport ports 5190 /* AOL, iChat, ICQ */ MARK xset 0x22/0xff
MARK udp -- anywhere anywhere mark match 0x0/0xf udp multiport ports 5190 /* AOL, iChat, ICQ */ MARK xset 0x22/0xff
CONNMARK all -- anywhere anywhere CONNMARK save mask 0xff
MARK tcp -- anywhere anywhere mark match 0x0/0xf tcp multiport ports ssh,domain /* ssh, dns */ MARK xset 0x11/0xff
MARK udp -- anywhere anywhere mark match 0x0/0xf udp multiport ports ssh,domain /* ssh, dns */ MARK xset 0x11/0xff
MARK tcp -- anywhere anywhere mark match 0x0/0xf tcp multiport ports ftp-data,ftp,smtp,www,pop3,https,imaps,pop3s /* ftp, smtp, http(s), imap */ MARK xset 0x33/0xff
MARK tcp -- anywhere anywhere mark match 0x0/0xf tcp multiport ports 5190 /* AOL, iChat, ICQ */ MARK xset 0x22/0xff
MARK udp -- anywhere anywhere mark match 0x0/0xf udp multiport ports 5190 /* AOL, iChat, ICQ */ MARK xset 0x22/0xff
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#
root@OpenWrt:~#iptables -t nat -L
Chain PREROUTING (policy ACCEPT)
target prot opt source destination
DNAT all -- anywhere 10.20.12.13 to:192.168.1.22
DNAT tcp -- anywhere 10.20.12.13 tcp dpt:8022 to:192.168.1.130:22
delegate_prerouting all -- anywhere anywhere
Chain INPUT (policy ACCEPT)
target prot opt source destination
Chain OUTPUT (policy ACCEPT)
target prot opt source destination
Chain POSTROUTING (policy ACCEPT)
target prot opt source destination
delegate_postrouting all -- anywhere anywhere
Chain MINIUPNPD (1 references)
target prot opt source destination
DNAT tcp -- anywhere anywhere tcp dpt:10946 to:192.168.1.22:10946
DNAT udp -- anywhere anywhere udp dpt:10946 to:192.168.1.22:10489
DNAT tcp -- anywhere anywhere tcp dpt:17083 to:192.168.1.128:10946
DNAT udp -- anywhere anywhere udp dpt:17083 to:192.168.1.128:10489
Chain delegate_postrouting (1 references)
target prot opt source destination
postrouting_rule all -- anywhere anywhere /* user chain for postrouting */
zone_lan_postrouting all -- anywhere anywhere
zone_wan_postrouting all -- anywhere anywhere
Chain delegate_prerouting (1 references)
target prot opt source destination
prerouting_rule all -- anywhere anywhere /* user chain for prerouting */
zone_lan_prerouting all -- anywhere anywhere
zone_wan_prerouting all -- anywhere anywhere
Chain luci_splash_leases (1 references)
target prot opt source destination
REDIRECT udp -- anywhere anywhere udp dpt:domain redir ports 53
REDIRECT tcp -- anywhere anywhere tcp dpt:www redir ports 8082
Chain luci_splash_prerouting (0 references)
target prot opt source destination
RETURN all -- anywhere lvps176-28-11-93.dedicated.hosteurope.de
luci_splash_leases all -- anywhere anywhere
Chain postrouting_lan_rule (1 references)
target prot opt source destination
Chain postrouting_rule (1 references)
target prot opt source destination
Chain postrouting_wan_rule (1 references)
target prot opt source destination
Chain prerouting_lan_rule (1 references)
target prot opt source destination
Chain prerouting_rule (1 references)
target prot opt source destination
Chain prerouting_wan_rule (1 references)
target prot opt source destination
Chain zone_lan_postrouting (1 references)
target prot opt source destination
postrouting_lan_rule all -- anywhere anywhere /* user chain for postrouting */
Chain zone_lan_prerouting (1 references)
target prot opt source destination
prerouting_lan_rule all -- anywhere anywhere /* user chain for prerouting */
Chain zone_wan_postrouting (1 references)
target prot opt source destination
postrouting_wan_rule all -- anywhere anywhere /* user chain for postrouting */
MASQUERADE all -- anywhere anywhere
Chain zone_wan_prerouting (1 references)
target prot opt source destination
MINIUPNPD all -- anywhere anywhere
prerouting_wan_rule all -- anywhere anywhere /* user chain for prerouting */
root@OpenWrt:~#
[/code]
解 决 方 法 在 下 面
问题原因:
在linux 3.10.49版本,有一个内核参数 net.netfilter.nf_conntrack_skip_filter,在我的openWrt版本配置里默认=1,因此当连接已建立时,自动忽略filter表,所以出现现象是,数据上行方向做过滤规则时,本机发起连接,因为连接未建立,过滤生效,数据下行方向时,因为netfilter已记录这个连接,连接已建立,如果
net.netfilter.nf_conntrack_skip_filter=1时,忽略filter表所有规则
在linux-3.10.49/net/ipv4/netfilter/iptable_filter.c
[code]
nf_ct_get(skb, &ctinfo);
if ((ctinfo == IP_CT_ESTABLISHED_REPLY || ctinfo == IP_CT_ESTABLISHED) &&
net->ct.skip_filter)
return NF_ACCEPT;
return ipt_do_table(skb, hook, in, out, net->ipv4.iptable_filter);
[/code]
究其原因,net->ct.skip_filter在以下文件赋值
linux-3.10.49/net/netfilter/nf_conntrack_standalone.c
[code]
table[1].data = &net->ct.count;
table[2].data = &net->ct.htable_size;
table[3].data = &net->ct.sysctl_checksum;
table[4].data = &net->ct.sysctl_log_invalid;
table[5].data = &net->ct.skip_filter;
/* Don't export sysctls to unprivileged users */
if (net->user_ns != &init_user_ns)
table[0].procname = NULL;
net->ct.sysctl_header = register_net_sysctl(net, "net/netfilter", table);
[/code]
从代码可见,table表与sysctl有关,因此,在linux shell下敲sysctl -a命令可以看到net.netfilter.nf_conntrack_skip_filter=1
修改/etc/sysctl.conf,使net.netfilter.nf_conntrack_skip_filter=0,并敲 sysctl -p重新加载配置文件,问题解决