This repository has no description
0

Configure Feed

Select the types of activity you want to include in your feed.

container-bridge: switch to SLAAC and fix DNS/NAT issues

- Use Router Advertisements + SLAAC instead of pre-computed IPv6 addresses
- Add RDNSS to advertise DNS64 resolver to containers
- Add PREF64 option to advertise NAT64 prefix (RFC 8781)
- Fix MASQUERADE rule breaking localhost DNS (exclude 127.0.0.0/8)
- Add local-zone for NAT64 reverse DNS to prevent PTR lookup timeouts
- Remove nix-hashlib dependency (no longer needed with SLAAC)

+90 -27
+57 -2
flake.lock
··· 78 78 "type": "github" 79 79 } 80 80 }, 81 + "extra-container": { 82 + "inputs": { 83 + "flake-utils": "flake-utils", 84 + "nixpkgs": [ 85 + "nixpkgs" 86 + ] 87 + }, 88 + "locked": { 89 + "lastModified": 1766155727, 90 + "narHash": "sha256-XGp4HHH6D6ZKiO5RnMzqYJYnZB538EnEflvlTsOKpvo=", 91 + "owner": "erikarvstedt", 92 + "repo": "extra-container", 93 + "rev": "b450bdb24fca1076973c852d87bcb49b8eb5fd49", 94 + "type": "github" 95 + }, 96 + "original": { 97 + "owner": "erikarvstedt", 98 + "repo": "extra-container", 99 + "type": "github" 100 + } 101 + }, 81 102 "flake-parts": { 82 103 "inputs": { 83 104 "nixpkgs-lib": [ ··· 163 184 } 164 185 }, 165 186 "flake-utils": { 187 + "inputs": { 188 + "systems": "systems_2" 189 + }, 190 + "locked": { 191 + "lastModified": 1731533236, 192 + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", 193 + "owner": "numtide", 194 + "repo": "flake-utils", 195 + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", 196 + "type": "github" 197 + }, 198 + "original": { 199 + "owner": "numtide", 200 + "repo": "flake-utils", 201 + "type": "github" 202 + } 203 + }, 204 + "flake-utils_2": { 166 205 "locked": { 167 206 "lastModified": 1676283394, 168 207 "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", ··· 322 361 }, 323 362 "nix-writers": { 324 363 "inputs": { 325 - "flake-utils": "flake-utils", 364 + "flake-utils": "flake-utils_2", 326 365 "nixpkgs": "nixpkgs_2" 327 366 }, 328 367 "locked": { ··· 458 497 "nixpkgs": [ 459 498 "nixpkgs" 460 499 ], 461 - "systems": "systems_2" 500 + "systems": "systems_3" 462 501 }, 463 502 "locked": { 464 503 "lastModified": 1767906546, ··· 478 517 "inputs": { 479 518 "clan-core": "clan-core", 480 519 "disko": "disko", 520 + "extra-container": "extra-container", 481 521 "le_menu": "le_menu", 482 522 "nether": "nether", 483 523 "nix-darwin": "nix-darwin_2", ··· 573 613 } 574 614 }, 575 615 "systems_2": { 616 + "locked": { 617 + "lastModified": 1681028828, 618 + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", 619 + "owner": "nix-systems", 620 + "repo": "default", 621 + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", 622 + "type": "github" 623 + }, 624 + "original": { 625 + "owner": "nix-systems", 626 + "repo": "default", 627 + "type": "github" 628 + } 629 + }, 630 + "systems_3": { 576 631 "locked": { 577 632 "lastModified": 1681028828, 578 633 "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=",
-2
flake.nix
··· 59 59 60 60 extra-container.url = "github:erikarvstedt/extra-container"; 61 61 extra-container.inputs.nixpkgs.follows = "nixpkgs"; 62 - 63 - nix-hashlib.url = "git+https://git.clan.lol/clan/nix-hashlib"; 64 62 }; 65 63 66 64 outputs =
+24 -3
2configs/container-bridge.nix
··· 16 16 dns64-prefix = "64:ff9b::/96"; 17 17 # Always synthesize, even if real AAAA exists (needed when host has no IPv6) 18 18 dns64-synthall = "yes"; 19 + # Handle reverse DNS for NAT64 prefix locally (return NXDOMAIN immediately) 20 + # Without this, PTR lookups for 64:ff9b::* timeout waiting for upstream 21 + local-zone = ''"0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.b.9.f.f.4.6.0.0.ip6.arpa." static''; 19 22 }; 20 23 forward-zone = [ 21 24 { ··· 41 44 systemd.network.networks."10-ctr0" = { 42 45 matchConfig.Name = "ctr0"; 43 46 address = [ "fd00:c700::1/64" ]; 44 - networkConfig.ConfigureWithoutCarrier = true; 47 + networkConfig = { 48 + ConfigureWithoutCarrier = true; 49 + IPv6SendRA = true; # Enable Router Advertisements 50 + }; 51 + 52 + # Router Advertisement configuration 53 + ipv6SendRAConfig = { 54 + Managed = false; # No DHCPv6 for addresses (use SLAAC) 55 + OtherInformation = false; # No DHCPv6 for DNS (use RDNSS) 56 + RouterLifetimeSec = 1800; 57 + DNS = [ "fd00:c700::1" ]; # RDNSS: advertise DNS64 resolver 58 + }; 59 + ipv6Prefixes = [ 60 + { Prefix = "fd00:c700::/64"; } 61 + ]; 62 + # Advertise NAT64 prefix via PREF64 option (RFC 8781) 63 + ipv6PREF64Prefixes = [ 64 + { Prefix = "64:ff9b::/96"; } 65 + ]; 45 66 }; 46 67 47 68 # Exclude from NetworkManager ··· 107 128 ]; 108 129 109 130 # NAT66 - masquerade container IPv6 to reach public IPv6 (when host has IPv6) 110 - # NAT44 - masquerade NAT64 translated IPv4 packets 131 + # NAT44 - masquerade NAT64 translated IPv4 packets (exclude localhost!) 111 132 krebs.iptables.tables.nat.POSTROUTING.rules = [ 112 133 { v4 = false; v6 = true; predicate = "-s fd00:c700::/64 ! -d fd00:c700::/64"; target = "MASQUERADE"; } 113 - { v4 = true; v6 = false; predicate = ""; target = "MASQUERADE"; } # Masquerade all outbound IPv4 134 + { v4 = true; v6 = false; predicate = "! -d 127.0.0.0/8 ! -o lo"; target = "MASQUERADE"; } # Don't masquerade localhost 114 135 ]; 115 136 116 137 # Allow containers to reach host's DNS64 resolver (IPv6 only)
+9 -20
machines/virtulus/container.nix
··· 1 1 { self }: 2 2 let 3 - lib = self.inputs.nixpkgs.lib; 4 - hashlib = self.inputs.nix-hashlib.lib; 5 - 6 - # Generate IPv6 suffix from hostname (16 hex chars = 64 bits) 7 - ipv6SuffixFun = hashlib.makeHashFun { 8 - type = "hash"; 9 - dictionary = lib.stringToCharacters "0123456789abcdef"; 10 - length = 16; 11 - }; 12 - 13 - formatIPv6Suffix = hash: 14 - "${builtins.substring 0 4 hash}:${builtins.substring 4 4 hash}:${builtins.substring 8 4 hash}:${builtins.substring 12 4 hash}"; 15 - 16 3 machineName = "virtulus"; 17 - ipv6Suffix = formatIPv6Suffix (ipv6SuffixFun machineName); 18 - ipv6Address = "fd00:c700::${ipv6Suffix}"; 19 4 in 20 5 { 21 6 privateNetwork = true; ··· 31 16 clan.core.settings.directory = self; 32 17 clan.core.settings.machine.name = machineName; 33 18 34 - # Configure IPv6 inside the container (on eth0 interface) 19 + # Accept Router Advertisements for SLAAC (IPv6 auto-configuration) 20 + # Address will be generated from prefix + interface ID (stable privacy) 35 21 systemd.network.networks."10-container" = { 36 22 matchConfig.Name = "eth0"; 37 - address = [ "${ipv6Address}/64" ]; 38 - gateway = [ "fd00:c700::1" ]; 39 - networkConfig.ConfigureWithoutCarrier = true; 23 + networkConfig = { 24 + IPv6AcceptRA = true; 25 + # Use stable privacy addresses (RFC 7217) - deterministic per interface 26 + IPv6PrivacyExtensions = "prefer-public"; 27 + }; 40 28 }; 41 29 42 - # Use host's local DNS64 resolver 30 + # DNS will be configured via RDNSS from Router Advertisements 31 + # But keep a fallback in case RDNSS isn't received 43 32 networking.nameservers = [ "fd00:c700::1" ]; 44 33 }; 45 34 }