Fix trigger matching and add network policies

- Trigger only matches when nick is at start of message, not mid-text
  Fixes: "coder: say hi to worker" no longer triggers worker
- Network policies per agent: "full" (default), "local" (LAN only), "none" (IRC+Ollama only)
  Configured via template "network" field, applied as iptables rules per agent IP

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-04-07 13:45:05 +00:00
parent 6fc6e89917
commit 36af68da90
3 changed files with 91 additions and 3 deletions

View File

@@ -111,6 +111,74 @@ export function deleteTap(tapName: string) {
}
}
export type NetworkPolicy = "full" | "local" | "none";
export function applyNetworkPolicy(ip: string, policy: NetworkPolicy) {
if (policy === "full") return; // Default, no restrictions
// Block outbound internet — only allow LAN, bridge, Ollama, IRC
const allowedDests = [
CONFIG.bridge.subnet, // bridge network (other VMs, IRC, Ollama)
"192.168.0.0/16", // LAN
];
if (policy === "none") {
// Only allow bridge subnet (IRC + Ollama)
allowedDests.length = 1; // keep only bridge subnet
}
// Allow established connections back
sudo([
"iptables", "-I", "FORWARD",
"-s", ip,
"-m", "state", "--state", "ESTABLISHED,RELATED",
"-j", "ACCEPT",
]);
// Allow specific destinations
for (const dest of allowedDests) {
sudo([
"iptables", "-I", "FORWARD",
"-s", ip, "-d", dest,
"-j", "ACCEPT",
]);
}
// Drop everything else from this IP
sudo([
"iptables", "-A", "FORWARD",
"-s", ip,
"-j", "DROP",
]);
}
export function removeNetworkPolicy(ip: string) {
// Remove all FORWARD rules mentioning this IP
// Run in a loop since there may be multiple rules
for (let i = 0; i < 10; i++) {
try {
sudo([
"iptables", "-D", "FORWARD",
"-s", ip,
"-j", "DROP",
]);
} catch {
break;
}
}
for (let i = 0; i < 10; i++) {
try {
sudo([
"iptables", "-D", "FORWARD",
"-s", ip,
"-j", "ACCEPT",
]);
} catch {
break;
}
}
}
export function macFromOctet(octet: number): string {
return `AA:FC:00:00:00:${octet.toString(16).padStart(2, "0").toUpperCase()}`;
}