fix: 修复高并发下自适应超时过低导致开放端口漏扫#598
Conversation
|
马上审计下,另外指向dev分支 |
has been changed |
ZacharyZcR
left a comment
There was a problem hiding this comment.
Review:Request Changes
感谢 PR,问题定位是对的——#503 在本机/低 RTT + 高并发场景下,AdaptiveTimeout 地板过低导致开放端口被误判,这个根因我认可。CI 也是绿的,方向没问题。
但当前实现里有一块会伤到自适应超时本身的设计目标,建议改完再合,不要直接合入。
可以保留
-
minTO从 100ms 调整为max(500ms, maxTimeout/5)
这是对症的核心修复。默认 3s → 600ms 地板合理,也能覆盖绝大多数高并发握手尾延迟。 -
pool.Invoke失败时的丢弃日志
无害、有助于排查漏扫,可以留。
需要改:超时后无条件用完整 maxTO 再拨一次
connectWithRetry 里:
- 自适应超时失败 → 再用
fallbackTimeout(完整超时,常为 3s)重试一次
端口扫描里,timeout 的大头是 filtered / 防火墙丢弃 / 无响应,不是「开放但稍慢」。对这类端口:
- 关闭(RST)→ refused,不重试(没问题)
- 开放且慢 → 重试可能捞回来(这是你想修的)
- 过滤/无响应 → 每次都先等 adaptive,再白等一整段 maxTO,且几乎必然失败
AdaptiveTimeout 存在的意义,就是网络学完之后别再对每个无响应端口傻等满 -time。现在这刀等于在 每个 timeout 端口 上把这个收益吃掉大半。默认 -t 600 扫带防火墙的网段时,耗时会明显恶化。
另外:「超时不重试」本身不是纯 bug,而是端口扫描的常见取舍——timeout ≈ 无响应,盲目重试多半只烧时间。资源耗尽才该重试(现有逻辑已经做了)。
#503 主场景(本机/低 RTT/高并发)靠抬高 minTO 通常就够。
无条件 full-timeout 重试是高价保险,保费却摊在所有 filtered 端口上。
建议(二选一)
A(更推荐)
去掉 timeout → full maxTO 重试,本 PR 只保留 minTO 抬升 + 丢弃日志。先合这个,用 #503 场景回归;若仍有漏扫,再单独讨论有条件的重试。
B(若坚持要保险) 至少同时收紧:
- 仅当当前 adaptive 已经贴着地板时才 fallback(例如
timeout接近minTO) - fallback 不要直接拉满
maxTO,用更温和的上探(例如min(maxTO, timeout*2)) - 避免对所有 timeout 无差别二次满超时
需要移出本 PR:webscan/lib/Client.go
gmtls handshake 的 stdout 噪声抑制和 #503 / 端口漏扫无关,属于范围污染。请从这个 PR 拿掉,另开 PR(或另找时机)处理。
测试建议
- 为
NewAdaptiveTimeout(3*time.Second)的下限收敛补一条断言(描述里写了 3s → 600ms,代码里最好有测试钉死) - 若保留任何形式的 timeout 重试,请说明 filtered 端口的预期耗时变化,最好有前后对比
小结
| 改动 | 意见 |
|---|---|
| minTO 抬升 | ✅ 认可,保留 |
| 丢弃日志 | ✅ 可保留 |
| timeout → 完整 maxTO 无条件重试 | ❌ 请删除或改为有条件/更温和 |
| Client.go gmtls stdout | ❌ 移出本 PR |
问题找对了,核心药方也对;把「无条件 full-timeout 重试」和无关 diff 拿掉后,这个 PR 就可以再 review 一次。
扫描本机/低 RTT 目标时,AdaptiveTimeout 在 10 次采样后迅速收敛到 100ms 下限。高并发(600+ 线程)下 TCP 握手尾延迟可能超过 100ms,加上超时错误不会重试,导致开放端口被误判为关闭。 - AdaptiveTimeout 下限从 100ms 提升至 max(500ms, maxTimeout/5) - connectWithRetry 对超时错误用完整超时重试一次 - slidingWindowSchedule 任务丢弃时记录日志,便于排查漏扫
根据 shadow1ng#598 review 反馈: 1. 移除 connectWithRetry 中 timeout->full maxTO 无条件重试 - filtered/无响应端口占超时大头,盲目重试只烧时间 - shadow1ng#503 主场景靠 minTO 抬升已足够覆盖 2. 移除不再使用的 MaxTimeout() 方法和 port_scan_timeout_retry i18n 条目 3. AdaptiveTimeout 收敛测试补充 minTO 下限断言(3s->600ms)
78bbcc0 to
4966e09
Compare
|
已按 review 意见修改,force push 更新了 PR: 已移除:
已保留:
已补充:
关于 Client.go:
全部测试通过。 |
ZacharyZcR
left a comment
There was a problem hiding this comment.
已复核最新提交:review 意见均已处理,改动范围干净,完整 go test ./... 通过,可以合并。
问题
Issue #503 反映 fscan 2.x 扫描本机时部分端口漏扫,而 1.8.4 不存在此问题。
原因
2.x 引入的 AdaptiveTimeout(自适应超时)在高并发场景下下限过低:
修复
1. 提高自适应超时下限(core/adaptive_timeout.go)
minTO 从固定 100ms 改为 max(500ms, maxTimeout/5):
2. 超时错误重试(core/port_scan.go)
connectWithRetry 新增 fallbackTimeout 参数,连接超时时用完整超时再试一次,避免自适应超时过低导致误判。
3. 任务丢弃日志(core/port_scan.go)
slidingWindowSchedule 中 pool.Invoke 失败不再静默丢弃,改为记录日志和总计统计,方便排查漏扫。
测试
全部测试通过,包括自适应超时收敛测试验证新下限工作正常:
Closes #503