查看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 //統計已記錄的鏈接數
加大防火牆跟蹤表的大小:nginx
nf_conntrack_max計算公式web
理論最大值計算公式:docker
CONNTRACK_MAX = RAMSIZE (inbytes) / 16384 / (x / 32) 這裏x是指針的bit數,(例如,32或者64bit)vim
示例,64G的64位操做系統計算方法:後端
CONNTRACK_MAX =64*1024*1024*1024/16384/(64/32)= 2097152tomcat
hashsize計算公式bash
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