kernel: nf_conntrack: table full, dropping packet错误处理过程

报错信息:

查看症状:

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

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

kernel: nf_conntrack: table full, dropping packet.

 

原因:

服务器访问量大,内核 netfilter 模块 conntrack 相关参数配置不合理,导致 IP 包被丢掉,连接无法建立。

 

查看nf_conntrack表最大连接数:

sudo sysctl net.netfilter.nf_conntrack_buckets #只读

cat /proc/sys/net/netfilter/nf_conntrack_max

 

查看nf_conntrack表当前连接数:

cat /proc/sys/net/netfilter/nf_conntrack_count

 

sudo sysctl net.netfilter.nf_conntrack_max

# 默认 nf_conntrack_buckets * 4

# max 是 bucket 的多少倍决定了每个桶里的链表有多长,因此默认链表长度为 4

 

跟踪连接记录

 

# Ubuntu 通常没有 /proc/net/nf_conntrack 文件,用 conntrack 命令代替,输出一样

sudo conntrack -L -o extended | tail -n 50

# CentOS:

sudo tail -n 50 /proc/net/nf_conntrack

# 输出例:

# ipv4     2 tcp      6 295019 ESTABLISHED src=47.96.117.250 dst=125.109.193.42 sport=40888 dport=18348 src=125.109.193.42 dst=47.96.117.250 sport=18348 dport=40888 [ASSURED] mark=0 secctx=system_u:object_r:unlabeled_t:s0 zone=0 use=2

# 记录格式:

# 网络层协议名、网络层协议编号、传输层协议名、传输层协议编号、记录失效前剩余秒数、连接状态(不是所有协议都有)

# 之后都是 key=value 或 flag 格式,1 行里最多 2 个同名 key(如 src 和 dst),第 1 次出现的来自请求,第 2 次出现的来自响应

# flag:

# [ASSURED]  请求和响应都有流量

# [UNREPLIED]  没收到响应,哈希表满的时候这些连接先扔掉

 

四层协议类型和连接数:

 

sudo conntrack -L -o extended | awk '{sum[$3]++} END {for(i in sum) print i, sum[i]}'

# 或:

sudo cat /proc/net/nf_conntrack | awk '{sum[$3]++} END {for(i in sum) print i, sum[i]}'

 

TCP 连接各状态对应的条数:

 

sudo conntrack -L -o extended | awk '/^.*tcp.*$/ {sum[$6]++} END {for(i in sum) print i, sum[i]}'

# 或:

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

 

三层协议类型和连接数:

 

sudo conntrack -L -o extended | awk '{sum[$1]++} END {for(i in sum) print i, sum[i]}'

# 或:

sudo cat /proc/net/nf_conntrack | awk '{sum[$1]++} END {for(i in sum) print i, sum[i]}'

 

连接数最多的 10 个 IP 地址:

 

sudo conntrack -L -o extended | awk '{print $7}' | cut -d "=" -f 2 | sort | uniq -c | sort -nr | head -n 10

# 或:

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

 

/proc/sys/net目录

所有的TCP/IP参数都位于/proc/sys/net目录下(请注意,对/proc/sys/net目录下内容的修改都是临时的,任何修改在系统重启后都会丢失)

 

/etc/sysctl.conf文件

/etc/sysctl.conf是一个允许你改变正在运行中的Linux系统的接口。它包含一些TCP/IP堆栈和虚拟内存系统的高级选项,可用来控制Linux网络配置,由于/proc/sys/net目录内容的临时性,建议把TCPIP参数的修改添加到/etc/sysctl.conf文件, 然后保存文件,使用命令“/sbin/sysctl –p”使之立即生效。

 

解决办法:

 

1、临时修改

echo 262144 | sudo tee /sys/module/nf_conntrack/parameters/hashsize

sysctl net.netfilter.nf_conntrack_max=1048576

sysctl net.netfilter.nf_conntrack_tcp_timeout_established=3600

 

2、修改配置文件(永久)

 sysctl [-w]  echo xxx > /pro/sys/net/netfilter/XXX 做的修改在重启后会失效。如果测试过没问题,在 /etc/sysctl.d/ 下新建配置文件,这里以 90-conntrack.conf 为例(CentOS 6 等旧系统编辑 /etc/sysctl.conf),系统启动时会加载里面的设置:

vi /etc/sysctl.conf或者vi  /etc/sysctl.d/90-conntrack.conf

# 格式:<参数>=<值>,等号两边可以空格,支持 # 注释
net.nf_conntrack_max=1048576
net.netfilter.nf_conntrack_max=104857
net.netfilter.nf_conntrack_buckets = 262144
net.netfilter.nf_conntrack_max=104857
net.netfilter.nf_conntrack_icmp_timeout=10
net.netfilter.nf_conntrack_tcp_timeout_syn_recv=5
net.netfilter.nf_conntrack_tcp_timeout_syn_sent=5
net.netfilter.nf_conntrack_tcp_timeout_established=300
net.netfilter.nf_conntrack_tcp_timeout_fin_wait=10
net.netfilter.nf_conntrack_tcp_timeout_time_wait=10
net.netfilter.nf_conntrack_tcp_timeout_close_wait=10
net.netfilter.nf_conntrack_tcp_timeout_last_ack=10

如果修改了配置文件,要马上应用配置文件里的设置:

sudo sysctl -p /etc/sysctl.d/90-conntrack.conf
# 不传文件路径默认加载 /etc/sysctl.conf

tail -f /var/log/messages  #查看是否正常

参考信息:

http://keithmo.me/post/2018/08/25/conntrack-tuning/#b-%E8%B0%83%E6%95%B4%E5%86%85%E6%A0%B8%E5%8F%82%E6%95%B0

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值