技术探索与实践:从司机端埋点到爬虫反制,我的安全边界意识

林平
2025-12-18 22:07
阅读 2055

大家好,我是老K,滴滴后端开发一枚,混迹司机端核心业务组快两年了。之前在别的大厂摸鱼三年多,算是个“四年经验”的老新人(别问,问就是简历注水)。平时除了修 Bug、怼产品经理的需求文档,最大的爱好就是扒开源项目的源码——不是为了装X,是真的觉得有些设计骚得让人头皮发麻。

去年双11前夕,我们组接了个新活儿:要搞一套“异常行为识别系统”,用来检测司机端有没有被第三方工具篡改或者模拟。说白了,就是防外挂、防刷单、防数据造假。这任务来得猝不及防,PM拍着桌子说:“老板说,安全是底线,出了事谁都跑不了。” 我当时就心里一咯噔——这不就是要把我平时研究的那些“灰色地带”技术反过来用吗?

今天这篇文章,不讲高大上的架构图,也不画PPT式的技术路线,就聊聊我在实战中踩过的坑、写过的工具、还有那点越来越强的安全意识。关键词你可能也注意到了:工具、区块链、爬虫。别急,等我说完你就明白它们怎么串起来了。


起因:一个凌晨三点的报警

事情的导火索发生在今年3月的一个周五晚上。我刚躺下准备睡个美容觉(程序员哪来的美容觉?),手机突然狂震——线上监控告警:司机端日志上报量突增300%

我连滚带爬打开电脑,一看日志流:全是重复的 GPS 位置 + 接单动作,时间戳精确到毫秒级,而且 IP 分布极其集中。很明显,有人在用自动化脚本模拟司机行为,试图刷服务分、薅平台补贴。

运维同事甩过来一句:“是不是你们后端没做频率控制?”
测试小哥补刀:“前端埋点是不是漏了校验?”
我:……(内心OS:锅怎么又砸我头上了?)

但吐槽归吐槽,问题得解决。我们初步判断:攻击者用了定制化爬虫 + 本地代理池 + 自动化点击工具。更麻烦的是,这些请求伪装得极像真实用户——User-Agent 正常、TLS 指纹合规、甚至还会模拟滑动解锁。

这时候我才意识到:光靠传统的限流、IP 封禁已经不够了。我们需要更细粒度的行为分析,以及更强的数据可信机制


工具链升级:从日志采集到行为指纹

首先得把数据收上来。我们原本的日志埋点系统是基于 Kafka + Flink 的实时管道,但字段太粗,连设备型号都丢了。于是我和数据组的老李一起重构了埋点协议,加了几个关键字段:

  • 设备硬件指纹(基于 IMEI、MAC 地址哈希,当然做了脱敏)
  • 屏幕操作轨迹(比如点击坐标序列、滑动速度)
  • 网络环境特征(WiFi SSID 哈希、基站 ID)
  • TLS Client Hello 指纹(用 JA3 算法生成)

注:所有敏感信息在客户端就做哈希或加密,绝不明文上传。这是滴滴内部的安全红线,违者直接进“红牌区”(真的有这个制度)。

接着,我们开发了一个轻量级 SDK,集成到司机端 App 里。核心逻辑是:每次关键操作(如接单、到达、结束)都会附带一个“行为签名”,由本地生成,不可伪造。

// 伪代码示意:生成行为签名
public String generateBehaviorSignature(Operation op) {
    String raw = op.deviceId + "|" + op.gps + "|" + op.timestamp + "|" + SECRET_SALT;
    // 使用设备私钥签名(私钥由TEE安全环境保管)
    return HmacSHA256(raw, getDevicePrivateKey());
}

这个私钥只存在于手机的安全芯片(比如高通的 QSEE 或华为的 TrustZone)里,App 本身都读不到。即使 APK 被逆向,也拿不到密钥。这招是从 Android SafetyNet 里学来的,效果拔群。


区块链?别慌,不是你想的那样

说到“区块链”,很多人第一反应是比特币、NFT、炒币割韭菜。但在我们这个场景里,它干了一件特别朴实的事:提供不可篡改的日志存证

为什么需要这个?因为一旦发现异常行为,我们要能回溯证据链——证明这条数据确实是某台设备在某个时间点产生的,而不是中间人伪造的。

我们没用公链(性能太差),也没搞联盟链(运维成本太高),而是基于 Hyperledger Fabric 搭了个内部轻量级账本。每天凌晨,Flink 作业会把前一天所有“高风险行为事件”打包成 Merkle Tree,根哈希上链。

字段 说明
EventID 行为事件唯一ID
DeviceFP 设备指纹(脱敏后)
BehaviorSig 客户端生成的签名
MerkleRoot 当日批次日志的Merkle根
BlockHash 链上区块哈希

这样一来,审计时只需比对:

  1. 客户端签名是否有效
  2. 日志是否包含在当日 Merkle Tree 中
  3. Merkle Root 是否与链上记录一致

三者合一,基本可以排除日志被篡改的可能。虽然听起来有点“杀鸡用牛刀”,但法务和风控部门特别吃这套——毕竟“上链”两个字在汇报材料里显得很高级(手动狗头)。


反爬虫:一场猫鼠游戏

最头疼的还是对抗爬虫。攻击者也在进化:从最早的 Selenium,到后来的 Puppeteer,再到现在的 Playwright + 住宅代理 + 模拟传感器数据,简直卷成麻花了。

我们的策略是“分层防御”:

第一层:网络层

  • 用 Nginx 模块检测 TLS 指纹异常(JA3 不匹配直接 403)
  • 限制同一 IP 的连接速率(但要小心误伤网约车热点共享场景)

第二层:应用层

  • 关键接口增加“挑战-响应”机制(类似 reCAPTCHA,但更轻)
  • 所有请求必须携带有效的 X-Behavior-Token(由 SDK 动态生成)

第三层:行为分析

  • 用 Flink 实时计算用户操作熵值(比如点击分布是否过于均匀)
  • 引入图神经网络(GNN)检测设备-账号-IP 的关联异常

这里有个真实案例:我们发现一批账号总是在固定时间、固定地点“接单”,且 GPS 轨迹呈完美直线。正常人开车哪有这么精准?立马标记为高危,配合封禁。

但最骚的操作来自攻击者:他们开始用真机集群 + 自动化脚本模拟人类操作,甚至还加入了随机延迟和误触。一度让我们模型准确率暴跌。

最后我们祭出了终极武器:设备传感器融合。通过司机端 App 获取加速度计、陀螺仪数据,判断设备是否处于“静止状态却上报行驶轨迹”。这一招直接让 80% 的假司机现形——毕竟手机放在桌上可不会产生真实的车辆震动频谱。


安全意识:不是功能,是本能

在整个项目推进过程中,我最大的感悟是:安全不是某个模块,而是一种开发本能

以前写代码,我可能只关心“能不能跑通”;现在第一反应是:“这个参数会不会被注入?”、“这个接口会不会被重放?”、“日志里有没有泄露敏感信息?”

举个例子:我们曾有个接口返回司机历史订单列表,结果某次上线忘了脱敏,把乘客手机号直接返回了。虽然很快回滚,但还是被安全团队抓去写了 2000 字检讨(是真的!)。从那以后,我对“数据出口”格外敏感,所有对外输出都过一遍脱敏过滤器。

另外,公司内部的 SRC(安全响应中心) 经常搞“红蓝对抗”演练。上周我还被拉去当蓝军,用 Burp Suite + 自研爬虫去攻击测试环境。结果发现一个 SSRF 漏洞,奖励了 500 块京东卡——这钱花得比工资还香!


效果与反思

上线三个月后,异常行为识别准确率达到 92%,误杀率控制在 0.3% 以下。更重要的是,外部爬虫攻击量下降了 70%。风控那边终于不再天天@我们“紧急排查”了。

但我也清楚,这是一场永无止境的攻防战。今天防住了 Playwright,明天可能冒出新的 AI 模拟器。所以团队现在每周五下午固定搞“技术雷达会”,轮流分享最新攻击手法和防御思路。

至于区块链?说实话,它在这套系统里的作用更多是“信任增强”,而非核心逻辑。但我并不后悔引入它——至少让跨部门协作时,大家对数据真实性少了很多扯皮。


写在最后

作为一线后端,我越来越觉得:真正的工程能力,不在于你会多少框架,而在于你能否在复杂约束下,做出安全、可靠、可维护的系统

工具只是手段,区块链不是银弹,爬虫永远存在。但只要我们保持警惕、持续学习、尊重规则(尤其是安全规则),就能在混沌中守住那条底线。

对了,如果你也在做类似的安全对抗项目,欢迎交流(私信暗号:“滴滴司机老K”)。但别问我怎么绕过风控啊——我可是签了保密协议的,真说了怕HR半夜敲我家门 😅


本文纯属个人经验分享,不代表滴滴官方立场。文中涉及的技术细节均已脱敏,如有雷同,纯属巧合。

评论 0

最热最新
暂无评论
林平Lv.1
0
影响力
0
文章
0
粉丝