记录Iptables状态跟踪(conntrack)的相关命令与参数,记录如下:
本节内容摘自: 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
[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为系统
[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
//
[root@centos7-18 ~]# cat /proc/sys/net/netfilter/nf_conntrack_max
65536
[root@centos7-18 ~]# cat /proc/sys/net/netfilter/nf_conntrack_buckets
16384
[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
// 最大跟踪连接记录400万
nf_conntrack_max = 4194304
// 100万个桶,每个桶存储4条连接记录
nf_conntrack_buckets = 1048576
// TCP timeout超时 2天
nf_conntrack_tcp_timeout_established = 172800
// 其它参数
可根据实际使用情况调整