利用conntrack梳理主机之间的端口互访情况

现状及难点:

  • 有一批运行很久的业务系统,目前防火墙配置的是全网开放(0.0.0.0/0),由于没有原系统开发商的支持,梳理各个业务系统之间的访问关系费时费力且肯定会有遗漏(比如某些低频使用的业务),如何实现最小化的访问控制且将风险降到最低

解决方案:

  • 利用 conntrack 实现跟踪和监控网络连接(注:conntrack(Connection Tracking,连接跟踪)是Linux内核中的一个功能)

安装及配置 conntrack

  • 安装 conntrack
#.centos 系统安装 conntrack
yum install -y conntrack

#.ubuntu 系统安装 conntrack
apt install -y conntrack
  • 分析 conntrack 日志
#.查看当前的网络连接
conntrack -L

#.当前连接最多的10个ip
conntrack -L | awk '{print $5}' | cut -d "=" -f 2 | sort | uniq -c | sort -nr | head -n 10

#.通过dmesg可以查看nf_conntrack的状况
dmesg |grep nf_conntrack

#.源主机(src=12.79.1.12)源端口(sport=4068)请求目标主机(dst=192.168.0.3)的目标端口(dport=22),在299秒内超时
#.之后又反向将响应发送回源主机。对于此连接,已在两个方向上看到数据包
tcp 6 299 ESTABLISHED src=12.79.1.12 dst=192.168.0.3 sport=4068 dport=22 src=192.168.0.3 dst=12.79.1.12 sport=22 dport=4068 [ASSURED] mark=0 use=1

#.从主机192.168.0.2到主机192.168.0.3的ICMP回应请求数据包,在29秒内超时
icmp 1 29 src=192.168.0.2 dst=192.168.0.3 type=8 code=0 id=18340 src=192.168.0.3 dst=192.168.0.2 type=0 code=0 id=18340 mark=0 use=1
  • 优化 conntrack 内核参数
#.持久化配置-先删除参数
sed -i '/^net.netfilter.nf_conntrack_max/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_buckets/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_tcp_timeout_established/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_tcp_timeout_close/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_tcp_timeout_fin_wait/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_tcp_timeout_last_ack/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_tcp_timeout_time_wait/d' /etc/sysctl.conf

#.持久化配置:再更新参数
echo 'net.netfilter.nf_conntrack_max = 524288' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_buckets = 131072' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_established = 21600' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_close = 60' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_last_ack = 120' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120' >> /etc/sysctl.conf
cat /etc/sysctl.conf | grep nf_conntrack

#.刷新内核参数
/sbin/sysctl -p /etc/sysctl.conf

#.重点关注如下几个参数
$ sysctl -a | grep nf_conntrack | egrep "(netfilter.nf_conntrack_max|nf_conntrack_buckets|nf_conntrack_tcp_timeout)"
net.netfilter.nf_conntrack_max = 524288
net.netfilter.nf_conntrack_buckets = 131072
net.netfilter.nf_conntrack_tcp_timeout_established = 21600
net.netfilter.nf_conntrack_tcp_timeout_close = 60
net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 120
net.netfilter.nf_conntrack_tcp_timeout_last_ack = 120
net.netfilter.nf_conntrack_tcp_timeout_time_wait = 120

持续监控

  • 持续监控,并将结果重定向到文件
#.持续监控并将结果重定向到文件
conntrack -E -o ktimestamp > /tmp/conntrack.log &

#.查看结果
cat /tmp/conntrack.log
  • 部署任务:将如下内容保存到 /usr/local/conntrack.sh 然后配置crontab每天轮转日志,比如 1 0 * * * /bin/bash /usr/local/conntrack.sh
mkdir -p /opt/logs
cnt=`ps -ef | grep -v grep | grep conntrack | wc -l`
if [[ $cnt -ge 1 ]];then ps -ef | grep -v grep | grep conntrack | awk '{print $2}' | xargs kill -9 2> /dev/null; fi
conntrack -E -o ktimestamp > /opt/logs/conntrack.`date +%Y%m%d%H%M`.log &
  • 日志分析:基于监控采集到的日志进行数据分析
#.分析日志:排除ICMP回应请求、发生数据传输STABLISHED、统计src来源ip
cat /opt/logs/conntrack.*.log | grep -v icmp | grep ESTABLISHED | \
  awk -F"src=" '{print $2}' | awk '{print $1}' | sort | uniq

#.分析日志:排除ICMP回应请求、发生数据传输STABLISHED、统计src来源ip、目标端口dport
cat /opt/logs/conntrack.*.log | grep -v icmp | grep ESTABLISHED | \
  awk -F"src=" '{print $2}' | awk -F"dport=" '{print $1,$2}' | awk '{print $1,$4}' | sort | uniq

遇到的问题

连接太多导致 conntrack table 被打爆

  • 现象:操作系统的内核日志中有如下报错:
$ less /var/log/messages
[Tue Apr  6 18:12:30 2021] nf_conntrack: nf_conntrack: table full, dropping packet
[Tue Apr  6 18:12:30 2021] nf_conntrack: nf_conntrack: table full, dropping packet
[Tue Apr  6 18:12:30 2021] nf_conntrack: nf_conntrack: table full, dropping packet
  • 解决办法:调大 conntrack 表,并调小 conntrack 的 GC(也叫 timeout)时间(默认5天,改为6小时),加快过期 entry 的回收
#.查看nf_conntrack表最大连接数
# echo 524288 > /proc/sys/net/netfilter/nf_conntrack_max
cat /proc/sys/net/netfilter/nf_conntrack_max

#.持久化配置-先删除参数
sed -i '/^net.netfilter.nf_conntrack_max/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_buckets/d' /etc/sysctl.conf
sed -i '/^net.netfilter.nf_conntrack_tcp_timeout_established/d' /etc/sysctl.conf

#.持久化配置:再更新参数
echo 'net.netfilter.nf_conntrack_max = 524288' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_buckets = 131072' >> /etc/sysctl.conf
echo 'net.netfilter.nf_conntrack_tcp_timeout_established = 21600' >> /etc/sysctl.conf
cat /etc/sysctl.conf | grep nf_conntrack

#.确认生效
/sbin/sysctl -p /etc/sysctl.conf
sysctl -a | grep nf_conntrack
Copyright © www.sqlfans.cn 2021 - 2026 All Right Reserved更新时间: 2025-05-22 11:33:52

results matching ""

    No results matching ""