From 17256403d085dcc12e7a42d99688d38f717b31d4 Mon Sep 17 00:00:00 2001 From: Lin Jian Date: Wed, 14 Jan 2026 14:04:57 +0800 Subject: [PATCH] nixos/network-interfaces: allow setting virtualOwner to null null will not set owner, allowing any user to access the virtual device. Previously, this behavior can be achieved by using systemd.network.netdevs.* options direcly and leaving systemd.network.netdevs..tapConfig.User unset. With this patch, this behavior can be achieved using the generic networking.interfaces.* options by setting networking.interfaces..virtualOwner to null. If needed, we can change the default value from "root" to null in the future to be consistent with systemd-networkd's default behavior. --- nixos/modules/tasks/network-interfaces-scripted.nix | 4 +++- nixos/modules/tasks/network-interfaces.nix | 3 ++- nixos/tests/networking/networkd-and-scripted.nix | 8 +++++++- 3 files changed, 12 insertions(+), 3 deletions(-) diff --git a/nixos/modules/tasks/network-interfaces-scripted.nix b/nixos/modules/tasks/network-interfaces-scripted.nix index 9e6529e487b4..e4408b6771d2 100644 --- a/nixos/modules/tasks/network-interfaces-scripted.nix +++ b/nixos/modules/tasks/network-interfaces-scripted.nix @@ -322,7 +322,9 @@ let RemainAfterExit = true; }; script = '' - ip tuntap add dev "${i.name}" mode "${i.virtualType}" user "${i.virtualOwner}" + ip tuntap add dev "${i.name}" mode "${i.virtualType}" ${ + lib.optionalString (i.virtualOwner != null) ''user "${i.virtualOwner}"'' + } ''; postStop = '' ip link del dev ${i.name} || true diff --git a/nixos/modules/tasks/network-interfaces.nix b/nixos/modules/tasks/network-interfaces.nix index 2a6d00296303..92c151142215 100644 --- a/nixos/modules/tasks/network-interfaces.nix +++ b/nixos/modules/tasks/network-interfaces.nix @@ -348,9 +348,10 @@ let virtualOwner = mkOption { default = "root"; - type = types.str; + type = types.nullOr types.str; description = '' In case of a virtual device, the user who owns it. + `null` will not set owner, allowing access to any user. ''; }; diff --git a/nixos/tests/networking/networkd-and-scripted.nix b/nixos/tests/networking/networkd-and-scripted.nix index b75f82218a69..c9b9d75cdcfd 100644 --- a/nixos/tests/networking/networkd-and-scripted.nix +++ b/nixos/tests/networking/networkd-and-scripted.nix @@ -1053,6 +1053,7 @@ let } ]; virtual = true; + virtualOwner = null; mtu = 1342; macAddress = "02:de:ad:be:ef:01"; }; @@ -1070,13 +1071,14 @@ let } ]; virtual = true; + virtualOwner = "root"; mtu = 1343; }; }; testScript = '' targetList = """ - tap0: tap persist user 0 + tap0: tap persist tun0: tun persist user 0 """.strip() @@ -1101,6 +1103,10 @@ let machine.wait_until_succeeds("ip link show dev tap0 | grep 'mtu 1342'") machine.wait_until_succeeds("ip link show dev tun0 | grep 'mtu 1343'") assert "02:de:ad:be:ef:01" in machine.succeed("ip link show dev tap0") + with subtest("Test virtualOwner are configured"): + for interface, expected_owner in [("tap0", "-1"), ("tun0", "0")]: + actual_owner = machine.succeed(f"cat /sys/class/net/{interface}/owner").strip() + assert expected_owner == actual_owner, f"{interface} owner: expect {expected_owner}, got {actual_owner}" '' # network-addresses-* only exist in scripted networking + lib.optionalString (!networkd) '' with subtest("Test interfaces' addresses clean up"):