How to enable "Predictable Network Interface Names" in initrd?

(I managed to figure it out, see answer below.)

1 Like

The solution is to add extra initrd udev rules:

nix-build --out-link /tmp/vm - <<'EOF'
(import <nixpkgs/nixos> {
  configuration = { lib, pkgs, ... }: with lib; {
    boot.initrd = {
      extraUdevRulesCommands = ''
        cp -v ${pkgs.systemd}/lib/udev/rules.d/75-net-description.rules $out
        cp -v ${pkgs.path}/nixos/modules/services/hardware/80-net-setup-link.rules $out
      '';
      preLVMCommands = ''
        echo
        echo "Yeah, predictable names:"
        ls -l /sys/class/net
        # Pause stage 1
        read
      '';
    };
  };
}).vm
EOF

# Run VM attached to console. To quit, press (Ctrl + A), c, q, <enter>
NIX_DISK_IMAGE=/tmp/vmimg /tmp/vm/bin/run-*-vm -m 1024 -smp 2 -nographic -append 'console=ttyS0'
1 Like

This is what I use, and it works for me on Hetzner hosts, at least.

boot.kernelParams = [ "net.ifnames=0" ];

This option explicitly disables predictable names.

Without net.ifnames=0, a device named eth0 by the kernel may be renamed to, e.g., ens3. For example, here’s a line from dmesg on one of my Vultr host:

[ 4.232924] virtio_net virtio0 ens3: renamed from eth0

Vultr hosts are virtualized, but this also happens on bare metal hosts.

This is particularly problematic on hosts without DHCP support (e.g., Hetzner dedicated instances) when the NixOS installer sees the original kernel name, but upon rebooting with a newer kernel, the device is renamed, and now you don’t have any network connectivity to your newly-installed machine.

The message ens3: renamed from eth0 is from udev in boot stage 2, which renames interfaces from stage 1 that are not brought up according to its extended predictable name rules.
To disable renaming, better use the more expressive networking.usePredictableInterfaceNames = false instead of setting the kernel parameter net.ifnames=0.

But the goal of this thread is the opposite: Enforce predictable names even in stage 1.