-
Notifications
You must be signed in to change notification settings - Fork 6
Description
需求描述
这里定义为获取终端 "用户" ip, 考虑到实际场景需要 bypass proxy / LB
基本要求
- 以 fastify 的
plugin形式产出组件 - 编写 unit test,实现代码 100% 全覆盖
单元测试的编写参考:@fe/byted-consul
思路
-
直连或透明代理由 TCP 协议获取
-
proxy / LB 从 http 协议(header)获取
-
一些标准化的云服务 / LB 服务, 从 header 中标准定义获取
策略梳理
-
优先 header 关键字判定, 命中则为 proxy / LB
-
检查最标准无歧义的 header:
X-Client-IP一般国外云服务商(Amazon / Heroku)遵循的业界标准
-
检查记录代理信息的 header:
x-forwarded-for和x-real-ip都为约定速成的 header,
x-forwarded-for目前应用最广泛,x-real-ip是早期 fastcgi 等默认的 headernode 服务最常见的 proxy 和 LB 默认配置, 属性值为
[client_IP, proxy1_IP, proxy2_IP, ...]如果是可控的 proxy 配置, 例如公司 TLB(nginx), 确保:
location配置包含proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;或proxy_set_header X-Real-IP $remote_addr; -
检查一些常见云服务商约定的 header:
cf-connecting-ip(Cloudflare)true-client-ip(Akamai)x-cluster-client-ip(一些 LB 服务商标准)
-
检查
x-forwarded-for的常见变体:x-forwardedforwarded-forforwarded
-
-
取 TCP 协议中的
remoteAddress(只有两种情况下可以获取 client ip, 与 client 直连或是经过透明代理)透明代理的 nginx 配置:
proxy_bind $remote_addr transparent;按 node net 模块 实现, 依次检查:
req.connection.remoteAddressreq.socket.remoteAddressreq.connection.socket.remoteAddressreq.info.remoteAddress
-
兼容一些 serverless 服务商, 从
req附加 context 获取req.requestContext.identity.sourceIp(AWS Lambda)