feat(headscale): add ACL policy, isolate mx, make mx an exit node

Introduces a headscale ACL policy (file-mode) plus matching client config:

- New systems/x86_64-linux/attic/headscale-policy.hujson:
  * tag:llm restricts a node to talking only to halo:8000
  * all other harald@ nodes have full mesh access to each other
  * harald@ nodes can route internet traffic via approved exit nodes
  * autoApprovers.exitNode = [tag:llm] auto-approves the exit route
    advertised by any tag:llm node (currently mx)

- attic headscale.nix: wire policy.mode = "file" / policy.path to
  the .hujson above.

- mx default.nix: enable useRoutingFeatures = "server" (needed for IP
  forwarding) and add extraSetFlags = ["--advertise-exit-node"] so the
  flag is reapplied on every activation, not just initial login.

Operational steps after deploy:
  headscale nodes tag -i 10 -t tag:llm
This commit is contained in:
Harald Hoyer 2026-05-13 09:06:40 +02:00
parent 87bdaf15da
commit 67b7c3a9fd
3 changed files with 37 additions and 1 deletions

View file

@ -0,0 +1,28 @@
{
"tagOwners": {
"tag:llm": ["harald@"],
},
"hosts": {
"halo": "100.64.0.3",
},
"autoApprovers": {
"exitNode": ["tag:llm"],
},
"acls": [
{
"action": "accept",
"src": ["tag:llm"],
"dst": ["halo:8000"],
},
{
"action": "accept",
"src": ["harald@"],
"dst": ["harald@:*"],
},
{
"action": "accept",
"src": ["harald@"],
"dst": ["autogroup:internet:*"],
},
],
}

View file

@ -25,6 +25,10 @@ in
client_secret_path = "/var/lib/headscale/client_secret"; client_secret_path = "/var/lib/headscale/client_secret";
issuer = "https://nc.hoyer.xyz"; issuer = "https://nc.hoyer.xyz";
}; };
policy = {
mode = "file";
path = toString ./headscale-policy.hujson;
};
}; };
}; };

View file

@ -26,7 +26,11 @@
./users.nix ./users.nix
]; ];
services.tailscale.enable = true; services.tailscale = {
enable = true;
useRoutingFeatures = "server";
extraSetFlags = [ "--advertise-exit-node" ];
};
metacfg = { metacfg = {
services.nginxBase.enable = true; services.nginxBase.enable = true;