Project Gleipnir
Project Gleipnir
Gleipnir: confining AI coding agents on a home Linux workstation. A home-lab writeup by Patrick Robinson. Industrial electrician and automation tech moving into OT/ICS network security; CompTIA Network+ verified badge, Security+ in progress.
Gleipnir:在家庭 Linux 工作站上限制 AI 编程代理。这是一篇由 Patrick Robinson 撰写的家庭实验室报告。他是一位工业电工和自动化技术人员,目前正转向 OT/ICS 网络安全领域;拥有 CompTIA Network+ 认证,正在考取 Security+。
What I built: I use two AI coding agents (Anthropic’s Claude Code and OpenAI’s Codex) to help me study and build. Agents like these can run commands, read files, and reach the internet, so I didn’t want them running as me. Gleipnir is the environment I built so they can be genuinely useful on my workstation while staying inside walls that I control and have tested. The goals were simple to state and took real work to meet: Each agent is protected from the other. I’m protected from either agent misbehaving. All three of us still share one knowledge base (my study notes), because that’s the whole point.
我的构建内容:我使用两个 AI 编程代理(Anthropic 的 Claude Code 和 OpenAI 的 Codex)来辅助学习和开发。这类代理可以运行命令、读取文件并访问互联网,因此我不希望它们以我的身份运行。Gleipnir 是我构建的环境,旨在让它们在我的工作站上发挥实际作用,同时又被限制在我控制并测试过的“围墙”内。目标陈述简单,但实现起来需要实打实的工作:每个代理之间互不干扰;我受到保护,免受任何代理异常行为的影响;我们三者仍然共享一个知识库(我的学习笔记),因为这正是核心目的所在。
How it works (the layers): Separate identities. Each agent runs as its own Linux user, never as me. Sandboxed launch. Agents start through systemd with sandboxing: read-only system directories, other users’ homes hidden, and only explicitly listed paths writable. Resource limits keep a runaway process from taking the machine down. Controlled network egress. Per-agent firewall rules (nftables) only let an agent talk to a local filtering proxy, and the proxy only allows that agent’s AI provider. Each agent’s launcher checks that this wall is in place and refuses to start if it isn’t.
工作原理(层级):独立的身份。每个代理都以其专属的 Linux 用户身份运行,绝非以我的身份。沙盒化启动。代理通过 systemd 在沙盒中启动:系统目录为只读,其他用户的主目录被隐藏,且仅有明确列出的路径可写。资源限制防止失控进程导致机器崩溃。受控的网络出口。基于代理的防火墙规则(nftables)仅允许代理与本地过滤代理通信,而该代理仅允许访问对应代理的 AI 提供商。每个代理的启动器都会检查这道“墙”是否就位,如果未就位则拒绝启动。
Policy as a second layer, not the only one. The agents’ own permission settings also deny the sensitive areas, but I treat those as a sign on the door. The kernel-level controls above are the door. A shared knowledge base with real permissions. My notes live on their own filesystem. Group ownership, setgid directories and default ACLs make the study area writable by everyone, while project records, paid course material and app configuration stay read-only or invisible to the agents.
策略作为第二层,而非唯一一层。代理自身的权限设置也会拒绝访问敏感区域,但我将其视为门上的告示牌,而上述内核级控制才是真正的门。带有实际权限的共享知识库。我的笔记存放在独立的文件系统上。通过组所有权、setgid 目录和默认 ACL,使得学习区域对所有人可写,而项目记录、付费课程材料和应用配置对代理保持只读或不可见。
Recovery built in. Hourly Git snapshots of the shared notes (so any deleted or mangled note can be restored), plus nightly encrypted backups with a restore I’ve actually tested. How I work: Staged changes, each reviewed. Every change is drafted, cross-checked by the other agent, and approved by me. Every privileged change is performed by me, by hand, one step at a time.
内置恢复功能。每小时对共享笔记进行 Git 快照(以便恢复任何被删除或损坏的笔记),外加每晚加密备份,且我已实际测试过恢复流程。我的工作方式:分阶段变更,逐一审核。每一项变更都经过起草、由另一个代理交叉检查,并由我批准。每一项特权变更都由我亲手一步步执行。
Testing by trying to break it. I run structured tests where each control is attacked on purpose: write where you shouldn’t, read what’s hidden, slip through a symlink or hardlink, reach the network directly. A control only counts once I’ve watched it refuse, with the exact error recorded. Honest records. A findings register, daily logs, and a policy changelog with the checksum of everything installed. Results that couldn’t be fully proven are labeled that way instead of being called a pass. Verified installs. Software comes from signed packages or is verified against published signatures and checksums before it runs.
通过尝试破坏来进行测试。我运行结构化测试,故意攻击每一个控制点:在不该写入的地方写入、读取隐藏内容、通过符号链接或硬链接绕过、直接访问网络。只有当我亲眼看到它拒绝访问并记录下确切错误时,该控制才算有效。诚实的记录。包括调查结果登记册、每日日志以及包含所有已安装软件校验和的策略变更日志。无法完全验证的结果会被标记出来,而不是直接判定为通过。已验证的安装。软件均来自签名包,或在运行前根据已发布的签名和校验和进行验证。
Three things I learned: Test the door, not the sign. A setting that says “deny” isn’t a control until you’ve watched the system actually refuse. Stacked layers hide each other. In one round of tests, two sandbox layers stopped everything before the deepest wall was ever reached. That’s good security, but it meant the tests proved the outer layers, not the inner one. I learned to record exactly which layer each test proves. Recovery steps don’t belong at the end of a runbook. I once followed a procedure top to bottom and ran its rollback section by accident. I recovered cleanly using a restore tool I’d built for exactly that, and since then recovery steps always live in a separate file.
我学到的三件事:测试门,而不是告示牌。一个显示“拒绝”的设置,除非你亲眼看到系统确实拒绝了,否则它算不上真正的控制。堆叠的层级会相互掩盖。在一轮测试中,两个沙盒层在触及最深层的墙之前就阻止了一切。这虽然是良好的安全实践,但意味着测试验证的是外层而非内层。我学会了准确记录每一项测试验证的是哪一层。恢复步骤不应放在操作手册的末尾。我曾有一次从头到尾执行流程,结果意外运行了回滚部分。我使用为此专门构建的恢复工具成功恢复,从那以后,恢复步骤总是存放在单独的文件中。
What’s next: The same discipline, applied to networking: a dedicated virtualization host with isolated lab segments (isolation proven with firewall drop counters, not just failed pings), then physical networking (managed switching, VLAN segmentation, a dedicated firewall, traffic capture), and finally an OT segment with PLC/HMI equipment and industrial protocols. That’s where my electrical and automation background meets security. The live configuration stays private by design because it contains operational details that don’t need to be public. The architecture, controls, testing methodology, and reasoning behind them are documented here. I’m happy to walk through the implementation in detail.
下一步:将同样的准则应用于网络:一个带有隔离实验室段的专用虚拟化主机(隔离性通过防火墙丢弃计数器验证,而非仅仅是 ping 失败),然后是物理网络(托管交换、VLAN 分段、专用防火墙、流量捕获),最后是包含 PLC/HMI 设备和工业协议的 OT 段。这正是我的电气和自动化背景与安全领域的结合点。实时配置在设计上保持私密,因为它包含无需公开的操作细节。架构、控制措施、测试方法及其背后的逻辑均记录于此。我很乐意详细讲解实现过程。