diff --git a/WORKAROUNDS.md b/WORKAROUNDS.md index 64221d89..5a7b83d0 100644 --- a/WORKAROUNDS.md +++ b/WORKAROUNDS.md @@ -33,18 +33,18 @@ A version or revision pinned for a reason that can go away. A setting that works around a bug or a hardware quirk. -| ID | What & where | Why | Removal condition | Added | Revisit | Status | -| ------ | --------------------------------------------------------------------------------------------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------- | ---------- | ------------------------------------------------------------------------------ | ------ | -| WA-008 | Relaxed NVMe APST (`nvme_core.default_ps_max_latency_us=100000`) — `hosts/idols-ai/hardware-configuration.nix` | the KINGBANK KP260 (DRAM-less QLC) froze on slow APST wake-ups | Drop the override once kernel/firmware fixes or replacement hardware make default APST reliable | 2026-10-03 | watch NVMe timeout/reset/AER in the journal | active | -| WA-009 | USB-SATA bridge mitigations (`usbcore.autosuspend=-1`, `usb-storage.delay_use=10`) — `hosts/12kingdoms-youko/default.nix` | flaky JMicron JMS567 resets with UDMA-CRC and I/O errors | Drop once the bridge/controller is replaced; the signal is smartctl CRC/media errors | 2026-09-21 | on hardware change or CRC errors | active | -| WA-010 | Insta360 Link USB reset on S3 resume — `hosts/idols-ai/default.nix` | the camera stays enumerated with a stalled UVC endpoint after resume | Drop after the Insta360 firmware or the kernel `uvcvideo` fixes it | 2026-08-01 | on kernel or firmware change | active | -| WA-011 | Kernel module blacklist (`esp4`, `esp6`, `rxrpc`) — `hardening/kernel-hardening.nix` | attack surface for the Dirty Frag LPE (CVE-2026-43284 / CVE-2026-43500) | Kept as defence in depth; drop only if something needs those modules | 2026-10-03 | rarely | active | -| WA-017 | keyd right-hand modifier passthrough — `modules/nixos/desktop/peripherals.nix` | keyd folds right Ctrl/Shift/Meta into their left keys | Drop once keyd or fcitx5 keeps right-hand modifiers distinct | 2026-10-05 | on keyd bump | active | -| WA-018 | user-owned `~/.ssh/config` + disabled systemd ssh-proxy include — `home/base/tui/ssh.nix`, `modules/nixos/base/ssh.nix` | bwrap exposes root-owned store files as `nobody` | Drop once sandboxes preserve store ownership | 2026-10-06 | when sandbox layout changes | active | -| WA-019 | programs.steam.extraCompatPackages = [ pkgs.dwproton-bin pkgs.proton-ge-bin ] — modules/nixos/desktop/gaming.nix | ACE games fail on GE/mainline Proton, work with DW-Proton | Drop once mainline or GE-Proton runs these games (GE-Proton#433) | 2026-10-07 | on Proton/GE bump | active | -| WA-024 | Wi-Fi power saving disabled (`networking.networkmanager.wifi.powersave = false`) — `hosts/12kingdoms-shoukei/apple-silicon.nix` | On this BCM4378/brcmfmac laptop, powersave is a common source of intermittent ASSOC-REJECT / authentication-timeout failures; NetworkManager then mistakes the failure for a bad key, re-prompts, and the client (Noctalia, nmtui, nmcli) saves the answer as a duplicate ` 1` profile | Drop once the kernel carries the brcmfmac `port_authorized` fix (WA-025) and no association failures remain | 2026-10-07 | watch `journalctl -u wpa_supplicant` for ASSOC-REJECT / authentication timeout | active | -| WA-026 | guest deploys run `installOnHost` then `systemctl restart microvm@`, not `just microvm-deploy` — `lib/genMicrovmGuestModule.nix` | the sshSwitch step runs `nix-store --load-db` against the guest's read-only virtiofs `/nix/store` and dies on `cannot remount "/nix/store" writable` (nix 2.35) | Drop the manual path once microvm.nix or nix handles a read-only store switch | 2026-10-09 | on microvm.nix or nix bump | active | -| WA-028 | `github.com` keeps `AddressFamily = "inet"` — `home/base/tui/ssh.nix` | measured on 1.19.31 + `tun.stack: gvisor`: TCP to a fake IPv6 is proxied and SSH even authenticates (`[fdfe:dcba:9876::18]:443`), but the session then never closes, while the same run over the fake IPv4 ends cleanly. HTTPS over a fake IPv6 is fine, so only ssh needs the pin | Drop the line once `git ls-remote` with `AddressFamily=any` returns a sha instead of hanging | 2026-10-09 | on a mihomo bump, or if `tun.stack` changes | active | +| ID | What & where | Why | Removal condition | Added | Revisit | Status | +| ------ | --------------------------------------------------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ | ---------- | --------------------------------------------------------------------------------------------------- | ------ | +| WA-008 | Relaxed NVMe APST (`nvme_core.default_ps_max_latency_us=100000`) — `hosts/idols-ai/hardware-configuration.nix` | the KINGBANK KP260 (DRAM-less QLC) froze on slow APST wake-ups | Drop the override once kernel/firmware fixes or replacement hardware make default APST reliable | 2026-10-03 | watch NVMe timeout/reset/AER in the journal | active | +| WA-009 | USB-SATA bridge mitigations (`usbcore.autosuspend=-1`, `usb-storage.delay_use=10`) — `hosts/12kingdoms-youko/default.nix` | flaky JMicron JMS567 resets with UDMA-CRC and I/O errors | Drop once the bridge/controller is replaced; the signal is smartctl CRC/media errors | 2026-09-21 | on hardware change or CRC errors | active | +| WA-010 | Insta360 Link USB reset on S3 resume — `hosts/idols-ai/default.nix` | the camera stays enumerated with a stalled UVC endpoint after resume | Drop after the Insta360 firmware or the kernel `uvcvideo` fixes it | 2026-08-01 | on kernel or firmware change | active | +| WA-011 | Kernel module blacklist (`esp4`, `esp6`, `rxrpc`) — `hardening/kernel-hardening.nix` | attack surface for the Dirty Frag LPE (CVE-2026-43284 / CVE-2026-43500) | Kept as defence in depth; drop only if something needs those modules | 2026-10-03 | rarely | active | +| WA-017 | keyd right-hand modifier passthrough — `modules/nixos/desktop/peripherals.nix` | keyd folds right Ctrl/Shift/Meta into their left keys | Drop once keyd or fcitx5 keeps right-hand modifiers distinct | 2026-10-05 | on keyd bump | active | +| WA-018 | user-owned `~/.ssh/config` + disabled systemd ssh-proxy include — `home/base/tui/ssh.nix`, `modules/nixos/base/ssh.nix` | bwrap exposes root-owned store files as `nobody` | Drop once sandboxes preserve store ownership | 2026-10-06 | when sandbox layout changes | active | +| WA-019 | programs.steam.extraCompatPackages = [ pkgs.dwproton-bin pkgs.proton-ge-bin ] — modules/nixos/desktop/gaming.nix | ACE games fail on GE/mainline Proton, work with DW-Proton | Drop once mainline or GE-Proton runs these games (GE-Proton#433) | 2026-10-07 | on Proton/GE bump | active | +| WA-024 | Wi-Fi power saving disabled (`networking.networkmanager.wifi.powersave = false`) — `hosts/12kingdoms-shoukei/apple-silicon.nix` | On this BCM4378/brcmfmac laptop, powersave is a common source of intermittent ASSOC-REJECT / authentication-timeout failures; NetworkManager then mistakes the failure for a bad key, re-prompts, and the client (Noctalia, nmtui, nmcli) saves the answer as a duplicate ` 1` profile | Drop once the kernel carries the brcmfmac `port_authorized` fix (WA-025) and no association failures remain | 2026-10-07 | watch `journalctl -u wpa_supplicant` for ASSOC-REJECT / authentication timeout | active | +| WA-026 | guest deploys run `installOnHost` then `systemctl restart microvm@`, not `just microvm-deploy` — `lib/genMicrovmGuestModule.nix` | the sshSwitch step runs `nix-store --load-db` against the guest's read-only virtiofs `/nix/store` and dies on `cannot remount "/nix/store" writable` (nix 2.35) | Drop the manual path once microvm.nix or nix handles a read-only store switch | 2026-10-09 | on microvm.nix or nix bump | active | +| WA-029 | mihomo `fake-ip-range6` is `2001:2::/64`, not the shipped ULA default — `modules/nixos/desktop/networking/mihomo/generate.nu` | the default `fdfe:dcba:9876::/64` sits in `fc00::/7`, which Local Network Access calls local, so a public page loaded over the v4 fake pool and pulling a dual-stack subresource prompts for local-network access (Chrome 154, Firefox). The same range also stalled ssh: a session to a fake AAAA authenticated and then never closed, on both `gvisor` and `mips`. `2001:2::/48` is RFC 5180 benchmarking -- the v6 twin of the `198.18.0.0/15` v4 default, absent from that table -- and both symptoms went with the move | Go back to the upstream default once mihomo ships a pool outside the LNA non-public table; the ULA default brings the ssh stall back | 2026-10-09 | on a browser or mihomo bump -- that table already grew to cover `2001:db8::/32` and `198.18.0.0/15` | active | If WA-008 freezes recur, the fallback is to restore `nvme_core.default_ps_max_latency_us=0 nvme_core.io_timeout=4294967295 pcie_aspm=off`; this is a diff --git a/home/base/tui/ssh.nix b/home/base/tui/ssh.nix index 0392d404..d50cc56e 100644 --- a/home/base/tui/ssh.nix +++ b/home/base/tui/ssh.nix @@ -27,8 +27,6 @@ settings = { "github.com" = { - # WA-028: pinned to IPv4 until the mihomo v6 fake-ip pool is proven here - AddressFamily = "inet"; HostName = "ssh.github.com"; Port = 443; User = "git"; diff --git a/modules/nixos/desktop/networking/mihomo/README.md b/modules/nixos/desktop/networking/mihomo/README.md index f5ca5375..e01b6c70 100644 --- a/modules/nixos/desktop/networking/mihomo/README.md +++ b/modules/nixos/desktop/networking/mihomo/README.md @@ -53,6 +53,14 @@ targets instead of writing a config the core rejects. back. mihomo has no IPv6 reachability probe (mihomo#2233), so the config has to match the line. SSH over a fake AAAA is the local exception: it connects, authenticates, then never closes -- WA-028's IPv4 pin covers it. + The pool is `2001:2::/64`, not the shipped `fdfe:dcba:9876::/64`: that is ULA (`fc00::/7`), which + Local Network Access calls **local**, so a public page pulling a dual-stack subresource prompts. + `2001:2::/48` is RFC 5180 benchmarking, the v6 twin of the `198.18.0.0/15` v4 default. Never grant + that prompt broadly -- it also covers `192.168.5.0/24`, `fd05:5::/64` and Tailscale. Moving the + pool leaves mihomo's own TUN addresses (`198.18.0.1`, `fdfe:dcba:9876::1`) alone; no client is + ever handed those as an answer. +- `tun.stack` stays at upstream's default `mips`; nftables rules out `system` and `mixed`. The + gateway runs `mixed`. - `private_domains`: each entry becomes a DIRECT rule + a `fake-ip-filter` entry. - WeChat resolves for itself, but its queries still cross the TUN, so `dns-hijack: any:53` catches them and the fake-ip table hands the name back to the rules: `mmbiz.qpic.cn` measured DIRECT. @@ -64,8 +72,9 @@ targets instead of writing a config the core rejects. round trip -- RFC1918, RFC 6598's `100.64.0.0/10` (where Tailscale addresses come from), link-local, multicast, reserved and documentation prefixes, the cluster ULA `fd05:5::/64` and Tailscale's `fd7a:115c:a1e0::/48`. Never exclude a range that holds a fake-ip pool: that is - `198.18.0.0/16` and `fdfe:dcba:9876::/64`, which is why the list spells the two ULAs out instead - of taking `fc00::/7`; `tun_exclude_address: []` puts everything back in TUN. + `198.18.0.0/16` and `2001:2::/64`. The two ULAs are spelled out instead of taking all of + `fc00::/7`, which would also exempt any other ULA a client dials; `tun_exclude_address: []` puts + everything back in TUN. - Steam's download caches follow the public IP Steam sees on the login (CM) connection, so a proxied Steam downloads from Tokyo/Singapore/HK/Los Angeles. `policy.yaml` pins the CM hosts, `steamcontent.com` and `IP-ASN,32590` DIRECT and keeps `steamcommunity.com` on the proxy -- Steam diff --git a/modules/nixos/desktop/networking/mihomo/gateway-config.nu b/modules/nixos/desktop/networking/mihomo/gateway-config.nu index 245b2cd0..02a6a9b7 100644 --- a/modules/nixos/desktop/networking/mihomo/gateway-config.nu +++ b/modules/nixos/desktop/networking/mihomo/gateway-config.nu @@ -37,7 +37,8 @@ def main [ | insert external-ui "ui" | insert external-ui-url $UI_URL | update secret "GATEWAY-SECRET-PLACEHOLDER" - | update tun.stack "mixed" + # the base leaves the stack at upstream's default; this box has run the kernel stack for months + | upsert tun.stack "mixed" | update tun.strict-route false # the desktop's resolver is loopback; a gateway serves the LAN instead | update dns.listen ":1053") diff --git a/modules/nixos/desktop/networking/mihomo/generate.nu b/modules/nixos/desktop/networking/mihomo/generate.nu index 80b553c7..ec81a9c3 100644 --- a/modules/nixos/desktop/networking/mihomo/generate.nu +++ b/modules/nixos/desktop/networking/mihomo/generate.nu @@ -517,7 +517,6 @@ def main [ tun: ( clean ({ enable: true - stack: "gvisor" "auto-route": true "strict-route": ($spec | get -o tun_strict_route | default true) "auto-detect-interface": true @@ -536,9 +535,9 @@ def main [ ipv6: true "enhanced-mode": "fake-ip" "fake-ip-range": "198.18.0.1/16" - # AAAA needs a pool of its own (fake-ip-range6, mihomo >= 1.19.16); one - # prefix per family, no comma list. Keep it out of route-exclude-address. - "fake-ip-range6": "fdfe:dcba:9876::1/64" + # AAAA needs its own pool (fake-ip-range6, mihomo >= 1.19.16) and must stay out of + # route-exclude-address. Why this pool and not the ULA default: README.md. + "fake-ip-range6": "2001:2::1/64" "fake-ip-filter-mode": "blacklist" "prefer-h3": false "respect-rules": false