iptables神秘的DROP –sport 80

最近,我决定丢弃想要通过端口80出去的数据包。它接缝我的configuration有一个问题,因为一些不需要的数据包被丢弃。

我的configuration摘录:

iptables -A OUTPUT -m state --state ESTABLISHED,RELATED -j ACCEPT iptables -A OUTPUT -p tcp -s [PUBLIC IP OF MY SERVER] --sport 80 --dport 1024:65535 -m state --state ESTABLISHED -j ACCEPT 

问题1:不是第二个无用的规则,因为我已经在第一个规则中说过,我接受所有具有“ESTABLISHED”状态的数据包?

问题2:为什么这两条规则不足以接受下面丢弃的数据包:

 Jul 14 18:47:18 [HOSTNAME] kernel: iptables output: IN= OUT=eth0 SRC=[PUBLIC IP OF MY SERVER] DST=[A WWW CLIENT PUBLIC IP] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=8408 DF PROTO=TCP SPT=80 DPT=50085 WINDOW=123 RES=0x00 ACK FIN URGP=0 Jul 14 18:47:53 [HOSTNAME] kernel: iptables output: IN= OUT=eth0 SRC=[PUBLIC IP OF MY SERVER] DST=[A WWW CLIENT PUBLIC IP] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=8409 DF PROTO=TCP SPT=80 DPT=50085 WINDOW=123 RES=0x00 ACK FIN URGP=0 Jul 14 18:48:08 [HOSTNAME] kernel: iptables output: IN= OUT=eth0 SRC=[PUBLIC IP OF MY SERVER] DST=[A WWW CLIENT PUBLIC IP] LEN=40 TOS=0x00 PREC=0x00 TTL=64 ID=54091 DF PROTO=TCP SPT=80 DPT=25780 WINDOW=16616 RES=0x00 ACK FIN URGP=0 

注意:

  • 在丢包的链条上面没有规则。
  • 默认策略是DROP。

编辑我看了这个post ,也启用内核loggingINVALID数据包:

 echo 255 >/proc/sys/net/netfilter/nf_conntrack_log_invalid 

现在它接缝我有几种错误:

 Jul 14 22:00:40 [HOSTNAME] kernel: nf_ct_tcp: invalid RST IN= OUT= SRC=[ONE_CLIENT_IP] DST=[SERVER_IP] LEN=40 TOS=0x00 PREC=0x00 TTL=49 ID=47149 PROTO=TCP SPT=993 DPT=51364 SEQ=1043042446 ACK=0 WINDOW=0 RES=0x00 RST URGP=0 Jul 14 21:57:11 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state ESTABLISHED IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=3782 SEQ=474588492 ACK=2243291425 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402) Jul 14 21:57:25 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state LAST_ACK IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=3782 SEQ=474588492 ACK=2243291425 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402) Jul 14 21:57:41 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state TIME_WAIT IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=3782 SEQ=474588492 ACK=2243291425 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402) Jul 14 21:58:52 [HOSTNAME] kernel: nf_ct_tcp: invalid packet ignored in state SYN_RECV IN= OUT= SRC=[SERVER_IP] DST=[ONE_CLIENT_IP] LEN=48 TOS=0x00 PREC=0x00 TTL=64 ID=0 DF PROTO=TCP SPT=80 DPT=50488 SEQ=3804975135 ACK=229029122 WINDOW=14600 RES=0x00 ACK SYN URGP=0 OPT (020405B401010402) 

(其实我在别处做了这个答案,我以为是同一个网站)

根据这些:

http://www.tcpipguide.com/free/t_TCPConnectionTermination-2.htm

http://www.iptables.info/en/connection-state.html (不是最新的)

可能(可能是移动的)客户端可能是先closures的,没有等到最后的FIN / ACK,也没有发送最终的ACK,或者服务器回答得太晚,客户端本身被防火墙或其他慢响应的情况…因此,服务器重试,除了一个计时器( sysctl net.netfilter.nf_conntrack_tcp_timeout_last_ack ),但netfilter已经放弃了真正的tcp堆栈下降之前的状态。

你应该拿走痕迹,看看你是否有重复的数据包例如。

第二条规则是第一条规则的一个子集,所以没用。 尝试增加各种tcp_timeout设置值( sysctl -w net.netfilter....或者echo XX > /proc/sys/net/netfilter/... )并查看这些日志是否消失。 我过去也是这样设定的,它解决了一些神秘的netfilter日志。 这可能会增加conntrack内存使用量。

1)第二个似乎是无用的,如果你有第一个。

2)现在。 为什么你会在OUTPUT上默认DROP? 你不相信自己? 我会默认接受。 只需将您的规则应用到INPUT链中,默认情况下为DROP。 在INPUT链和DROP默认情况下,iptables将在保护你的服务器方面做得很好。 为OUTPUT创build这样的策略似乎太多,如果你没有做特别的安全设置。

在三次TCP握手完成之前,连接将不会“build立”。 握手要求客户端发送一个SYN数据包,返回一个SYN+ACK数据包,然后客户端返回一个ACK数据包。 但是,您将要阻止SYN+ACK传出数据包。

一个更好的办法是允许OUTPUT中与-p tcp --sport 80 --dport 1024:65535匹配的所有数据包。 你也可以进一步限制下限。 IANAbuild议端口41952及以上用于随机源端口,但您可能会注意到许多客户端不符合规定。 像这样的规则将允许任何stream量作为端口80连接的响应,其中客户端端口不是特权端口(并且将防止恶意软件在80或443上调用主页)。

如果你喜欢为你的规则使用连接状态,你也可以在源端口80上允许状态为ESTABLISHED,RELATED,SYN_RECV传出数据包(在你的configuration中,你可以使用SYN_RECV因为第一个规则会照顾它)。 这将允许传出的SYN+ACK设置传出连接。

无效的数据包似乎与它们是SYN+ACK数据包有关,但连接并不等待build立。 这可能是一个与问题无关的神器,没有什么可担心的。