通过路由器API日志追踪内网异常行为的一次实战记录
前言
在之前的文章《用命令行探索 iKuai 路由器 API》中,我详细介绍了如何通过命令行调用 iKuai 路由器的 REST API 来获取网络状态、设备列表、端口映射等信息。今天继续这个话题,聊聊我在实际运维中通过分析路由器 API 调用日志发现的一次可疑行为,以及完整的排查和解决过程。
事情是这样的:在例行巡检的过程中,我习惯性地查看路由器 API 的调用情况。结果发现某台服务器的 API 调用频率出现了异常——平时每小时大约 200 次调用,突然有一天变成了每小时 1800 次。这不是网络波动能解释的现象。
问题现象:凌晨 3 点的 API 调用高峰
在日常巡检脚本里,我加了一个简单的计数器,用来记录每次 API 调用的时间戳和调用来源。正常运行状态下,每小时的调用次数稳定在 150-250 次之间,不同 IP 的分布也比较均匀。但上周三早上,我查看前一天的统计时,发现了一个明显的”尖峰”——凌晨 3 点左右,调用频率突然飙升到了 1800 次/小时,持续了大约 40 分钟,然后恢复正常。
这个”尖峰”本身没有触发任何告警(因为我设置的阈值比较高,而且这种一次性峰值容易被忽略),但它引起了我的注意。凌晨 3 点,网络里应该没有什么人在操作,为什么 API 调用频率会突然增加 10 倍?
排查过程
第一步:确认数据来源和真实性
首先,我需要确认这个数据不是采集错误或者脏数据。我查看了 Prometheus 里对应的监控指标,确认数据来源是路由器本身的 API 日志,不是本地服务器的日志。数据点是真实的,路由器确实在那个时间段收到了大量 API 请求。
然后我查了一下那个时间段的具体调用记录。路由器的 API 调用日志会记录调用时间、来源 IP、目标功能码等信息。通过分析这些信息,我发现:
1 | |
这个发现让我心里咯噔了一下。凌晨 3 点,从同一台内网服务器,对路由器的 DHCP 列表和 ARP 表进行密集调用——这不是正常的人类行为。正常的运维人员不会在凌晨 3 点手动查询 DHCP 列表,即使查也不会在 40 分钟内查 1200 次。这种调用模式更像是某种自动化的侦察行为——有人在脚本里循环调用路由器的 API,试图摸清内网的设备分布。
第二步:溯源到具体服务器
接下来,我需要确认这个”来源 IP”是哪台服务器。查了一下 IP 地址对应的服务器,发现是一个跑着 Node-RED 的树莓派,上面部署了好几个 flow,其中一个 flow 负责定时采集网络设备信息。看起来是个正常的自动化任务。
但是,定时任务的频率是每小时一次,不应该在凌晨 3 点产生 1200 次调用。
我登录了那台树莓派,查看 Node-RED 的 flow 配置。在 flow 列表里,我看到了一个意外的配置——有一个 flow 的触发条件是”收到 HTTP 请求”,而不是”定时执行”。这个 flow 会把收到的请求转发到路由器的 API,然后返回结果。
也就是说,这台树莓派上的 Node-RED,对外暴露了一个 HTTP 接口,任何人向这个接口发送请求,都可以触发对路由器 API 的调用。
这个接口本身没有认证,但它是”对内网开放的”,所以之前我没有觉得这是个问题。现在看来,这个”没有认证的对内网开放”,恰恰就是问题所在。
第三步:还原攻击路径
通过分析,我大致还原出了这次可疑行为的路径:
1 | |
当然,这只是我的推测。我没有确凿证据证明这确实是攻击行为,也有可能是某个失控的自动化脚本在运行。但无论如何,这种行为本身是不正常的,它暴露了内网安全的一个盲点。
实际上,攻击者要做的事情很简单:先拿下一台内网服务器,然后在服务器上运行一个脚本,脚本里写一个循环,不断地调用路由器的 API,把返回的数据保存下来。整个过程不需要任何高深的技术,只需要基本的 Linux 命令和 curl。而这种攻击之所以能成功,根本原因只有一个:路由器 API 的访问控制太松散了。
第四步:排查”怎么进来的”
光知道攻击路径还不够,我还需要知道攻击者是怎么拿到那台树莓派的访问权限的。
我查了一下那台树莓派的 SSH 登录记录。结果发现,在凌晨 3 点之前的几分钟里,有一条来自外网 IP 的 SSH 登录成功记录。登录用户名是默认的用户名,登录时间是下午 6 点左右。
这条记录本身不算异常——那台树莓派确实需要从外网访问,所以我配置了 SSH 端口转发。但问题是,那个默认用户名的密码,是一个简单的 8 位数字。这种密码,用暴力破解的话,理论上几分钟就能破解。
我赶紧改了密码,改成了强密码。然后查了一下那个外网 IP 的来源——是一个东南亚地区的 IP 地址。没有确凿证据证明是它干的,但时间线太巧了,不能不让人怀疑。
解决方案
发现这个问题之后,我做了以下几件事:
1. 立即关闭可疑接口
第一步当然是把那个暴露的 HTTP 接口给关掉。我登录 Node-RED,禁用了那个可疑的 flow,然后重启了 Node-RED 服务。同时,我还检查了其他 flow,确认没有其他可疑的 HTTP 接口。之后再查看路由器的 API 调用频率,已经恢复正常水平。
2. 修改路由器 admin 密码
既然路由器 admin 密码可能已经被泄露(或者至少是存在被泄露的风险),最安全的做法是修改密码。我重置了路由器的 admin 密码,然后在所有保存了密码的服务器上更新了配置。
同时,我还做了一个额外的安全措施:把路由器 admin 密码从明文存储改成了加密存储。密码文件本身用 root 权限保护,读取需要 sudo。这样即使服务器被拿下,攻击者也不能直接拿到路由器密码。
3. 增加 API 调用监控
在 Prometheus 里新增了一个告警规则:当某个 IP 的 API 调用频率超过正常水平的 5 倍时,自动发送告警。同时,我还配置了一个定期检查脚本,如果某个 IP 在短时间内的调用频率超过阈值,就自动封锁该 IP 的访问。
这个规则可以覆盖大部分异常调用的情况,虽然不能完全防止攻击,但至少可以在异常发生时第一时间发现。
4. 梳理内网所有对外暴露的服务
这是最重要的一步。我花了半天时间,把内网所有可能暴露的服务梳理了一遍,包括:Node-RED 的 HTTP 接口、各类服务器的管理后台、数据库的外部访问端口、SSH 的密码登录(建议改为密钥登录)。梳理完之后,我发现了好几个之前没有注意到的安全隐患,全部记录在案,逐一修复。
经验总结
回过头来看这次排查经历,有几点想分享:
经验一:API 调用日志是金矿
很多安全事件事后分析时,我们会发现其实事前有很多蛛丝马迹。但问题是,这些蛛丝马迹往往藏在我们平时不太关注的地方。路由器 API 的调用日志就是这样一个例子——它记录了”谁在什么时候调用了什么”,这些信息平时看起来没什么用,但一旦出了问题,它就是溯源的利器。
建议:养成定期分析 API 调用日志的习惯,特别是调用频率异常的情况。可以设置自动化脚本,当调用频率超过阈值时自动告警。
经验二:内网服务不等于安全
很多人有一个误区:只要服务不对外网开放,就是安全的。这种想法在某种程度上是对的,但不完整。那台 Node-RED 的 HTTP 接口确实不对外网开放,但内网的任何一台被攻克的服务器,都可能成为攻击者的跳板。攻击者拿到内网的一台服务器之后,可以通过它访问任何”对内网开放”的服务。
建议:不要把”内网服务”当作”安全服务”。对内网开放的服务,同样需要认证和访问控制。能不用就不用,能限IP就限IP。
经验三:弱密码是最大的安全隐患
这次事件的核心问题,其实就是弱密码。那台树莓派的 SSH 密码是一个简单的 8 位数字,SSH 暴力破解就能轻松拿下。拿到 SSH 之后,攻击者发现服务器上有路由器的 admin 密码(明文保存在某个配置文件里),然后就顺理成章地拿到了路由器的访问权限。
建议:所有服务器一律使用强密码,推荐密钥登录,禁止密码登录。路由器 admin 密码不要保存在服务器上,或者至少要加密保存。
经验四:自动化是双刃剑
在这次事件里,攻击者使用的是自动化脚本。它在凌晨 3 点发起密集的 API 调用,试图在最短时间内摸清内网的设备分布。这种行为模式如果是人工操作,很难持续 40 分钟;但换成脚本,就变成了一个不眠不休的侦察工具。
自动化工具在提升效率的同时,也降低了攻击的成本。以前攻击者需要手动收集情报,现在只需要跑一个脚本。以前攻击者需要在白天行动,现在可以在任何时间发起攻击。进攻方在用自动化工具,防御方也不能落后。
建议:在防御侧也要利用自动化。机器学习异常检测、自动封禁、实时告警——这些自动化手段可以让我们和攻击者站在同一起跑线上。
后续行动
事情到这里还没有结束。我又做了几件后续的事情:
第一,制定内网安全扫描计划。每周对内网的所有服务器进行一次安全扫描,包括开放端口、暴露服务、弱密码等。发现问题及时修复。这项工作我用了 Ansible 自动化,把扫描任务写成了一个 playbook,每周定时执行,结果自动发送到钉钉告警群。
第二,更新应急预案。这次的事件让我意识到,我们之前的应急预案主要针对”服务挂了”的情况,对”被入侵”的情况覆盖不够。这次之后,我更新了应急预案,加入了”发现可疑行为时的处理流程”,包括:发现异常 → 隔离受影响机器 → 排查攻击路径 → 修复漏洞 → 复盘总结。
第三,开展安全培训。这次的问题根源是弱密码和使用习惯。归根结底,人的安全意识是最重要的。我计划下个月组织一次安全培训,给大家讲讲这次事件的经过和教训,让大家都提高警惕。
附:快速检查脚本
提供一个简单的脚本,用于检查路由器 API 的调用频率异常,可以集成到 Prometheus 监控中:
1 | |
这个脚本可以配合 Prometheus 的 blackbox_exporter 或者 script_exporter 使用,实现自动化的 API 频率监控。当调用频率超过阈值时,会自动发送告警到钉钉或邮件。
常见问题解答
Q1:如何判断路由器 API 调用是不是异常的?
A:正常情况下,每小时的 API 调用次数应该是相对稳定的,如果有明显的峰值(比如超过平时的 5 倍),就需要关注。特别要注意凌晨等非工作时间的调用,因为正常运维人员很少在这个时间段操作。
Q2:路由器 API 的调用日志在哪里看?
A:iKuai 路由器本身不提供 API 调用日志,你需要自己在调用端记录。我一般在每台调用路由器 API 的服务器上写一个简单的日志脚本,把每次调用的时间戳、来源 IP、目标功能码记录到一个日志文件里,然后定期分析这个日志文件。
Q3:发现异常调用后应该怎么处理?
A:首先确认是不是自己人或合法脚本的调用(可以通过来源 IP 和调用模式判断)。如果确认是异常行为,立即封锁来源 IP,修改路由器密码,检查服务器是否被入侵,然后复盘分析攻击路径。
作者:小六,一个今天通过路由器日志发现可疑行为的打工人