diff --git a/nixos/doc/manual/release-notes/rl-1909.xml b/nixos/doc/manual/release-notes/rl-1909.xml
index e8e8ed8eae2d..30570a279eca 100644
--- a/nixos/doc/manual/release-notes/rl-1909.xml
+++ b/nixos/doc/manual/release-notes/rl-1909.xml
@@ -122,6 +122,19 @@
+
+
+ IPv6 Privacy Extensions are now enabled by default for undeclared
+ interfaces. The previous behaviour was quite misleading — even though
+ the default value for
+ was
+ true, undeclared interfaces would not prefer temporary
+ addresses. Now, interfaces not mentioned in the config will prefer
+ temporary addresses. EUI64 addresses can still be set as preferred by
+ explicitly setting the option to false for the
+ interface in question.
+
+
Since Bittorrent Sync was superseded by Resilio Sync in 2016, the
diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix
index f9b0eb330bf8..1a13e3869474 100644
--- a/nixos/modules/tasks/network-interfaces.nix
+++ b/nixos/modules/tasks/network-interfaces.nix
@@ -1087,7 +1087,24 @@ in
virtualisation.vswitch = mkIf (cfg.vswitches != { }) { enable = true; };
- services.udev.packages = mkIf (cfg.wlanInterfaces != {}) [
+ services.udev.packages = [
+ (pkgs.writeTextFile rec {
+ name = "ipv6-privacy-extensions.rules";
+ destination = "/etc/udev/rules.d/98-${name}";
+ text = ''
+ # enable and prefer IPv6 privacy addresses by default
+ ACTION=="add", SUBSYSTEM=="net", RUN+="${pkgs.procps}/bin/sysctl net.ipv6.conf.%k.use_tempaddr=2"
+ '';
+ })
+ (pkgs.writeTextFile rec {
+ name = "ipv6-privacy-extensions.rules";
+ destination = "/etc/udev/rules.d/99-${name}";
+ text = concatMapStrings (i: ''
+ # enable IPv6 privacy addresses but prefer EUI-64 addresses for ${i.name}
+ ACTION=="add", SUBSYSTEM=="net", RUN+="${pkgs.procps}/bin/sysctl net.ipv6.conf.${i.name}.use_tempaddr=1"
+ '') (filter (i: !i.preferTempAddress) interfaces);
+ })
+ ] ++ lib.optional (cfg.wlanInterfaces != {})
(pkgs.writeTextFile {
name = "99-zzz-40-wlanInterfaces.rules";
destination = "/etc/udev/rules.d/99-zzz-40-wlanInterfaces.rules";
@@ -1161,8 +1178,7 @@ in
# Generate the same systemd events for both 'add' and 'move' udev events.
ACTION=="move", SUBSYSTEM=="net", ENV{DEVTYPE}=="wlan", NAME=="${device}", ${systemdAttrs curInterface._iName}
'');
- }) ];
-
+ });
};
}
diff --git a/nixos/tests/ipv6.nix b/nixos/tests/ipv6.nix
index 14f24c29cfe2..d11eba764da3 100644
--- a/nixos/tests/ipv6.nix
+++ b/nixos/tests/ipv6.nix
@@ -1,14 +1,16 @@
# Test of IPv6 functionality in NixOS, including whether router
# solicication/advertisement using radvd works.
-import ./make-test.nix ({ pkgs, ...} : {
+import ./make-test.nix ({ pkgs, lib, ...} : {
name = "ipv6";
meta = with pkgs.stdenv.lib.maintainers; {
maintainers = [ eelco ];
};
nodes =
- { client = { ... }: { };
+ # Remove the interface configuration provided by makeTest so that the
+ # interfaces are all configured implicitly
+ { client = { ... }: { networking.interfaces = lib.mkForce {}; };
server =
{ ... }:
@@ -73,6 +75,11 @@ import ./make-test.nix ({ pkgs, ...} : {
$client->succeed("curl --fail -g http://[$serverIp]");
$client->fail("curl --fail -g http://[$clientIp]");
};
+ subtest "privacy extensions", sub {
+ my $ip = waitForAddress $client, "eth1", "global temporary";
+ # Default route should have "src " in it
+ $client->succeed("ip r g ::2 | grep $ip");
+ };
# TODO: test reachability of a machine on another network.
'';
diff --git a/nixos/tests/networking.nix b/nixos/tests/networking.nix
index ed9f287d5582..949d946bdc4c 100644
--- a/nixos/tests/networking.nix
+++ b/nixos/tests/networking.nix
@@ -510,7 +510,7 @@ let
'';
};
};
- nodes.client = { pkgs, ... }: with pkgs.lib; {
+ nodes.clientWithPrivacy = { pkgs, ... }: with pkgs.lib; {
virtualisation.vlans = [ 1 ];
networking = {
useNetworkd = networkd;
@@ -522,21 +522,39 @@ let
};
};
};
+ nodes.client = { pkgs, ... }: with pkgs.lib; {
+ virtualisation.vlans = [ 1 ];
+ networking = {
+ useNetworkd = networkd;
+ useDHCP = true;
+ interfaces.eth1 = {
+ preferTempAddress = false;
+ ipv4.addresses = mkOverride 0 [ ];
+ ipv6.addresses = mkOverride 0 [ ];
+ };
+ };
+ };
testScript = { ... }:
''
startAll;
$client->waitForUnit("network.target");
+ $clientWithPrivacy->waitForUnit("network.target");
$router->waitForUnit("network-online.target");
# Wait until we have an ip address
+ $clientWithPrivacy->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'");
$client->waitUntilSucceeds("ip addr show dev eth1 | grep -q 'fd00:1234:5678:1:'");
# Test vlan 1
+ $clientWithPrivacy->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1");
$client->waitUntilSucceeds("ping -c 1 fd00:1234:5678:1::1");
# Test address used is temporary
- $client->waitUntilSucceeds("! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'");
+ $clientWithPrivacy->waitUntilSucceeds("! ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'");
+
+ # Test address used is EUI-64
+ $client->waitUntilSucceeds("ip route get fd00:1234:5678:1::1 | grep -q ':[a-f0-9]*ff:fe[a-f0-9]*:'");
'';
};
routes = {