Iptables状态跟踪(conntrack)相关命令与参数

记录Iptables状态跟踪(conntrack)的相关命令与参数,记录如下:

参考

  • 链接: 你真的了解nf_conntrack么?
  • 链接: conntrack最大数量
  • 链接: linux 路由跟踪表 nf_conntrack 数据结构 参数 简介
  • 链接: Iptables状态跟踪机制介绍和优化探讨
  • 链接: 运维排查篇 | Linux 连接跟踪表满了怎么处理
  • 链接: linux iptables详解
  • 链接: iptables详解(图文)

概念

本节内容摘自: linux 路由跟踪表 nf_conntrack 数据结构 参数 简介

在内核中,连接跟踪表是一个二维数组结构的哈希表(hash table),哈希表的大小记作HASHSIZE,哈希表的每一项(hash table entry)称作bucket,因此哈希表中有HASHSIZE个bucket存在,每个bucket包含一个链表(linked list),每个链表能够存放若干个conntrack条目(bucket size)。

需要明确的是,nf_conntrack 模块并不是所有 Linux 内核都会加载,最常见的导致加载该模块的原因是使用了 iptables、lvs 等内核态 NAT/防火墙导致内核需要对连接表进行追踪,iptable_nat、ip_vs 等多个内核模块都依赖 nf_conntrack, 但是 nf_conntrack 的存在会影响高并发下的内核收包性能。

在这里插入图片描述

对于一个新收到的数据包,内核使用如下步骤判断其是否属于一个已有连接:

  • 内核提取此数据包信息(源目IP,port,协议号)进行hash计算得到一个hash值,在哈希表中以此hash值做索引,索引结果为数据包所属的bucket(链表)。这一步hash计算时间固定并且很短。

  • 遍历hash得到的bucket,查找是否有匹配的conntrack条目。这一步是比较耗时的操作,bucket size越大(条目越多),遍历时间越长。

    说明:遍历时间复杂度是 o(n) ,bucket size越大(条目越多),效率越低

bucket_size 和 hashsize 的关系
根据上面对哈希表的解释,系统最大允许连接跟踪数CONNTRACK_MAX = 连接跟踪表大小(HASHSIZE) * Bucket大小(bucket size)。从连接跟踪表获取bucket是hash操作时间很短,而遍历bucket相对费时,因此为了conntrack性能考虑,bucket size越小越好。

官方推荐一个桶(bucket)里放4条entry(conntrack条目),所以官方的默认参数 nf_conntrack_max = nf_conntrack_buckets x 4 ,是四倍的关系。

在参数设置中,需要调整nf_conntrack_maxnf_conntrack_buckets两个参数,系统自动调整两者比值(每个桶存放的条目数量)

命令

  • 查看内核模块是否加载nf_conntrack
// 查看内核模块是否加载nf_conntrack
[root@centos7-10 ~]# lsmod   |  grep nf_conntrack
nf_conntrack_netlink    36396  0 
nfnetlink              14519  2 nf_conntrack_netlink
nf_conntrack_ipv4      15053  2 
nf_defrag_ipv4         12729  1 nf_conntrack_ipv4
nf_conntrack          139264  6 nf_nat,nf_nat_ipv4,xt_conntrack,nf_nat_masquerade_ipv4,nf_conntrack_netlink,nf_conntrack_ipv4
libcrc32c              12644  3 xfs,nf_nat,nf_conntrack
[root@centos7-10 ~]# 
  • 如果没有请先动态加载
// 动态加载
[root@centos7-10 ~]# modprobe nf_conntrack
[root@centos7-10 ~]# 
// 动态卸载
// [root@centos7-10 ~]# modprobe -r nf_conntrack
// 如果想启动开启可以修改
// vim /ect/rc.d/rc.local

参数

  • 参数说明

    • nf_conntrack_max 表示系统最大允许连接跟踪数,即 entry 的个数。缺省为 nf_conntrack_buckets value * 4

      推荐计算公式: nf_conntrack_max = RAMSIZE (in bytes) / 16384 / ( ARCH / 32 )
      其中:RAMSIZE是内存,不含swap;ARCH为机器CPU的架构,64或32

    • nf_conntrack_buckets 哈希表的大小,建议每个 bucket(bucket size) 存储4个 entry 。默认如果内存(RAMSIZE)超过4GB,缺省值是65536;如果内存1-4GB之间,缺省值是16384;最小值不小于32个。

    • nf_conntrack_tcp_timeout_established TCP timeout的时间,默认是43200秒(5天)

  • 系统信息

    • 64位系统
    • 内存 1034600448 byte(不包括swap)
// 64为系统
[root@centos7-18 ~]# uname -a
Linux centos7-18.localdomain 3.10.0-1160.6.1.el7.x86_64 #1 SMP Tue Nov 17 13:59:11 UTC 2020 x86_64 x86_64 x86_64 GNU/Linux
// 内存 1.8G 
[root@centos7-18 ~]# free -h
              total        used        free      shared  buff/cache   available
Mem:           1.8G        509M        1.0G        9.2M        319M        1.1G
Swap:          3.0G          0B        3.0G
  • nf_conntrack_max
    nf_conntrack_max = nf_conntrack_buckets * 4
// 
[root@centos7-18 ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
65536
  • nf_conntrack_buckets
[root@centos7-18 ~]# cat /proc/sys/net/netfilter/nf_conntrack_buckets
16384
  • nf_conntrack_tcp_timeout_established
[root@centos7-18 ~]# cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
432000
  • 查看全部参数
[root@centos7-18 ~]# sysctl -a |grep net.netfilter.nf_conntrack
sysctl: reading key "net.ipv6.conf.all.stable_secret"
sysctl: reading key "net.ipv6.conf.default.stable_secret"
sysctl: reading key "net.ipv6.conf.enp0s5.stable_secret"
sysctl: reading key "net.ipv6.conf.lo.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0.stable_secret"
sysctl: reading key "net.ipv6.conf.virbr0-nic.stable_secret"
net.netfilter.nf_conntrack_acct = 0
net.netfilter.nf_conntrack_buckets = 16384
net.netfilter.nf_conntrack_checksum = 1
net.netfilter.nf_conntrack_count = 1
net.netfilter.nf_conntrack_dccp_loose = 1
net.netfilter.nf_conntrack_dccp_timeout_closereq = 64
net.netfilter.nf_conntrack_dccp_timeout_closing = 64
net.netfilter.nf_conntrack_dccp_timeout_open = 43200
net.netfilter.nf_conntrack_dccp_timeout_partopen = 480
net.netfilter.nf_conntrack_dccp_timeout_request = 240
net.netfilter.nf_conntrack_dccp_timeout_respond = 480
net.netfilter.nf_conntrack_dccp_timeout_timewait = 240
net.netfilter.nf_conntrack_events = 1
net.netfilter.nf_conntrack_events_retry_timeout = 15
net.netfilter.nf_conntrack_expect_max = 256
net.netfilter.nf_conntrack_generic_timeout = 600
net.netfilter.nf_conntrack_helper = 1
net.netfilter.nf_conntrack_icmp_timeout = 30
net.netfilter.nf_conntrack_log_invalid = 0
net.netfilter.nf_conntrack_max = 65536
net.netfilter.nf_conntrack_sctp_timeout_closed = 10
net.netfilter.nf_conntrack_sctp_timeout_cookie_echoed = 3
net.netfilter.nf_conntrack_sctp_timeout_cookie_wait = 3
net.netfilter.nf_conntrack_sctp_timeout_established = 432000
net.netfilter.nf_conntrack_sctp_timeout_heartbeat_acked = 210
net.netfilter.nf_conntrack_sctp_timeout_heartbeat_sent = 30
net.netfilter.nf_conntrack_sctp_timeout_shutdown_ack_sent = 3
net.netfilter.nf_conntrack_sctp_timeout_shutdown_recd = 0
net.netfilter.nf_conntrack_sctp_timeout_shutdown_sent = 0
net.netfilter.nf_conntrack_tcp_be_liberal = 0
net.netfilter.nf_conntrack_tcp_loose = 1
net.netfilter.nf_conntrack_tcp_max_retrans = 3
net.netfilter.nf_conntrack_tcp_timeout_close = 10
net.netfilter.nf_conntrack_tcp_timeout_close_wait = 60
net.netfilter.nf_conntrack_tcp_timeout_established = 432000
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 30
net.netfilter.nf_conntrack_tcp_timeout_max_retrans = 300
net.netfilter.nf_conntrack_tcp_timeout_syn_recv = 60
net.netfilter.nf_conntrack_tcp_timeout_syn_sent = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_unacknowledged = 300
net.netfilter.nf_conntrack_timestamp = 0
net.netfilter.nf_conntrack_udp_timeout = 30
net.netfilter.nf_conntrack_udp_timeout_stream = 180
[root@centos7-18 ~]# 
  • 修改参数
// 永久修改参数
[root@centos7-18 etc]# vim /etc/sysctl.conf 
// 修改后生效
// [root@centos7-18 etc]# sysctl -p
  • 推荐参数
    • 64G内存情况下设置参数
// 最大跟踪连接记录400万
nf_conntrack_max = 4194304 

// 100万个桶,每个桶存储4条连接记录
nf_conntrack_buckets = 1048576

// TCP timeout超时 2天
nf_conntrack_tcp_timeout_established = 172800

// 其它参数
可根据实际使用情况调整