查看nf_conntrack相关数值:
cat /proc/sys/net/netfilter/nf_conntrack_max sysctl net.netfilter.nf_conntrack_buckets cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_time_wait cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_close_wait cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_fin_wait wc -l /proc/net/nf_conntrack //统计已记录的连接数
加大防火墙跟踪表的大小:
nf_conntrack_max计算公式
理论最大值计算公式:
CONNTRACK_MAX = RAMSIZE (inbytes) / 16384 / (x / 32) 这里x是指针的bit数,(例如,32或者64bit)
示例,64G的64位操作系统计算方法:
CONNTRACK_MAX =64*1024*1024*1024/16384/(64/32)= 2097152
hashsize计算公式
hashsize = CONNTRACK_MAX / 8 ~CONNTRACK_MAX / 2
示例,64G的64位操作系统计算方法:
2097152 /8 ~ 2097152 /2 = 262144 ~ 1048576
修改数值的方式:
sysctl -w net.netfilter.nf_conntrack_max=393216 //最多使用12G内存来追踪连接状态
echo 49152 >/sys/module/nf_conntrack/parameters/hashsize //对应的hashsize
echo -e "sysctl -w net.netfilter.nf_conntrack_max=393216 \n echo 49152 >/sys/module/nf_conntrack/parameters/hashsize" >> /etc/rc.d/rc.local&& chmod +x /etc/rc.d/rc.local //开机自动执行
监控脚本(需要添加sudo权限,可结合zabbix做监控):
#!/bin/bash currentLink=$(sudo /bin/cat/proc/net/nf_conntrack | /usr/bin/wc -l) totalLink=$(/bin/cat/proc/sys/net/netfilter/nf_conntrack_max) restLink=$[$totalLink-$currentLink] case $1 in max) echo $totalLink ;; used) echo $currentLink ;; idle) echo $restLink esac
关于nf_conntrack的一些测试:
Centos 6.8
关闭iptables服务后,即使使用iptables -L来查看,也不会新增链接记录
Centos 7.2
关闭firewalld服务后,仍然会新增链接记录
关于NAT的一些测试:
Centos 6.8
由于NAT是基于iptables来实现的,因此关闭iptables服务后,无法使用NAT功能
开启iptables服务并添加nat规则后,nf_conntrack会跟踪nat相关的链接
如果在raw表的PREROUTING链上添加了NOTRACK规则,相应的流量无法使用nat功能,如添加以下规则后,192.168.2.0的网段的流量将无法通过nat访问外网。
iptables -t raw -A PREROUTING -s 192.168.2.0/24 ! -d 192.168.2.0/24 -j NOTRACK
Centos 7.2
关闭firewalld服务后,iptables仍然可以正常工作,即NAT可以正常工作,且nf_conntrack会跟踪nat相关的链接
如果在raw表的PREROUTING链上添加了NOTRACK规则,同样无法使用nat功能
关于反向代理的一些测试:
拓扑
nginx做反向代理,后端为tomcat
结果
每向nginx发送一次动态请求,nf_conntrack都会新增链接记录,分别为客户端访问nginx的链接以及nginx访问tomcat的链接
关于docker的端口映射的一些测试:
Centos 7.2
由于docker容器访问外网是基于iptables的nat来实现的,因此开启docker服务后,docker会自动添加nat规则,因此nf_conntrack会记录nat相关的链接记录
同样的,如果执行以下命令,向raw表添加NOTRACK规则,docker容器将无法访问外网。
iptables -t raw -A PREROUTING -s 172.17.0.0/24 ! -d172.17.0.0/24 -j NOTRACK
docker容器之间的链接也会被nf_conntrack跟踪
基于测试结果,对nf_conntrack的调优:
示例一,适用于普通的web服务器
思路,不跟踪访问量大的链接状态
iptables -t raw -A PREROUTING -p tcp--dport 80 -j NOTRACK iptables -t raw -A OUTPUT -p tcp --sport80 -j NOTRACK //不跟踪web服务的链接
iptables -t raw -A PREROUTING -i lo -jNOTRACK iptables -t raw -A OUTPUT -o lo -jNOTRACK //不跟踪本地内的所有链接
示例二,适用于把iptables作为网关,做NAT
无法nf_conntrack表做进一步优化,只能对nf_conntrack表容量进行扩容
示例三,适用于nginx+tomcat的反向代理
思路:
1. 不跟踪访问nginx的链接状态
2. 不跟踪nginx访问tomcat的链接状态
iptables -t raw -A PREROUTING -p tcp --dport80 -j NOTRACK iptables -t raw -A OUTPUT -p tcp --sport80 -j NOTRACK //不跟踪nginx服务的链接
iptables -t raw -A PREROUTING -i lo -jNOTRACK iptables -t raw -A OUTPUT -o lo -jNOTRACK //不跟踪本地内的所有链接
示例四,适用于nginx+docker的反向代理(nginx使用宿主机网络,容器使用端口映射)
思路:
1. 不跟踪访问nginx的链接状态
2. 不跟踪nginx访问docker容器的链接状态
iptables -t raw -A PREROUTING -p tcp --dport80 -j NOTRACK iptables -t raw -A OUTPUT -p tcp --sport80 -j NOTRACK //不跟踪nginx服务的链接
iptables -t raw -A PREROUTING -i lo -jNOTRACK iptables -t raw -A OUTPUT -o lo -jNOTRACK //不跟踪本地内的所有链接
注
此示例中,docker内部网段(即172.17.0.0网段)相关的链接状态仍然会被跟踪,没有找到取消这些链接状态的方法。因此需要对nf_conntrack表做适当扩容
示例五,适用于kubernetes的集群平台
1.前端nginx做代理,使用宿主机网络
2.使用nginx反向代理到后端的pod上
iptables -t raw -A PREROUTING -p tcp --dport80 -j NOTRACK iptables -t raw -A OUTPUT -p tcp --sport80 -j NOTRACK //不跟踪nginx服务的链接
注:
经测试,如果取消lo口上的链接跟踪,nginx无法访问到后端的pod
docker内部网段相关的链接仍然会被跟踪,没有找到取消这些链接状态的方法
其他优化nf_conntrack的方法:
降低各链接状态的timeout值,加快链接的释放
彻底关闭nf_conntrack功能(无法使用state模块以及nat功能)
①Centos 6
关闭iptables服务即可
②Centos 7
vim/etc/modprobe.d/blacklist.conf
blacklist nf_conntrack blacklist nf_conntrack_ipv6 blacklist xt_conntrack blacklist nf_conntrack_ftp blacklist xt_state blacklist iptable_nat blacklist ipt_REDIRECT blacklist nf_nat blacklist nf_conntrack_ipv4