mirror of
https://github.com/ryan4yin/nix-config.git
synced 2026-11-13 12:13:46 +01:00
fix(mihomo): use fake-IP for gateway IPv6 (#442)
This commit is contained in:
1 parent
c888dd65e9
commit
bb89987640
5 files changed
+26
-30
No files matched your search
@@ -74,24 +74,6 @@ in
|
||||
useDHCP = false;
|
||||
};
|
||||
|
||||
# suzi's fake-ip DNS hands out AAAA records whose IPv6 path does not work: a
|
||||
# `curl -6` to a registry returns 502 or times out, while `curl -4` answers in
|
||||
# 0.1 s. Clients that try the AAAA first (podman, git, pip) then hang on the
|
||||
# handshake, which is why docker.io, github.com and pypi.org looked blocked
|
||||
# here. These are RFC 6724's default precedences with the IPv4-mapped row
|
||||
# raised, so IPv4 sorts first; glibc drops its whole built-in table as soon as
|
||||
# the file lists any entry, hence spelling all of it out.
|
||||
#
|
||||
# The real fix belongs on that gateway: stop answering AAAA for proxied names
|
||||
# (`dns.ipv6: false` in mihomo; the module README says the same).
|
||||
networking.getaddrinfo.precedence = {
|
||||
"::1/128" = 50;
|
||||
"::/0" = 40;
|
||||
"2002::/16" = 30;
|
||||
"::/96" = 20;
|
||||
"::ffff:0:0/96" = 100;
|
||||
};
|
||||
|
||||
# A `boot.kernel.sysctl` that disabled IPv6 was removed on 2026-10-14: networkd
|
||||
# re-enables it on the wired link for the `DHCP = "ipv6"`/`IPv6AcceptRA` settings
|
||||
# below, so it never applied and the AAAA attempt already fails at once (WA-034).
|
||||
|
||||
@@ -62,12 +62,19 @@ Verge UI. Verge logs `Unregistered Clash configuration key "ipv6"` for the pin -
|
||||
still reaches the core.
|
||||
|
||||
The gateway (`suzi`, not a host in this flake) runs the same config with a fixed set of deltas --
|
||||
`gateway-config.nu` renders it from the same `sources.yaml` and `policy.yaml`. Its output carries
|
||||
the subscriptions and the private domains, so never commit it; the secret is filled in on the box,
|
||||
not here. Its binary is a static release build under `/usr/local/bin`, not a package: update it by
|
||||
hand, validate the live config with the new core (`mihomo -t -d /etc/mihomo -f <candidate>`) before
|
||||
swapping, and keep the previous binary. The release ships no checksums, so TLS plus `-v` is the
|
||||
whole verification.
|
||||
`gateway-config.nu` renders it from the same `sources.yaml` and `policy.yaml`. The gateway uses
|
||||
nftables TProxy, disables the desktop TUN auto-route, and uses `fake-ip` DNS with `dns.ipv6: true`:
|
||||
LAN clients receive stable fake A/AAAA mappings so mihomo retains the domain for routing and
|
||||
sniffing. Its output carries the subscriptions and the private domains, so never commit it; the
|
||||
secret is filled in on the box, not here. Its binary is a static release build under `/usr/local/bin`,
|
||||
not a package: update it by hand, validate the live config with the new core (`mihomo -t -d /etc/mihomo
|
||||
-f <candidate>`) before swapping, and keep the previous binary. The release ships no checksums, so TLS
|
||||
plus `-v` is the whole verification.
|
||||
|
||||
Gateway mode contract: the tested working combinations are nftables TProxy with both `tun.enable`
|
||||
and `tun.auto-route` disabled, using either `redir-host` or `fake-ip` DNS. This generator selects
|
||||
`fake-ip` because it preserves more domain information. Do not combine LAN TProxy with the desktop
|
||||
TUN auto-route: in this gateway topology it can recapture fake IPv6 dials and cause timeouts.
|
||||
|
||||
## Why generate
|
||||
|
||||
|
||||
@@ -36,9 +36,14 @@ def main [
|
||||
| insert external-ui "ui"
|
||||
| insert external-ui-url $UI_URL
|
||||
| update secret "GATEWAY-SECRET-PLACEHOLDER"
|
||||
# the base leaves the stack at upstream's default; this box has run the kernel stack for months
|
||||
| upsert tun.stack "mixed"
|
||||
# The gateway uses nftables TProxy for LAN traffic; its desktop-style TUN
|
||||
# auto-route would capture the gateway's own DIRECT IPv6 dials again.
|
||||
| upsert tun.enable false
|
||||
| upsert tun.auto-route false
|
||||
| update tun.strict-route false
|
||||
# TProxy handles fake IPv4 and IPv6 destinations when the desktop TUN
|
||||
# auto-route is disabled; fake-IP preserves the domain mapping for LAN flows.
|
||||
| upsert dns.enhanced-mode "fake-ip"
|
||||
# the desktop's resolver is loopback; a gateway serves the LAN instead
|
||||
| update dns.listen ":1053"
|
||||
# LAN clients that use DoH dial the IPs they resolved; sniff so the node dials a name
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
gpuRecoveryEnabled = true;
|
||||
aspmDisabled = true;
|
||||
cStatesCapped = true;
|
||||
prefersIpv4 = true;
|
||||
nativeIpv6Preference = true;
|
||||
sourceCheckoutsPersistent = true;
|
||||
rootlessPodmanEnabled = true;
|
||||
stableKernel = true;
|
||||
|
||||
@@ -25,9 +25,11 @@ in
|
||||
aspmDisabled = builtins.elem "pcie_aspm=off" cfg.boot.kernelParams;
|
||||
cStatesCapped = builtins.elem "processor.max_cstate=2" cfg.boot.kernelParams;
|
||||
|
||||
# suzi's fake-ip DNS returns AAAA records with no working IPv6 path, so the
|
||||
# generated gai.conf has to sort IPv4 first (see ./default.nix).
|
||||
prefersIpv4 = lib.hasInfix "precedence ::ffff:0:0/96 100" cfg.environment.etc."gai.conf".text;
|
||||
# Aqua uses native IPv6; the gateway returns real AAAA records instead of
|
||||
# requiring a host-local IPv4 precedence workaround.
|
||||
nativeIpv6Preference =
|
||||
!(cfg.environment.etc ? "gai.conf")
|
||||
|| !lib.hasInfix "precedence ::ffff:0:0/96 100" cfg.environment.etc."gai.conf".text;
|
||||
|
||||
# The Strata checkout lives under ~/src, which has to survive the tmpfs root
|
||||
# like ~/codes does.
|
||||
|
||||
Reference in new issue
Block a user