Merge pull request #34492 from rnhmjoj/privacy

nixos/networking-interfaces: add preferTempAddress option

authored by Joachim F and committed by GitHub 7bf049a5 87f6e05d

+79 -4
+2 -1
nixos/modules/system/boot/networkd.nix
··· 94 94 checkNetwork = checkUnitConfig "Network" [ 95 95 (assertOnlyFields [ 96 96 "Description" "DHCP" "DHCPServer" "IPForward" "IPMasquerade" "IPv4LL" "IPv4LLRoute" 97 - "LLMNR" "MulticastDNS" "Domains" "Bridge" "Bond" 97 + "LLMNR" "MulticastDNS" "Domains" "Bridge" "Bond" "IPv6PrivacyExtensions" 98 98 ]) 99 99 (assertValueOneOf "DHCP" ["both" "none" "v4" "v6"]) 100 100 (assertValueOneOf "DHCPServer" boolValues) ··· 104 104 (assertValueOneOf "IPv4LLRoute" boolValues) 105 105 (assertValueOneOf "LLMNR" boolValues) 106 106 (assertValueOneOf "MulticastDNS" boolValues) 107 + (assertValueOneOf "IPv6PrivacyExtensions" ["yes" "no" "prefer-public" "kernel"]) 107 108 ]; 108 109 109 110 checkAddress = checkUnitConfig "Address" [
+1
nixos/modules/tasks/network-interfaces-systemd.nix
··· 91 91 (if i.useDHCP != null then i.useDHCP else cfg.useDHCP && interfaceIps i == [ ])); 92 92 address = flip map (interfaceIps i) 93 93 (ip: "${ip.address}/${toString ip.prefixLength}"); 94 + networkConfig.IPv6PrivacyExtensions = "kernel"; 94 95 } ]; 95 96 }))) 96 97 (mkMerge (flip mapAttrsToList cfg.bridges (name: bridge: {
+19 -3
nixos/modules/tasks/network-interfaces.nix
··· 155 155 description = "Name of the interface."; 156 156 }; 157 157 158 + preferTempAddress = mkOption { 159 + type = types.bool; 160 + default = cfg.enableIPv6; 161 + defaultText = literalExample "config.networking.enableIpv6"; 162 + description = '' 163 + When using SLAAC prefer a temporary (IPv6) address over the EUI-64 164 + address for originating connections. This is used to reduce tracking. 165 + ''; 166 + }; 167 + 158 168 useDHCP = mkOption { 159 169 type = types.nullOr types.bool; 160 170 default = null; ··· 941 951 message = '' 942 952 The networking.interfaces."${i.name}" must not have any defined ips when it is a slave. 943 953 ''; 954 + })) ++ (flip map interfaces (i: { 955 + assertion = i.preferTempAddress -> cfg.enableIPv6; 956 + message = '' 957 + Temporary addresses are only needed when IPv6 is enabled. 958 + ''; 944 959 })) ++ [ 945 960 { 946 961 assertion = cfg.hostId == null || (stringLength cfg.hostId == 8 && isHexString cfg.hostId); ··· 963 978 "net.ipv6.conf.all.disable_ipv6" = mkDefault (!cfg.enableIPv6); 964 979 "net.ipv6.conf.default.disable_ipv6" = mkDefault (!cfg.enableIPv6); 965 980 "net.ipv6.conf.all.forwarding" = mkDefault (any (i: i.proxyARP) interfaces); 966 - } // listToAttrs (concatLists (flip map (filter (i: i.proxyARP) interfaces) 967 - (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true)) 968 - )); 981 + } // listToAttrs (flip concatMap (filter (i: i.proxyARP) interfaces) 982 + (i: flip map [ "4" "6" ] (v: nameValuePair "net.ipv${v}.conf.${i.name}.proxy_arp" true))) 983 + // listToAttrs (flip map (filter (i: i.preferTempAddress) interfaces) 984 + (i: nameValuePair "net.ipv6.conf.${i.name}.use_tempaddr" 2)); 969 985 970 986 # Capabilities won't work unless we have at-least a 4.3 Linux 971 987 # kernel because we need the ambient capability
+57
nixos/tests/networking.nix
··· 476 476 ); 477 477 ''; 478 478 }; 479 + privacy = { 480 + name = "Privacy"; 481 + nodes.router = { config, pkgs, ... }: { 482 + virtualisation.vlans = [ 1 ]; 483 + boot.kernel.sysctl."net.ipv6.conf.all.forwarding" = true; 484 + networking = { 485 + useNetworkd = networkd; 486 + interfaces.eth1 = { 487 + ipv6Address = "fd00:1234:5678:1::1"; 488 + ipv6PrefixLength = 64; 489 + }; 490 + }; 491 + services.radvd = { 492 + enable = true; 493 + config = '' 494 + interface eth1 { 495 + AdvSendAdvert on; 496 + AdvManagedFlag on; 497 + AdvOtherConfigFlag on; 498 + 499 + prefix fd00:1234:5678:1::/64 { 500 + AdvAutonomous on; 501 + AdvOnLink on; 502 + }; 503 + }; 504 + ''; 505 + }; 506 + }; 507 + nodes.client = { config, pkgs, ... }: with pkgs.lib; { 508 + virtualisation.vlans = [ 1 ]; 509 + networking = { 510 + useNetworkd = networkd; 511 + useDHCP = true; 512 + interfaces.eth1 = { 513 + preferTempAddress = true; 514 + ip4 = mkOverride 0 [ ]; 515 + ip6 = mkOverride 0 [ ]; 516 + }; 517 + }; 518 + }; 519 + testScript = { nodes, ... }: 520 + '' 521 + startAll; 522 + 523 + $client->waitForUnit("network.target"); 524 + $router->waitForUnit("network-online.target"); 525 + 526 + # Wait until we have an ip address 527 + $client->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'"); 528 + 529 + # Test vlan 1 530 + $client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1"); 531 + 532 + # Test address used is temporary 533 + $client->succeed("! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'"); 534 + ''; 535 + }; 479 536 }; 480 537 481 538 in mapAttrs (const (attrs: makeTest (attrs // {