Skip to content

KKarsyline/ccroach

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

1 Commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

ccroach 🪳

A paranoid Claude Code wrapper for macOS machines. 三层 fail-closed 防护——wrapper + Proxy + PF——让 Claude Code 的流量物理上只能从一个固定 IP 出去。


⚠️ 叠甲:

1.这是一个笨重、overthinking、作者严重封号焦虑下产生的且不一定有意义的极端产物,仅作为我自己的技术/思路分享,并非正式project; 2.代码部分完全由claude,GPT接力完成,不保证没有bug完全能跑; 3.A\封号受多方面因素影响(例如ip本身,用户使用习惯等等),这个项目只是为cc的运行提供一个稳定的网络环境,减少ip泄漏的风险,不保证能完全规避封号的可能性; 4.这个项目在proxy配置,pf kill switch上的策略非常极端,仅供参考;推荐落地的只有wrapper部分,且在落地wrapper前,也强烈建议和你的AI先行讨论并且修改/删除部分条件; 5.请保证你在正式实施前阅读完所有前置条件;


这是什么

ccroach 是一套围绕 macOS 上 Claude Code的 fail-closed 网络隔离方案。它的设计前提是:

  • 我肉身在国内,因此有网络环境的需求
  • 我的被封号焦虑大于对工作效率的追求,我不是重度coding用户,对我来说我的账号比项目本身更加重要
  • 我有一台单独的mac用于我的AI agent工作,我希望这台机器上的 claude等开发流量从一个固定的公网 IP 出去
  • 我不介意任何网络异常、代理链崩溃、IP 漂移、IPv6 leak、DNS泄漏国内ip都导致拒绝启动 / 立刻杀掉这个进程,而不是 fallback 到真实 IP,我不在乎当前操作进度中断造成的后果

三层架构

┌─────────────────────────────────────────────────────────────┐
│  Claude Code / Codex / npm / pip / git / curl ...           │
└───────────────────────────┬─────────────────────────────────┘
                            │  Wrapped & gated by
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Layer 1 · ccroach wrapper(应用层)                          │
│    • 完全接管CC启动,启动前 8 项 precheck,未通过 → 拒绝启动       │
│    • 后台 daemon 每 5s 监控 IP / PF / DNS                     │
│    • 异常时 kill cc 进程 + macOS 通知                         │
└───────────────────────────┬─────────────────────────────────┘
                            │  HTTPS_PROXY=127.0.0.1:6152
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Layer 2 · Proxy Enhanced Mode(策略层)                     │
│    • Proxy Chain: 机场入口 → 美国家宽 SOCKS5                  │
│    • FINAL → strict policy (no DIRECT, no fallback)         │
│    • DoH 跟随出站策略                                         │
└───────────────────────────┬─────────────────────────────────┘
                            │  TCP only to airport ingress
                            ▼
┌─────────────────────────────────────────────────────────────┐
│  Layer 3 · PF kill switch(物理网卡层)                       │
│    • en0 只放行 → <airport_ip>:<airport_port>               │
│    • IPv6 全封 / DNS 53/853 全封 / 私有段全封                 │
│    • 兜底 block out(fail-closed)                           │
└───────────────────────────┬─────────────────────────────────┘
                            │
                            ▼
                        Internet
                  (only via your egress IP)

三层互相独立——任何一层失效,其他两层仍然能拦住绝大多数泄露路径。这就是为什么 wrapper 检查 PF 状态、PF 不信任 wrapper、Surge 不信任 PF:三方互不背书。


设计哲学:fail-closed

原则 含义
断网 = 正确失败 网络异常时拒绝启动 / kill cc,不允许 fallback 到任何其他出口
三层独立证据 wrapper / Surge / PF 不互相信任,每层独立验证
物理边界优先 可信边界是 PF 对物理网卡的控制优先
不做大锤式断网 wrapper 只 kill cc 进程;不会 down 网卡、不会 pkill Surge、不会 route delete default

不适合的情况

如果符合下面任何一条,请谨慎考虑

  • ❌ 电脑是日常工作 / 上网机,AI 只是偶尔用一下的工具
  • ❌ 没有固定公网出口 IP(住宅 ISP 动态分配 / 经常切换网络),或网络条件非常不稳定、极易出现断联or超时现象(会增加cc被误杀的概率)
  • ❌ 需要这台机器同时跑别的需要其他出口的服务

可能适合:封号/网络环境焦虑大于对工作效率的追求的人、有 dedicated Mac 给 AI / 工作 agent 的人、对 IP 隐私有刚性需求的开发者、想要 fail-closed 而不是 best-effort 的 paranoid 用户。


前置条件

硬件 / OS

  • 一台 专门 给 AI / Claude Code 使用的 Mac(如果电脑有日常使用需要的话,必须对Proxy和PF策略进行删除或修改,并且对wrapper进行对应调整)
  • 物理网卡接口名(一般 Wi-Fi 是 en0,跑 ifconfig 确认)

网络

  • 一个靠谱的proxy软件,可以自定义编写调整策略(这里采用surge)
  • 一个固定出口公网 IPv4——可以是:
    • 美国家宽 SOCKS5(推荐)
    • 任何你能确定 IP 稳定的代理
  • 你的机场入口 IP + 端口(用来在 PF 里放行唯一公网出口)

软件

  • 已安装的 Claude Code(npm install -g @anthropic-ai/claude-code 或类似)
  • bash 4+ / coreutils(macOS 自带的够用)

安装步骤梗概

1. 拉代码

git clone git@github.com:<your-username>/ccroach.git ~/.ccroach
cd ~/.ccroach

2. 配置 ccroach 本身

cp etc/config.example.toml etc/config.toml
# 编辑 etc/config.toml,填入你的:
#   expected_ipv4   = "<YOUR_EXPECTED_EGRESS_IPV4>"
#   airport_ip      = "<YOUR_AIRPORT_INGRESS_IPV4>"
#   airport_port    = <YOUR_AIRPORT_PORT>
#   physical_interface = "en0"  # 你的物理网卡

3. 配置 Proxy

⚠️ 仅供参考:本节描述的是我本机 Surge profile 的关键约束,并非通用配置模板。每个人的机场订阅、节点格式、策略偏好都不一样,请根据自己的情况进行重写or修改。 我自己的 Surge profile 的设计条件是:

  • Enhanced Mode 开启(系统全局代理)
  • 唯一允许出口指向你的 airport_ip:airport_port
  • FINAL 走你的 strict policy(禁用 DIRECT / fallback / url-test / load-balance / 自动选择)
  • DoH / DoT 跟随出站策略,不走系统 DNS
  • IPv6 关闭
  • 因为不是日常用机,这里我不保留日常分流、Domestic、Debug、DIRECT

4. 装 PF kill switch(‼️如果是有日常使用需要的电脑的话强烈建议不要使用PF部分,或者一定需要对PF策略进行大改)

⚠️ 仅供参考pf/surge-killswitch.example 是我本机 PF anchor 的脱敏样本,反映我的具体网络环境(单一物理网卡、固定家宽出口、无 IPv6 需求等)。你的硬件 / 网卡数 / 链路结构如果不同,请根据自己的情况进行修改,不能直接照搬。 装 PF 之前请多次检查——‼️错误的 PF 规则可能导致你完全连不上网且无法 ssh 回来修‼️

# 编辑 pf/surge-killswitch.example,替换占位符 + 按你的环境调整规则
vim pf/surge-killswitch.example
# 然后装到系统:
sudo cp pf/surge-killswitch.example /etc/pf.anchors/surge-killswitch

# 在 /etc/pf.conf 里加上(如果还没加过):
#   anchor "surge-killswitch"
#   load anchor "surge-killswitch" from "/etc/pf.anchors/surge-killswitch"

sudo pfctl -f /etc/pf.conf
sudo pfctl -e

我这里另写了一个 LaunchDaemon 让 PF 开机自启。

5. 装 PATH shim

# 让 claude 命令默认走 ccroach
mkdir -p ~/bin
ln -sf ~/.ccroach/bin/claude ~/bin/claude
# 在你的 ~/.zshrc 或 ~/.bashrc 里添加:
#   export PATH="$HOME/bin:$PATH"

6. 装 LaunchAgent(daemon 后台保活)

# 编辑 launchd 模板把 REPLACE_ME_USERNAME 换成你的用户名
sed -i '' "s|REPLACE_ME_USERNAME|$USER|g" launchd/ccroach.daemon.plist.example
cp launchd/ccroach.daemon.plist.example ~/Library/LaunchAgents/ccroach.daemon.plist
launchctl load ~/Library/LaunchAgents/ccroach.daemon.plist

7. 首次跑

# 跑一次 precheck,看 8 项是否全绿
~/.ccroach/ccroach check

# 全绿了再正式启动 Claude Code
claude  # 走的是 shim,会被 wrapper 接管
# 看到 "Type START to continue" → 输入 START 启动

子命令

命令 说明
ccroach run [args...] 跑 precheck → 等 START 提示 → 启动 daemon → 启动真实 claude
ccroach check 只跑 precheck,不启动 cc
ccroach daemon 跑后台监控 daemon(一般 LaunchAgent 调用,不手跑)
ccroach status 当前状态(缓存值,非实时)
ccroach logs 调取实时日志(相当于 tail -f daemon 日志)
ccroach stop 停止 cc 和 daemon

Precheck 检查项

启动前 wrapper 会跑这 8 项:

  1. Surge — 进程在跑 + 6152 端口监听
  2. PF — ICMP 直连被阻 + TCP 直连被阻(不采用pf策略的话这里需要删掉)
  3. Surge 链路 — 经 Surge 出口 IP 等于 expected_ipv4
  4. IPv4 三源 — ipify / ifconfig.me / icanhazip 至少 2/3 都返回 expected_ipv4
  5. IPv6 — 四层独立验证:
    • 接口层(无全局 v6 地址)
    • 系统层(macOS Wi-Fi 服务 v6 = Off)
    • PF 运行层(v6 literal 探针被秒拒)
    • PF 配置层(surge-killswitch 文件里有 block drop quick inet6 all
  6. DoH 出口 — 经 Surge 的 DNS-over-HTTPS 正常工作
  7. 直连 DNS TCP/53 — 被 PF 封死
  8. 直连 DNS UDP/53 — 被 PF 封死

任何一项 fail → 拒绝启动。


Daemon 监控项

后台 daemon 每 5 秒跑一次轻量监控(不跑完整 8 项 precheck,避免对网络造成持续负担):

  • 每次:当前出口 IP 是否仍等于 expected_ipv4
  • 每 30 秒一次:PF ICMP / TCP 直连探针
  • 每 60 秒一次:DoH 工作正常 + 直连 UDP/53 被封

返回码:

  • 0 = OK
  • 1 = HARD FAIL(确诊 IP 错误 / PF 漏洞)→ 立即 kill cc
  • 2 = SOFT FAIL(网络抖动 / 临时无响应)→ 累计 3 次才 kill,避免误杀

重要保护:daemon kill 之前会检查 cc 是否真的在跑——cc 没在跑就只写 log,不弹通知,不退出。避免你不开 cc 时网络抖动也跳通知。


已知踩坑 / 设计取舍

这些是开发过程中真实踩过的坑,仅供参考。

Read deny 对带空格路径失效

settings.json 里的 Read deny 规则用 glob 时,如果路径含空格(比如 Library/Application Support/Surge/),匹配会失效。解决:用 ** 通配符替代(Library/**/Surge/**)。

chflags uchg 不阻止读取

chflags uchg 只阻止写 / 删 / 改名,不阻止读。如果你想完全阻止 cc 读某个敏感文件,需要 chmod 改权限或挪到 root-owned 路径。

Surge HTTP API 端口

127.0.0.1:6170/6171 是 Surge 的本地 API 端口。如果不显式 deny,理论上 cc 可以通过它修改 Surge profile。我们的方案是 settings.json 里 deny 整个 127.0.0.1localhost 的 WebFetch + deny curl 127.0.0.1:6170 类 bash 命令。

IPv6 check 不能用域名

如果用 curl -6 https://api64.ipify.org 测 IPv6 leak,Surge MitM DNS 会把域名解析成 fake IPv4 ::ffff:198.18.x.x,curl 看到 v6 socket 就以为通了。正确做法是用 IPv6 literal 直连(比如 nc -6 -z 2606:4700:4700::1111 443)绕开 DNS。

不要相信 utun 接口

utun0-9 不一定是 Surge 创建的——其他 VPN、Tailscale、WireGuard、系统隧道都可能创建。PF 规则只盯物理网卡(en0),不显式信任任何 utun。

不要做 panic 断网

曾经讨论过 route delete default / ifconfig en0 down / pkill Surge 这类"全锁死"方案。最终拒绝——PF 已经提供 fail-closed,wrapper 只需要 kill cc。乱关网卡会增加恢复复杂度。


仓库结构

ccroach/
├── README.md                          ← 你正在看的这个
├── LICENSE                            ← MIT
├── .gitignore                         ← 排除 var/、log、用户真实 config.toml
├── ccroach                            ← 主脚本(~500 行 bash)
├── bin/
│   └── claude                         ← PATH shim,让 `claude` 命令走 wrapper
├── etc/
│   └── config.example.toml            ← 配置模板(填占位符)
├── launchd/
│   └── ccroach.daemon.plist.example   ← LaunchAgent 模板
└── pf/
    └── surge-killswitch.example       ← PF anchor 模板
---

## License

MIT。

---

## 使用感受
Mac air跑cc时后台挂着daemon并没有感受到明显负担or卡顿的情况,也基本上没有误杀的情况,姑且算是使用体验良好,但不确定哪里会不会有bug,readme大部分是CC和GPT写的,怨气有点大有些地方可能语气不太友好hhh


🪳 *Like a cockroach: small, persistent, lives quietly in the corner, almost impossible to dislodge once installed.*

About

一个用于claudecode的wrapper,推荐仅作参考

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages