nf_conntrack详解

2019独角兽企业重金招聘Python工程师标准>>> hot3.png

(服务器用的阿里云主机,CentOS 7.3,似乎不管内存多少阿里云都把 conntrack_max 设成 65536)

症状
CentOS服务器,负载正常,但请求大量超时,服务器/应用访问日志看不到相关请求记录。

在dmesg或/var/log/messages看到大量以下记录:

kernel: nf_conntrack: table full, dropping packet.

原因
服务器访问量大,内核netfilter模块conntrack相关参数配置不合理,导致新连接被drop掉。

详细
nf_conntrack模块在kernel 2.6.15(2006-01-03发布) 被引入,支持ipv4和ipv6,取代只支持ipv4的ip_connktrack,用于跟踪连接的状态,供其他模块使用。

最常见的使用场景是 iptables 的 nat 和 state 模块:

nat 根据转发规则修改IP包的源/目标地址,靠nf_conntrack的记录才能让返回的包能路由到发请求的机器。
state 直接用 nf_conntrack 记录的连接状态(NEW/ESTABLISHED/RELATED/INVALID)来匹配防火墙过滤规则。
iptables

nf_conntrack用1个哈希表记录已建立的连接,包括其他机器到本机、本机到其他机器、本机到本机(例如 ping 127.0.0.1 也会被跟踪)。

如果连接进来比释放的快,把哈希表塞满了,新连接的数据包会被丢掉,此时netfilter变成了一个黑洞,导致拒绝服务。 这发生在3层(网络层),应用程序毫无办法。

各发行版区别:

CentOS (7.3) 默认加载该模块
Ubuntu (16.10+) 和 Kali Linux (2016.1+) 默认不加载,不会有这问题
查看
netfilter 相关的内核参数:

sudo sysctl -a | grep conntrack

只看超时相关参数(超时时间 = 连接在哈希表里保留的时间)

sudo sysctl -a | grep conntrack | grep timeout
netfilter模块加载时的bucket和max配置:

sudo dmesg | grep conntrack

找类似这样的记录:

nf_conntrack version 0.5.0 (16384 buckets, 65536 max)

哈希表使用情况:

grep conntrack /proc/slabinfo

前4个数字分别为:

当前活动对象数、可用对象总数、每个对象的大小(字节)、包含至少1个活动对象的分页数

当前跟踪的连接数:

sudo sysctl net.netfilter.nf_conntrack_count

或 cat /proc/net/nf_conntrack | wc -l

跟踪的每个连接的详情:

cat /proc/net/nf_conntrack

统计里面的TCP连接的各状态和条数

cat /proc/net/nf_conntrack | awk '/^.tcp.$/ {count[$6]++} END {for(state in count) print state, count[state]}'

记录数最多的10个ip

cat /proc/net/nf_conntrack | awk '{print $7}' | cut -d "=" -f 2 | sort | uniq -c | sort -nr | head -n 10

记录格式:

你可能感兴趣的:(网络,运维,开发工具)