一个有意思的问题引起了我的反思

前两天逛V站,看到一个帖子《macos 抓包最佳实践是什么?》,这不是问到我的专业领域了嘛,赶紧点开看看。

这不巧了,用的正好是Reqable,找对工具就成功了80%,我心里好一阵开心,赶紧看看问题是什么。

1. 问题的场景

提问者的场景其实很简单,需要用Reqable抓下AI接口的调用数据。由于国外的几大AI巨头屏蔽了国内IP的访问,在抓包时,程序发起HTTP请求,会先访问Reqable,Reqable再访问AI接口服务器,这是一个代理的过程。但是Reqable并不具备科学上网的功能,所以这个访问会失败。解决方法正如提问者所说配置一个二级代理,让Reqable去访问Clash代理,Clash去访问AI接口的服务器,链路如下:

scss 复制代码
client -> reqable(port:9000) -> clash(port: 7890) -> server

可以看出提问者的网络基础知识非常扎实,找到了正确的方式。接下来是他遇到的问题,浏览器上好使,但是在命令行里面跑程序就不好使了,原因和解决方案他也找到了:

第一个要在命令行里面配置代理环境变量,因为命令行并不会和浏览器一样自动读取系统代理配置,需要手动配置。

第二个是运行的程序不会读取命令行中配置的代理环境变量,还需要改代码强行走代理。从楼下的回复来看,应该是用的Javascript写的程序,需要加入如下代码,读取环境变量中的代理地址。

js 复制代码
setGlobalDispatcher(  
    new ProxyAgent(process.env.HTTP_PROXY)
);

很明显,这个解决方案是临时的,非常繁琐不方便,所以他有了疑问:抓包最佳实践是什么?爱思考才能有进步,偷懒是科技进步的动力。

相信这个场景很多开发者都会遇到,我们也考虑过这个问题,并给出了解决方案:代理终端

2. 代理终端如何用?

在Reqable顶部本机地址的后面有一个命令行图标,点击一下就可以打开代理终端了(快捷键 Alt + T)。

点击之后会打开一个命令行窗口,显示一个帅气的Reqable艺术照。

接下来,只需要直接在这个命令行里面正常运行程序就可以了,不需要配置环境变量,不需要修改代码,Everything is OK!

Reqable支持哪些命令行工具呢,有下面这些:

  • Windows: cmd(默认)、PowerShell和Pwsh。
  • Mac: Terminal(默认)、iTerm2。
  • Linux: gnome console(Ubuntu)和konsole(KDE)、xterm。

注意:不用默认的命令行,可以图标右键点击修改默认启动的命令行工具。

为什么代理终端可以解决上面的两个问题呢,我们接下来揭晓答案。

3. 代理终端的原理是什么?

在启动命令行工具之后,我们会自动执行一段脚本,这个脚本做了下面几件事情。

首先,配置环境变量,把HTTP_PROXY和HTTPS_PROXY设置为Reqable的代理地址,例如 127.0.0.1:9000。

接着,修改PATH环境变量,在运行程序之前先执行我们预设好的程序进行Hook。比如要通过node执行一个JS程序,命令行从PATH中搜索node可执行程序的时候,由于我们的假node在PATH中位置最前面,就先找了这个假node,我们在其中先执行一段逻辑,例如强制网络框架走代理,强制不进行SSL验证等等,然后再调用系统真正的node来运行需要执行的程序。

sh 复制代码
#!/bin/sh
set -e

# Find system node path
PATH="$(printf '%s\n' "$PATH" | sed "s:$(dirname "$0")\:::g")"
systemNode=`command -v node`
PATH="`dirname "$0"`:$PATH"

# Find the override script path
OVERRIDE_SCRIPT_PATH=`dirname "$0"`/override.js

# Call system node with the override script
"$systemNode" -r "$OVERRIDE_SCRIPT_PATH" "$@"

上面是一个shell脚本,在Windows上是bat脚本,内容大同小异。我们插入的逻辑在override.js里面,强制网络框架走代理。

js 复制代码
const globalAgent = require("global-agent");
globalAgent.bootstrap();

// For node fetch usage
const Undici = require('undici');
const ProxyAgent = Undici.ProxyAgent;
const setGlobalDispatcher = Undici.setGlobalDispatcher;
setGlobalDispatcher(
  new ProxyAgent(process.env.HTTP_PROXY)
);

最后一步,也是最关键的一步。输入一个帅气的Reqable艺术照,把逼格拉高。

sh 复制代码
"echo '______                 _     _      '",
"echo '| ___ \               | |   | |     '",
"echo '| |_/ /___  __ _  __ _| |__ | | ___ '",
"echo '|    // _ \/ _` |/ _` | `_ \| |/ _ \'",
"echo '| |\ \  __/ (_| | (_| | |_) | | ___/'",
"echo '\_| \_\___|\__. |\__._|_.__/|_|\___|'",
"echo '              | |                   '",
"echo '              |_| '",

手敲上面这段是不可能的,我们找了一个text-to-ascii-art的网站自动生成。

上面是Node自动Hook的原理,而像Python又有很大的不同了,Python不是通过修改PATH环境变量来Hook,而是通过PYTHONPATH来指定路径Hook掉httplib、aiohttp等网络库,具体代码比较多,这里写不下,就不放出来了。

目前Reqable代理终端支持NodeJS、Python和Ruby三种程序的强制代理,当前其他的不需要强制代理的也可以使用。如果大家有其他需要支持的或者方案实现,欢迎在评论区一起讨论交流。

4. 我在反思什么?

这么好用的功能为什么大家都不知道,这个问题不得不引起我的反思。说明,我们的文档和教程做得不够好不够细,后面要大大加强这方面的建设。

感谢大家的阅读,欢迎体验我们的产品:

新一代API开发工具 - Reqable

未来属于Reqable!

相关推荐
JohnYan1 小时前
Bun技术评估 - 30 SSE支持
javascript·后端·bun
程序猿_极客1 小时前
【2025最新】 Java 入门到实战:数组 + 抽象类 + 接口 + 异常(含案例 + 语法全解析+巩固练习题)
java·开发语言·后端·java基础·java入门到实战
鹤归时起雾.1 小时前
CSS属性继承与元素隐藏全解析
前端·css
火星数据-Tina1 小时前
让电竞数据实时跳动:Spring Boot 后端 + Vue 前端的完美融合实践
前端·vue.js·spring boot
v***43171 小时前
spring.profiles.active和spring.profiles.include的使用及区别说明
java·后端·spring
fruge1 小时前
前端可视化家庭账单:用 ECharts 实现支出统计与趋势分析
前端·javascript·echarts
IT_陈寒2 小时前
Vue3性能优化实战:5个被低估的Composition API技巧让你的应用快30%
前端·人工智能·后端
嘻嘻哈哈猿人2 小时前
从 0 到 1 实现一个支持 @ 提及用户的输入框组件(Vue3 实战)
前端·vue.js
Moe4882 小时前
@SpringBootApplication 注解(Spring Boot 自动配置)详解
java·后端