记录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_max 和nf_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 // 其它参数 可根据实际使用情况调整