TCP 状态概述
TCP(Transmission Control Protocol)是一种面向连接的、可靠的、基于字节流的传输层通信协议。在 TCP 连接的生命周期中,连接会经历不同的状态。
监控 TCP 连接状态对于以下场景非常重要:
- 排查网络连接问题
- 分析系统负载
- 检测异常连接(如 SYN 洪水攻击)
- 优化系统性能
11 种 TCP 状态详解
状态转换图
+--------+
主动打开 | CLOSED | 被动打开
+--------->| (关闭) |<-----------+
| +--------+ |
| | |
| | 被动打开 |
| v |
| +--------+ |
+--------->| LISTEN |<-----------+
| SYN_SENT |(监听) | SYN_RCVD
| (同步 +--------+ (同步
| 已发送) | SYN 已接收)
| | 发送
| v
+--------->+--------+
| ESTAB |
|(已建立)|
+--------+
|
+--------------+--------------+
| |
v v
+---------+ +---------+
主动关闭|FIN_WAIT1| |CLOSE_WAIT|
|(终止等待1)| |(关闭等待)|
+---------+ +---------+
| |
| 收到 ACK | 被动关闭
v v
+---------+ +---------+
|FIN_WAIT2| |LAST_ACK |
|(终止等待2)| |(最后确认)|
+---------+ +---------+
| |
| 收到 FIN | 收到 ACK
v v
+---------+ +--------+
| TIME_W | | CLOSED |
|(时间等待)| |(关闭) |
+---------+ +--------+
|
| 2MSL 超时
v
+--------+
| CLOSED |
+--------+
额外状态:
+---------+
| CLOSING | (同时关闭)
+---------+各状态详细说明
| 状态 | 英文全称 | 说明 | 正常场景 |
|---|---|---|---|
| CLOSED | Closed | 连接关闭状态,没有任何连接活动 | 初始状态或连接已完全关闭 |
| LISTEN | Listening | 监听状态,等待来自客户端的连接请求 | 服务端正常监听端口 |
| SYN_SENT | Synchronize Sent | 已发送 SYN 包,等待对方确认 | 客户端发起连接 |
| SYN_RCVD | Synchronize Received | 收到 SYN 包,已发送 SYN+ACK,等待确认 | 服务端收到连接请求 |
| ESTABLISHED | Established | 连接已建立,可以传输数据 | 正常数据传输状态 |
| FIN_WAIT1 | Finish Wait 1 | 已发送 FIN 包,等待对方确认 | 主动关闭连接的第一步 |
| FIN_WAIT2 | Finish Wait 2 | 收到对方对 FIN 的确认,等待对方的 FIN | 等待对方关闭连接 |
| CLOSE_WAIT | Close Wait | 收到对方的 FIN,等待本地应用关闭连接 | 被动关闭,应用未响应 |
| CLOSING | Closing | 双方同时关闭连接,等待确认 | 同时主动关闭(较少见) |
| LAST_ACK | Last Acknowledge | 已发送 FIN,等待最后的 ACK | 被动关闭的最后阶段 |
| TIME_WAIT | Time Wait | 等待足够的时间以确保对方收到最后的 ACK | 防止旧连接数据包干扰 |
状态分类
1. 正常建立连接状态
SYN_SENT→SYN_RCVD→ESTABLISHED
2. 正常关闭连接状态
- 主动关闭:
FIN_WAIT1→FIN_WAIT2→TIME_WAIT→CLOSED - 被动关闭:
CLOSE_WAIT→LAST_ACK→CLOSED
3. 需要关注的状态
| 状态 | 异常表现 | 可能原因 |
|---|---|---|
| SYN_SENT 过多 | 大量连接发起但未建立 | 网络不通、服务端无响应、防火墙阻断 |
| SYN_RCVD 过多 | SYN 洪水攻击迹象 | SYN Flood 攻击、连接队列满 |
| ESTABLISHED 过多 | 连接数超过系统限制 | 连接泄漏、并发量过大 |
| TIME_WAIT 过多 | 端口资源耗尽 | 短连接频繁、2MSL 时间过长 |
| CLOSE_WAIT 过多 | 应用未关闭连接 | 程序 Bug、资源未释放 |
| FIN_WAIT1/2 过多 | 对端无响应 | 网络问题、对端异常 |
监控方法
1. 命令行查看
# 查看所有 TCP 连接状态统计
ss -s
# 按状态统计
ss -ant | awk '{print $1}' | sort | uniq -c
# 或使用 netstat
netstat -ant | awk '{print $6}' | sort | uniq -c
# 查看特定状态的连接
ss -ant state established
ss -ant state time-wait2. 查看详细连接信息
# 查看 TIME_WAIT 状态的连接详情
ss -ant state time-wait
# 查看 CLOSE_WAIT 状态的连接及对应的进程
ss -antp state close-wait
# 统计各状态连接数
for state in ESTABLISHED SYN_SENT SYN_RCVD FIN_WAIT1 FIN_WAIT2 TIME_WAIT CLOSE_WAIT CLOSING LAST_ACK; do
count=$(ss -ant state $state 2>/dev/null | wc -l)
echo "$state: $((count - 1))"
done自定义监控配置
1. 创建监控脚本
创建 /etc/zabbix/zabbix_agent2.d/tcp_status.sh:
#!/bin/bash
# TCP 连接状态监控脚本
STATE=$1
case $STATE in
ESTABLISHED)
ss -ant state established 2>/dev/null | wc -l
;;
SYN_SENT)
ss -ant state syn-sent 2>/dev/null | wc -l
;;
SYN_RCVD)
ss -ant state syn-recv 2>/dev/null | wc -l
;;
FIN_WAIT1)
ss -ant state fin-wait-1 2>/dev/null | wc -l
;;
FIN_WAIT2)
ss -ant state fin-wait-2 2>/dev/null | wc -l
;;
TIME_WAIT)
ss -ant state time-wait 2>/dev/null | wc -l
;;
CLOSE_WAIT)
ss -ant state close-wait 2>/dev/null | wc -l
;;
CLOSING)
ss -ant state closing 2>/dev/null | wc -l
;;
LAST_ACK)
ss -ant state last-ack 2>/dev/null | wc -l
;;
LISTEN)
ss -ant state listening 2>/dev/null | wc -l
;;
*)
echo 0
;;
esac设置权限:
chmod +x /etc/zabbix/zabbix_agent2.d/tcp_status.sh
chown zabbix:zabbix /etc/zabbix/zabbix_agent2.d/tcp_status.sh2. 配置 UserParameter
创建 /etc/zabbix/zabbix_agent2.d/tcp_status.conf:
# TCP 连接状态监控
UserParameter=tcp.status[*],/etc/zabbix/zabbix_agent2.d/tcp_status.sh $1
# 或直接使用 ss 命令(无需脚本)
UserParameter=tcp.status.established,ss -ant state established 2>/dev/null | wc -l
UserParameter=tcp.status.syn_sent,ss -ant state syn-sent 2>/dev/null | wc -l
UserParameter=tcp.status.syn_recv,ss -ant state syn-recv 2>/dev/null | wc -l
UserParameter=tcp.status.fin_wait1,ss -ant state fin-wait-1 2>/dev/null | wc -l
UserParameter=tcp.status.fin_wait2,ss -ant state fin-wait-2 2>/dev/null | wc -l
UserParameter=tcp.status.time_wait,ss -ant state time-wait 2>/dev/null | wc -l
UserParameter=tcp.status.close_wait,ss -ant state close-wait 2>/dev/null | wc -l
UserParameter=tcp.status.closing,ss -ant state closing 2>/dev/null | wc -l
UserParameter=tcp.status.last_ack,ss -ant state last-ack 2>/dev/null | wc -l
UserParameter=tcp.status.listen,ss -ant state listening 2>/dev/null | wc -l3. 重启 Agent
systemctl restart zabbix-agent2
# 测试键值
zabbix_agent2 -t tcp.status[ESTABLISHED]
zabbix_agent2 -t tcp.status.time_wait4. Zabbix Web 配置
4.1 创建监控项
为每种 TCP 状态创建监控项:
| 名称 | 键值 | 类型 | 单位 |
|---|---|---|---|
| TCP Established | tcp.status[ESTABLISHED] | Zabbix agent | 无 |
| TCP Time Wait | tcp.status[TIME_WAIT] | Zabbix agent | 无 |
| TCP Close Wait | tcp.status[CLOSE_WAIT] | Zabbix agent | 无 |
| ... | ... | ... | ... |
4.2 创建图形
创建聚合图形展示各状态趋势:
- 进入 Configuration → Hosts → Graphs
- 点击 Create graph
- 添加所有 TCP 状态监控项
- 选择合适的图形类型(如堆叠面积图)
触发器配置
建议的告警阈值
| 状态 | 警告阈值 | 严重阈值 | 说明 |
|---|---|---|---|
| TIME_WAIT | > 10000 | > 30000 | 端口资源耗尽风险 |
| CLOSE_WAIT | > 100 | > 500 | 应用程序连接泄漏 |
| SYN_SENT | > 100 | > 500 | 连接建立异常 |
| SYN_RCVD | > 100 | > 500 | 可能遭受 SYN Flood |
| ESTABLISHED | > 10000 | > 50000 | 连接数过高 |
触发器示例
TIME_WAIT 过多
名称:TCP TIME_WAIT 连接数过高
表达式:{Template OS Linux:tcp.status[TIME_WAIT].last()}>10000
严重性:Warning
名称:TCP TIME_WAIT 连接数严重超标
表达式:{Template OS Linux:tcp.status[TIME_WAIT].last()}>30000
严重性:HighCLOSE_WAIT 过多
名称:TCP CLOSE_WAIT 连接数异常
表达式:{Template OS Linux:tcp.status[CLOSE_WAIT].last()}>100
严重性:Warning
描述:存在大量 CLOSE_WAIT 状态连接,可能是应用程序未正确关闭连接SYN 攻击检测
名称:可能的 SYN Flood 攻击
表达式:{Template OS Linux:tcp.status[SYN_RCVD].last()}>500
严重性:Disaster
描述:SYN_RCVD 状态连接数异常,可能正在遭受 SYN Flood 攻击优化建议
1. TIME_WAIT 优化
# 编辑 /etc/sysctl.conf
# 开启 TIME_WAIT 重用
net.ipv4.tcp_tw_reuse = 1
# 开启 TIME_WAIT 快速回收(不建议在 NAT 环境使用)
net.ipv4.tcp_tw_recycle = 0
# 缩短 TIME_WAIT 等待时间(秒,默认 60)
net.ipv4.tcp_fin_timeout = 30
# 增加可用端口范围
net.ipv4.ip_local_port_range = 1024 65535
# 应用配置
sysctl -p2. SYN 攻击防护
# 编辑 /etc/sysctl.conf
# 开启 SYN Cookies
net.ipv4.tcp_syncookies = 1
# 缩短 SYN 超时时间
net.ipv4.tcp_syn_retries = 2
net.ipv4.tcp_synack_retries = 2
# 增大 SYN 队列长度
net.ipv4.tcp_max_syn_backlog = 65536
# 应用配置
sysctl -p3. 连接数优化
# 编辑 /etc/sysctl.conf
# 增大系统最大连接跟踪数
net.netfilter.nf_conntrack_max = 655360
# 增大文件描述符限制
echo "* soft nofile 65536" >> /etc/security/limits.conf
echo "* hard nofile 65536" >> /etc/security/limits.conf