记一次iptables导致的生产故障


记一次iptables导致的生产故障


故障还原

流量监控报警,经排查网站日志发现有大量的恶意访问,导致/var/log/messages日志报错“nf_conntrack:table full,drop packet”。

nf_conntrack是一个内核模块,用于跟踪一个连接状态;连接跟踪状态可以供其他模块使用。可通过以下查看:

<code>/sbin/lsmod | egrep conntrack
nf_conntrack_ipv4 9506 4 iptable_nat,nf_nat
nf_defrag_ipv4 1483 1 nf_conntrack_ipv4
nf_conntrack_ipv6 8748 2
nf_defrag_ipv6 11182 1 nf_conntrack_ipv6
nf_conntrack 79758 6 xt_NOTRACK,iptable_nat,nf_nat,nf_conntrack_ipv4,nf_conntrack_ipv6,xt_state
ipv6 317340 45 ip6t_REJECT,nf_conntrack_ipv6,nf_defrag_ipv6
/<code>

原因

当网站有大量的请求时,iptables开启后会记录连接跟踪状态,就可能导出现“nf_conntrack:table full”,从而导致服务器无法正常通信。我们可以通过关闭iptables或是重启iptables清空连接跟踪表,但会有安全隐患。

解决方案

1.修改内核参数

<code>vim /etc/sysctl.conf
#加大 ip_conntrack_max 值
net.ipv4.ip_conntrack_max = 393216

net.ipv4.netfilter.ip_conntrack_max = 393216
#降低 ip_conntrack timeout时间
net.ipv4.netfilter.ip_conntrack_tcp_timeout_established = 300
net.ipv4.netfilter.ip_conntrack_tcp_timeout_time_wait = 120
net.ipv4.netfilter.ip_conntrack_tcp_timeout_close_wait = 60
net.ipv4.netfilter.ip_conntrack_tcp_timeout_fin_wait = 120/<code>

增加完以上内容后,通过sysctl -p 使配置生效 。不过该方法缺点:一旦重启iptables后,ip_conntrack_max值又会变成65535默认值,需要重新sysctl -p。

2.移除模块

<code>modprobe -r xt_NOTRACK nf_conntrack_netbios_ns nf_conntrack_ipv4 xt_state
modprobe -r nf_conntrack/<code>

执行完查看/proc/net/ 下面如果没用了 nf_conntrack ,就证明模块移除成功了

注意:此方法会将state模块也一块儿移除掉,如果我们的iptables应用nat会用到state模块,卸载后导致iptables某些功能无法使用。

3.使用raw表,跳过跟踪记录

首先先认识下什么是raw表?做什么用的?

iptables有5个链:PREROUTING,INPUT,FORWARD,OUTPUT,POSTROUTING;4个表:filter,nat,mangle,raw 。

4个表的优先级由高到低的顺序为:raw-->mangle-->nat-->filter

举例来说:如果PRROUTING链上,即有mangle表,也有nat表,那么先由mangle处理,然后由nat表处理 。

RAW表只使用在PREROUTING链和OUTPUT链上,因为优先级最高,从而可以对收到的数据包在连接跟踪前进行处理。因此用户使用了RAW表,在某个链上RAW表处理完后,将跳过NAT表和 ip_conntrack处理,即不再做地址转换和数据包的链接跟踪处理了。

RAW表可以应用在那些不需要做nat的情况下,以提高性能。如大量访问的web服务器,可以让80端口不再让iptables做数据包的连接跟踪处理,以提高用户的访问速度 。

使用方法:

(1)增加"UNTRACKED",保存并重启iptables

<code>/sbin/iptables -A INPUT -m state --state RELATED,ESTABLISHED,UNTRACKED -j ACCEPT/<code>

注意: 必须更改此步,增加”UNTRACKED“,否则执行后面的语句会造成相应的端口不能访问。我使用该方法时就因为没有执行第一步的操作,造成web访问不能使用。

(2)针对特定端口机本机lo增加以下语句

<code># 针对进入本机的包
/sbin/iptables -t raw -A PREROUTING -p tcp -m multiport --dports 80 -j NOTRACK
# 针对从本机出去的包
/sbin/iptables -t raw -A OUTPUT -p tcp -m multiport --sports 80 -j NOTRACK
/sbin/iptables -t raw -A PREROUTING -i lo -j NOTRACK
/sbin/iptables -t raw -A OUTPUT -o lo -j NOTRACK/<code>

注意:

a.一定将进入和出去的包都设置规则;

b.建议只开放公共端口,如80/443;一旦开放,端口将不受防火墙其他策略限制;


分享到:


相關文章: