ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

treg 本地代理实战:一段没有 Key 的代码,如何被团队凭据悄悄喂饱

treg 本地代理实战:一段没有 Key 的代码,如何被团队凭据悄悄喂饱 后端API网关MCP 服务dsh-plugin【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址https://gitcode.com/GitHub_Trending/treg/treg点击查看免费下载导读treg 的本地代理local proxy解决了程序自己直连第三方 API这一最隐蔽的接入场景——当一个脚本直接向api.openai.com、api.stripe.com发出 HTTPS 请求时它既没有 key也从未听说过 treg。本指南以 examples/proxy-demo 中的最小演示为核心讲解如何用treg node server.js让同一份代码在服务端获得团队凭据注入同时剖析 本地代理源码 的拦截、盲隧道与证书机制帮你掌握无需改一行代码即可为任意 HTTP 客户端注入凭据的完整实战方案。演示要旨代码不变凭据来自父进程examples/proxy-demo/是一个故意做得极小的 web 应用它会调用一个它没有 key 的真实 API。整个演示的核心主张可以用三句话概括server.js从头到尾没有提到过 treg它不读取任何 secret它零依赖只用 Node 内置模块。凭据之所以会出现仅仅因为 treg 是它的父进程。这就是本地代理与treg call、/call/URL 等其它入口的本质区别——那些入口要求调用方知道 treg而本地代理在程序发起外呼的路上把它拦下来让服务端去添加凭据。仓库架构文档 docs/context/architecture/local-proxy.md 对此有专门论述源码实现集中在 src/treg/localproxy.py。一分钟跑起来在仓库的examples/proxy-demo/目录下用两种方式运行完全相同的代码node server.js # plain: the call goes out as-is treg node server.js # the same code, credentialed by your team打开 http://localhost:3000点击Call api.openai.com按钮两次运行的差异一目了然运行方式OpenAI 的答复node server.js401 — Missing bearer authentication in header。没有 key调用失败。treg node server.js200和真实的模型列表。treg 在服务端注入了你团队的 key。页面顶部还有一个模式指示条/mode端点会返回viaTreg布尔值实际逻辑是检测HTTPS_PROXY/https_proxy环境变量是否存在见 server.js 第 235-238 行告诉你当前这次运行是否处于 treg 保护之下。前置条件需要api.openai.com工具已在你的活跃团队中注册可用treg tool ls确认。任何已注册的主机都可以——直接编辑server.js顶部的TARGETS常量即可切换目标const TARGETS { openai: { url: https://api.openai.com/v1/models, label: api.openai.com, note: registered with your team }, example: { url: https://example.com/, note: not registered — goes straight out, label: example.com }, };第二个按钮两半承诺的另一半演示页面上还有第二个按钮Call example.com。example.com是一个未注册的主机。它的结果无论哪种运行方式都是200——因为一个 treg 不认识的地址会被原样隧道转发blind tunnel字节被复制但永不被解密也不会为它签发任何证书。这就是本地代理的两半承诺注册的主机→ 被拦截TLS 终止于本地代理签发的叶证书明文请求被重新寻址到 treg 的/call/通道凭据在服务端注入未注册的主机→ 盲隧道直通treg 看不见内容也因此不可能读到程序自己的api.anthropic.com之类的私有流量。在 src/treg/localproxy.py 中这由ProxyConfig.intercepts(host)决定只有主机在 allow-list来自GET /tools且已按成员权限过滤且具备 CA且具备 treg token 时才拦截——终止了 TLS 却没有办法完成这次调用比不拦截更糟因为调用方会以一个它看不到原因的方式失败。演示中的example.com走的是_blind_tunnel路径对应测试 tests/test_localproxy.py 中的test_tunnel_is_byte_faithful与test_tunnel_generates_no_certificate。一个诚实的褶皱Node 与代理演示 README 明确指出了 Node 的一个历史问题Node 内置的fetch会忽略HTTPS_PROXY直到 Node 24。在 Node 24 上treg 设置的环境变量NODE_USE_ENV_PROXY1会开启对代理变量的支持而在Node 23 及更早版本上普通的fetch()会径直绕过代理导致即使在 treg 下运行也得到同样的401。因此这个演示选择显式地对代理说话——先发CONNECT再在隧道之上跑 TLS——也就是throughProxy()函数约 30 行写出来只是为了让演示在任何 Node 版本上都能跑。它的实现要点见 server.js 第 36-100 行解析代理 URL用其中的用户名treg与随机会话 token 构造Proxy-Authorization: Basic ...头发起CONNECT target-host:443对 407 响应给出明确提示HTTPS_PROXY可能是早前会话残留用eval $(treg serve env --unset)清除对ECONNREFUSED同样给出可操作的指引——这是最常见且最令人困惑的失败变量指向一个已停掉的代理CONNECT 成功后用SSL_CERT_FILE或NODE_EXTRA_CA_CERTS指向的信任包建立 TLS 连接这正是 treg 给我们的 bundle系统根 treg 本地 CA再手写 HTTP/1.1 请求由于是手写 HTTP还需要一个unchunk()函数手动解开 chunked 传输编码。真实应用完全不需要这些。所有常见的 HTTP 客户端都已经会读环境变量axios、got、undici的ProxyAgent、python-requests、httpx、curl、git。在 Node 24 上fetch也可以。检查方法node --version # 24 or newer → plain fetch() is captured从源码看本地代理如何工作演示背后的完整机制在 src/treg/localproxy.py本地捕获端与 src/treg/infra/upstream/relay.py服务端注入端之间协作完成。架构文档 docs/context/architecture/local-proxy.md 给出了整体链路a program that has never heard of treg │ HTTPS_PROXYhttp://treg:session-token127.0.0.1:port ▼ local proxy (src/treg/localproxy.py) │ ├─ host NOT registered ──► blind tunnel. Bytes copied, never decrypted │ └─ host IS registered ──► terminate TLS with a leaf we sign re-address it, keeping method/path/query/body │ ▼ treg server POST /call/https://api.stripe.com/v1/charges X-Treg-Token / X-Treg-Org / X-Treg-Client │ relay() injects the credential ▼ api.stripe.com │ ◄─────────────── response streamed back, unchanged ──────────────────┘关键点本地代理携带的只有成员的 treg token任何厂商 key 都不会落到这台机器上。因为被拦截的调用最终落在普通的/call/路径上已经建好的每成员工具列表、项目作用域、deny 规则、每日配额、审计记录、OAuth 刷新全部复用无需第二套策略引擎——这正是这个模块能保持小巧的原因。三个入口同一个引擎本地代理共有三种启动方式由 src/treg/cli.py 的cmd_with、cmd_shell_start、cmd_serve_start分别实现入口生效范围适用场景treg command即treg with command该进程及其子进程常规场景——treg claude、treg node app.jstreg shell start --proxy一个子 shell希望团队 CLI 与裸调用在同一个会话内都生效treg serve配合eval $(treg serve env)任何主动 opt-in 的终端希望跨终端长期运行treg command是主打入口treg 成为被启动进程的父进程环境变量只到达该进程——treg claude使用团队访问权限而普通的claude不受影响、仍用成员自己的 key。而且不写任何配置文件因此无需撤销任何东西。main()通过_looks_like_a_program()实现这一短路当第一个词在with自己的-q/--quiet标志之后不是treg 子命令且存在于PATH上时自动改写为with commandsrc/treg/cli.py 第 6416-6431 行。两个条件缺一不可没有前者一个恰好叫call的二进制会遮蔽treg call没有后者treg toool ls这种拼写错误会变成一次令人困惑的 exec 尝试而不是普通的参数错误。cmd_with的行为如果已有treg serve守护进程在运行就挂载到它上面并保持其运行否则在端口 0上启动一个私有代理——操作系统自动分配端口并行会话永不冲突——并在命令退出时于finally中停止它。子进程通过shell._run_subshell运行忽略 SIGINT/SIGQUIT 以便交互式 Agent 拥有终端且子进程的退出码会成为 treg 的退出码。环境变量把进程指向我们并让它信任我们proxy_env()src/treg/localproxy.py 第 327-362 行返回一组变量其中两个是能用与神秘地毫无反应的分水岭NODE_USE_ENV_PROXY1——Node 18 起内置fetch静默忽略HTTPS_PROXY没有这个标志所有 Node Agent 都会径直绕过代理让整个功能看起来时好时坏NO_PROXY——回环地址和 registry 主机本身绝不能经由我们回流否则代理对 treg 的调用会绕回代理自己。其余变量HTTPS_PROXY/HTTP_PROXY的大小写两种形式——curl 读小写、多数工具读大写以及信任包的多重出口NODE_EXTRA_CA_CERTS、SSL_CERT_FILE、REQUESTS_CA_BUNDLE、CURL_CA_BUNDLE、GIT_SSL_CAINFO、DENO_CERT、AWS_CA_BUNDLE。这保证了 Node、Python、curl、git、Deno、AWS CLI 都能验证本地 CA。代理 URL 形如http://treg:随机token127.0.0.1:porttoken 由mint_token()用secrets.token_urlsafe(24)生成防止本机其它进程借道消耗成员配额。证书每台机器一个 CA系统信任库永不动ensure_ca()在首次使用时按机器生成 CAECDSA P-256、两年期、自签名、BasicConstraints(caTrue)。私有密钥文件以0600权限创建——而且是先以 0600 打开再写入避免先写后 chmod窗口期里私钥世界可读源码注释明确说明了这一点。当证书文件不可读或处于最后 30 天_RENEW_WITHIN_DAYS内时自动重新生成这样过期永远不会以莫名其妙的 TLS 错误形式出现在会话中途。build_bundle()写入系统根 我们自己的 CA追加次序是重点SSL_CERT_FILE等变量是替换信任列表若 bundle 里只有我们的 CA调用方将无法验证真实互联网。叶证书按需签发、按主机缓存为ssl.SSLContext因为 Python 的load_cert_chain只读文件叶证书被写入一个 0600 临时文件、加载完成即刻删除context_for()src/treg/localproxy.py 第 182-209 行。系统信任库永远不会被触碰。信任通过环境变量限定作用域因此只有被启动的进程树信任我们——不是浏览器不是操作系统。allow-list继承成员权限的拦截清单ProxyConfig.hosts来自GET /tools而该接口已经按此成员可用什么过滤过所以 allow-list 免费继承了每成员工具列表与项目作用域——一个成员用不了的主机甚至不会被解密。两个失败模式被刻意处理见架构文档与源码 docstring抓取失败返回空集没有答复绝不能被解读为拦截一切且刷新器绝不用空答案覆盖正在工作的列表——否则会在调用继续外发时静默停止注入。treg shell --proxy与treg command两个入口都用已抓取的工具清单做种子因此开启代理不产生额外请求。服务端一次调用、一个/call/路径被拦截的请求被重新寻址为POST /call/原URLURL-passthrough 形态并携带X-Treg-Token、X-Treg-Org、X-Treg-Client控制头。服务端由relay()注入凭据src/treg/infra/upstream/relay.py。忠实中继契约只改动三样东西hop-by-hop 传输头、treg 控制头、注入的凭据方法、路径、全部查询参数含重复项、请求头、Cookie、body 字节一律原样转发。注入发生在多个绑定上——每个绑定只覆盖它指定的目标头/查询参数/顶层 JSON 字段。这意味着拦截后的调用与treg call走完全相同的策略链成员工具列表、项目作用域、deny 规则、每日配额、审计、OAuth 刷新这就是没有第二套策略引擎的具体含义。安全不变量每一条对应一个会出的事故架构文档 docs/context/architecture/local-proxy.md 以对照表形式列出了安全不变量每条都对应一种具体事故形态#不变量它防止什么1CA 私钥每机器一份、0600、永不外发共享 CA 会让任何持有者向所有用户冒充任意站点2永不触碰系统信任库拦截会蔓延到浏览器和整个操作系统而非仅限被启动的进程3仅 allow-list 拦截读到调用方自己的api.anthropic.com/api.openai.com流量4仅绑定127.0.0.1LISTEN_HOST网络上任何人消耗成员的配额5随机会话 token 禁止调用方伪造控制头本机其它进程、或调用方自己的头冒名顶替6treg_client使用trust_envFalsehttpx 会读自己环境里的HTTPS_PROXY——第一次调用就会绕回我们自己7日志只记主机与状态body、请求头或 token 出现在日志文件其中第 6 条尤其微妙代理自己的出站 HTTP 客户端如果信任环境变量那么HTTPS_PROXY会让它的第一次调用循环回代理自身。因此它显式关闭了trust_env。测试如何证明这一切tests/test_localproxy.py 覆盖了单元与集成两级、全程无网络依赖。值得知道的几条test_tunnel_is_byte_faithful/test_tunnel_generates_no_certificate——未注册主机字节原样转发、且永不为它生成叶证书不变量 3test_a_real_client_trusts_a_leaf_signed_by_our_ca与test_a_client_trusting_only_the_system_roots_rejects_our_leaf——真实 TLS 握手既验证我们签发的叶被信任、也验证只信任系统根的客户端会拒绝它不变量 2test_the_caller_cannot_speak_as_someone_else——调用方无法伪造x-treg-*头test_ensure_ca_writes_a_private_key_only_the_owner_can_read、test_an_expiring_ca_is_regenerated、test_a_corrupt_ca_does_not_brick_the_proxy——证书生命周期与容错test_proxy_env_carries_the_flags_that_matter——环境变量的关键标志位端到端测试test_the_agent_calls_the_vendor_and_treg_injects_the_key驱动一个普通的httpx.Client穿过代理直连真实的FastAPI 应用——这正是演示页面背后那条链路的自动化版本。treg serve的守护进程形态由write_state在~/.treg/proxy/proxy.json0600、先建权后写入记录端口/pid/token/registry/捕获主机running()会在 pid 已死时把状态文件视为未运行并删除否则status会永远声称代理在运行、start也会拒绝替换一个已死的守护进程。pid_alive在调用os.kill前拒绝非正 pid——因为os.kill(0, …)会向调用方的整个进程组发信号。已知限制值得先知道证书固定pinning只接受自己证书的客户端会拒绝我们的叶证书。它只会单独失败需要一张永不可拦截主机清单尚未构建。远程 MCP 服务器不在覆盖范围托管型 MCP 从别人机器发起调用本地 stdio 型 MCP 继承环境、会被捕获。非 HTTPS 协议不覆盖SSH、数据库线协议WebSocket 被隧道化而非拦截。每次被拦截的调用都多一跳 treg 往返treg 宕机即失败——这是key 永不落地的代价。部分厂商 CLI 仍需要treg run比如gh在发起任何网络调用前就拒绝执行无内容可拦截。小结examples/proxy-demo用约 30 行显式代理代码 一个零依赖的 HTTP 服务器把 treg 本地代理的核心承诺压缩成了一次点击实验同一份代码node运行即 401treg node运行即 200已注册主机被服务端注入凭据未注册主机被盲隧道原样直通。理解了这个演示你就掌握了treg command、treg shell start --proxy、treg serve三个入口背后的同一台引擎以及它凭据只存在于服务端、本机仅持有会话 token的安全模型。想继续深入可以依次阅读 本地代理架构文档、代理模型与中继文档、本地运行文档或直接在 tests/test_localproxy.py 里观看测试如何端到端驱动这条链路。赞分享后端API网关MCP 服务dsh-plugin【免费下载链接】tregOpenRouter for agent tools. Join community here: https://discord.gg/6mQYYfFMAn项目地址https://gitcode.com/GitHub_Trending/treg/treg点击查看免费下载相关推荐Reiverr插件开发实战从零开始构建自定义媒体源Reiverr插件开发实战从零开始构建自定义媒体源 Reiverr是一款强大的媒体管理整合工具它为Jellyfin、TMDB、Radarr和Sonarr提供Xemu BIOS配置终极指南从零开始搭建完美Xbox模拟环境Xemu BIOS配置终极指南从零开始搭建完美Xbox模拟环境 Xemu是一款功能强大的原始Xbox模拟器支持Windows、macOS和Linux三大平台游戏开发虚拟化TypeScript中outDir配置对源码可见性的影响机制解析TypeScript中outDir配置对源码可见性的影响机制解析 概述 在TypeScript项目构建过程中outDir配置项的行为机制是一个需要特别注意的技编程语言编译器开发工具创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表