iftop是基于libpcap的实时流量监控工具,可显示网卡连接的ip、端口及2s/10s/40s平均速率,用于快速定位ddos或cc攻击源;需配合-nnp参数禁dns解析、显端口,并结合tcpdump抓包验证是否到达应用层。

用 iftop 看实时入站流量,别信 netstat 的连接数
Workerman 是常驻进程模型,netstat 统计的 ESTABLISHED 连接数容易误导——它包含大量已关闭但未完全释放的 TIME_WAIT,也混着健康长连接。真正反映攻击压力的是实时带宽占用。
直接运行:sudo iftop -nNP -i eth0
重点关注左列 IP 和右列「2s/10s/40s」三档速率。DDoS 攻击通常表现为单个 IP 持续占满 80/443 端口的 90%+ 入站带宽;CC 攻击则更隐蔽,可能多个 IP 均匀分布,但每 IP 的请求频率异常高(需结合日志确认)。
- -n 禁 DNS 解析,避免卡顿导致漏看关键帧
- -P 显示端口,快速区分是 HTTP 流量还是异常 UDP/ICMP
- 若看到大量
*:random → your_ip:80,极可能是 SYN Flood,不是 Workerman 能拦住的层级
从 Nginx 日志反查 Workerman 的真实请求来源
Workerman 常作为后端被 Nginx 反代(如 WebSocket 或 HTTP 接口)。此时 $_SERVER['REMOTE_ADDR'] 在 Workerman 里拿到的是 Nginx 的内网地址(如 127.0.0.1),不是真实客户端 IP。
必须检查 Nginx 配置是否透传了真实 IP:
- 确认
nginx.conf中 upstream 段有proxy_set_header X-Real-IP $remote_addr; - Workerman 代码中要读
$connection->getHeader('x-real-ip'),而非$connection->getRemoteIp() - 若用了 Cloudflare 或高防 IP,还要检查
X-Forwarded-For链,并只取最左边非可信代理的 IP(防伪造)
漏掉这步,所有基于 IP 的限流、封禁都等于对空气开枪。
在 Workerman onMessage 里加轻量级请求频控,别等 Redis
DDoS/CC 攻击发生时,Redis 可能成为瓶颈或单点故障。先用内存级简单计数做第一道过滤:
$ip = $connection->getHeader('x-real-ip') ?: $connection->getRemoteIp();
$now = time();
$window = 60; // 60秒窗口
$key = "req:$ip";
<p>// 简单数组计数(注意:仅适用于单 Worker 进程,多进程需换 Redis)
if (!isset($this->reqCount[$key])) {
$this->reqCount[$key] = ['count' => 0, 'start' => $now];
}
if ($now - $this->reqCount[$key]['start'] > $window) {
$this->reqCount[$key] = ['count' => 0, 'start' => $now];
}
if (++$this->reqCount[$key]['count'] > 100) {
$connection->close();
return;
}
</p>
- 这个逻辑必须放在
onMessage开头,越早拦截越省资源 - 阈值 100 是示例,需根据业务接口复杂度调低(如登录接口建议 ≤ 5/分钟)
- 数组存内存快,但不跨进程——Workerman 多子进程时,攻击者轮询不同进程就能绕过
抓包验证:用 tcpdump 确认流量是否真进到了 Workerman
如果 iftop 显示某 IP 流量巨大,但 Nginx 日志和 Workerman onMessage 日志里完全没记录,说明攻击根本没到应用层——大概率是 SYN Flood 或 UDP 洪水,Workerman 无能为力,得靠系统防火墙或高防清洗。
立即抓包验证:
sudo tcpdump -i eth0 -nn 'host 203.0.113.45 and port 2346' -c 50 -w /tmp/attack.pcap
- 替换
203.0.113.45为你怀疑的 IP,2346为 Workerman 监听端口 - 抓到包后用 Wireshark 打开,看是否有完整的 TCP 握手 + HTTP/WebSocket 协议载荷
- 如果只有 SYN 包、没有后续 ACK 或数据,就是协议层攻击,Workerman 进程甚至收不到连接事件
真正的难点永远不在代码里——而在于分清哪层该谁扛:SYN Flood 是内核和防火墙的事,CC 是 Nginx+Workerman 的事,UDP 洪水是运营商的事。混淆层级,排查就会南辕北辙。











