Repository navigation
feat(disguise): harden container spoofing and add in-container OAuth browser - #11
Open
kamikakushi wants to merge 1 commit into
Open
kamikakushi wants to merge 1 commit into
kamikakushi wants to merge 1 commit into
Conversation
…browser spoof-fingerprint.js (informed by reverse-engineering claude 2.1.304): - rewrite /proc/self/cgroup (claude reads it directly) and /proc/self/mountinfo (overlay root rebuilt as ext4) - statSync/accessSync on /.dockerenv and /run/.containerenv throw ENOENT - intercept uname -s/-r/-m/-n/-a consistent with spoofed os.release - patch Intl timeZone and Date.prototype.getTimezoneOffset in tandem (SPOOF_TIMEZONE, fallback to TZ, default America/New_York) - spoof os.availableParallelism (was leaking host core count) - pass machine-id through: entrypoint already provides a unique, persistent value; JS-layer fakes disagreed with shell reads - safeAssign fallback: bun freezes some os builtins (os.tmpdir assignment crashed the claude binary on startup) managed-user entrypoint / image: - machine-id persisted to /var/lib/claude-persist (stable across restarts; was hostname+uptime and changed every boot) - DISGUISE_TZ applied to /etc/timezone + /etc/localtime + env - cgroup memory quota exported as SPOOF_TOTAL_MEM so os.totalmem() does not leak host RAM - BUN_OPTIONS=--preload injected via PID1 env + generated profile.d + /etc/environment (UsePAM=no skips pam_env) - ship spoof module in image; add tzdata - fix RUN_USER unbound variable when disguise runs before user setup In-container OAuth browser: - browser-open.sh installed as cc-browser-open; BROWSER exported so claude /login opens the auth page in the VNC desktop Chromium: auth traffic shares the sing-box egress IP and the localhost callback stays inside the container - launch-chromium.sh: keep WebRTC leak-protection flags when a URL argument is passed (was exec chromium "$@" bare) tools: - claude-spoofed.sh: document that BUN_OPTIONS is the only working injection channel for bun-compiled claude - dns-guard.js: document bun-runtime ineffectiveness (network layer is built-in; telemetry blocking relies on sing-box + nft) - spoof-selftest.js: 22-case self-test Verified end-to-end in a real Linux container: env injection in SSH login shells, machine-id stable across docker restart, date showing target timezone, claude loading the spoof identity, chromium opening on the VNC display, egress policy routing via tun0.
This branch has not been deployed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
背景
对 claude 2.1.304(bun 编译二进制)做了逆向分析,确认了其实际采集路径,并据此补强容器伪装层。同时解决
claude /login浏览器认证无法走容器网络的问题。关键事实(逆向结论)
NODE_OPTIONS=--require对 bun 编译版无效,BUN_OPTIONS=--preload是唯一有效注入通道/proc/self/cgroup(.includes("docker"))、/proc/self/mountinfo、statSync("/.dockerenv"),并跑uname -s/-r/-m采集内核localhost:随机端口,本机浏览器无法回调;且本机认证流量出口 IP 与容器 API 不一致,触发关联风控改动内容
tools/spoof-fingerprint.js(重写补强)
/proc/self/cgroup改写(此前只改/proc/1/cgroup,claude 有直接读 self 的路径)/proc/self/mountinfo改写:overlay 根挂载重建为 ext4,丢弃 docker 卷挂载行statSync/accessSync对/.dockerenv、/run/.containerenv抛 ENOENT(此前只有existsSync)uname(-s/-r/-m/-n/-a),输出与os.release()伪装值一致Intl.DateTimeFormat().resolvedOptions().timeZone与Date.prototype.getTimezoneOffset指向同一目标(SPOOF_TIMEZONE→TZ→ America/New_York)os.availableParallelism伪装(双注入实测发现泄漏宿主核数)safeAssign降级赋值:bun 对os.tmpdir等内置导出只读冻结,直接赋值导致 claude 启动崩溃(新旧版本共同的雷,首次在 bun 实测暴露)managed-user 镜像 / entrypoint
/var/lib/claude-persist(原 hostname+uptime 派生,每次重启漂移 → 遥测端看到"频繁换设备")DISGUISE_TZ落地/etc/timezone+/etc/localtime+ 环境(Date/Intl/shell 三层一致)SPOOF_TOTAL_MEM(os.totalmem()返回宿主物理内存,按配额伪装)BUN_OPTIONS=--preload三通道注入(PID 1 进程环境 + entrypoint 生成的profile.d/zz-disguise.sh+/etc/environment)——镜像UsePAM=no,/etc/environment单通道不进 login shellRUN_USER: unbound variable(伪装函数提前到用户变量初始化之前执行)容器内 OAuth 浏览器
browser-open.sh(/usr/local/bin/cc-browser-open):claude 经$BROWSER在 VNC 桌面 Chromium 打开授权页,认证流量与 API 同走 sing-box 出口,回调走容器内 localhostlaunch-chromium.sh带 URL 参数时丢失全部 WebRTC 防泄漏 flags 的问题其他
claude-spoofed.sh/dns-guard.js:标注实测局限,避免误判有进程内网络拦截tools/spoof-selftest.js:22 项自测验证
node tools/spoof-selftest.js:22/22 通过date显示目标时区、machine-id 跨docker restart稳定、claude 实际加载伪装身份(hostname/platform/timezone/cpus/totalMem=配额值/release)、$BROWSER调用后 Chromium 弹出于 VNC 桌面、策略路由确认浏览器流量走 tun0/proc/self/cgroup本来就是0::/,相关 patch 属双保险遗留(另行处理)
DISGUISE_TZ(当前缺省 America/New_York)