fix(desktop): tie ai's link DNS takeover to mihomo's lifecycle (#380)

* fix(desktop): tie ai's link DNS takeover to mihomo's lifecycle

sing-tun normally points systemd-resolved at the TUN DNS by running
resolvectl (dns/domain/default-route). Under nixpkgs' hardened
DynamicUser mihomo unit that hand-off fails silently: the unit's
RestrictAddressFamilies blocks resolvectl's D-Bus socket and resolve1
requires privileged authorization, so resolved keeps querying the
physical-link DNS, fake-ip is bypassed, and domain rules degrade to
MATCH.

Do the hand-off as '+' ExecStartPost/ExecStopPost hooks instead: '+'
commands run outside the sandbox (systemd.exec: address-family
restrictions do not apply to them) and ExecStopPost reverts even on
crashes, so a dead mihomo leaves DNS usable.

Signed-off-by: Ryan Yin <xiaoyin_c@qq.com>

* docs(mihomo): record sing-tun's resolvectl hand-off as the leak cause

Signed-off-by: Ryan Yin <xiaoyin_c@qq.com>

* refactor(desktop): keep mihomo only on ai and shoukei

ruby/kana never ran the core (service inactive live), and their
resolved + TUN combo would reintroduce the resolver leak once enabled.
Drop the enable and the explicit module import from computer-use; the
eval test now pins mihomo=false for both guests.

---------

Signed-off-by: Ryan Yin <xiaoyin_c@qq.com>
This commit is contained in:
ryan4yin | 二花 authored and GitHub committed 2026-10-05 00:07:32 +08:00
1 parent bbd230e6fd
commit 8f0961d9c2
7 files changed
+42 -22

No files matched your search

+12 -11
View File
@@ -24,17 +24,18 @@ bump, and the commands that destroy rollback points are in the `nix-config-updat
## 1. Localize by layer
| Layer | Symptom | Look with |
| ------------- | ---------------------------------------------- | --------------------------------------------------------------------------------------------------- |
| eval | `just test` prints `false`, an eval error | `just eval-host <host>` (already passes `--show-trace`) |
| build | build error, hash mismatch, "marked as broken" | `just build-host <host>`, then `nix log <drv>` |
| activation | the deploy fails after building | the deploy output; `journalctl -u home-manager-$USER -b` for Home Manager |
| runtime | a unit is failed or restarting | `just list-failed`, `systemctl status <unit>`, `journalctl -u <unit> -b` |
| boot | errors at boot, wrong kernel | `journalctl -b -p err`; `just history` for what is booted |
| session | desktop or app misbehaves | `journalctl --user -b -p err`; the `nix-config-desktop` skill |
| remote host | anything on a Colmena host | `ssh root@<host> journalctl -b -p err`, same commands over SSH |
| MicroVM guest | guest down or unreachable | on the VM host: `systemctl status microvm@<guest>` and `microvm-tap-interfaces@<guest>`; then `br0` |
| secrets | missing or unreadable `/etc/agenix/*` | the `nix-config-secrets` skill |
| Layer | Symptom | Look with |
| ------------- | ---------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------- |
| eval | `just test` prints `false`, an eval error | `just eval-host <host>` (already passes `--show-trace`) |
| build | build error, hash mismatch, "marked as broken" | `just build-host <host>`, then `nix log <drv>` |
| activation | the deploy fails after building | the deploy output; `journalctl -u home-manager-$USER -b` for Home Manager |
| runtime | a unit is failed or restarting | `just list-failed`, `systemctl status <unit>`, `journalctl -u <unit> -b` |
| proxy/DNS | proxied sites time out, node and rules look ok | `dig +short <site>` must return a fake-ip (`198.18.x.x`); a real IP means the system resolver bypasses `dns-hijack` — mihomo README Gotchas |
| boot | errors at boot, wrong kernel | `journalctl -b -p err`; `just history` for what is booted |
| session | desktop or app misbehaves | `journalctl --user -b -p err`; the `nix-config-desktop` skill |
| remote host | anything on a Colmena host | `ssh root@<host> journalctl -b -p err`, same commands over SSH |
| MicroVM guest | guest down or unreachable | on the VM host: `systemctl status microvm@<guest>` and `microvm-tap-interfaces@<guest>`; then `br0` |
| secrets | missing or unreadable `/etc/agenix/*` | the `nix-config-secrets` skill |
## 2. Read the evaluated value
+4 -1
View File
@@ -59,7 +59,10 @@ assume the physical-host deployment is done through Colmena.
unused `args`: haumea passes them lazily and they are still required.
5. `vars/networking.nix` - `hostsAddr.<name> = { iface; ipv4; }` for a LAN host. That entry drives
the static address, the SSH `Host` alias used for remote builds, and `known_hosts`, so a wrong
`iface` takes the host offline at activation. Skip it for a DHCP or mobile host.
`iface` takes the host offline at activation. Skip it for a DHCP or mobile host. If the host
enables `modules.networking.mihomo` and runs systemd-resolved, it needs a DNS takeover tied to
mihomo's lifecycle (`resolvectl dns`/`revert` in `ExecStartPost`/`ExecStopPost`, see
`hosts/idols-ai/default.nix`); a static link DNS would kill DNS when mihomo dies.
6. `hosts/README.md` - add the host to the inventory.
Pin service user and group ids (`service-user-ids.nix`, as on `shoryu`) before the host has state on