10

How do you reset /etc/networking/interfaces when using "predictable network interface names"?

Versions of Ubuntu older than 15.10 use network adapter names like:

  • eth0
  • eth1
  • eth2

Replacing a network card, or moving a vm to a new hypervisor, would cause Linux to increment the interface number. Deleting /etc/udev/rules.d/70-peristent-net.rules would make Linux reuse eth0.

Ubuntu 15.10 and newer use 'Predictable Network Interface Names'. The network adapter name is derived from the mac address.

  • ens3
  • ens32
  • ens192

When migrating a vm, the networking won't start since /etc/network/interfaces still references the old non existent network adapter.

# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto ens32
iface ens32 inet dhcp
pre-up sleep 2

What's the best way to reset the /etc/network/interfaces file?

I need to do this action before shutting down the vm and migrating to a new hypervisor since I'm using packer to make automated golden images, based on the chef/bento golden images.

I've found deleting /etc/network/interfaces does not work since the file isn't automatically regenerated on the next boot after migration.

I've tried editing my grub file to revert back to the 'eth0' naming convention. While /etc/network/interfaces does refer to the old name (eth0), the vm will not get an ip, and any reboots will cause the vm to use the new naming convention. Also I've found systemd will always take precedence unless I can guarantee biosdevname=0 permanently remains in the grub config. Not sure how to permanently apply this

GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 bios.devname=0"

If possible, I'd rather not use cloud init or use any post startup scripts since I'd rather keep the golden images as clean as possible.

Surely this is a problem that cloud providers (Azure, AWS, RackSpace, Openstack) have already solved when they import vms. I can't possibly be the first person to try and migrate a vm using predictable network interface names.

I've tried running these commands before shutting down and migrating the vm

apt-get remove biosdevname -y;
ln -s /dev/null /etc/systemd/network/99-default.link;

I find when I migrate the vm, that /etc/network/interfaces and ip address still refer to ens32

3
  • Did you try the solution from sister site askubuntu? askubuntu.com/a/785442/467355 - basically manually create the udev rule, and possibly use a single time boot script to insert the new mac into it after the clone (or to create it fresh after each clone)
    – Dani_l
    Jan 22, 2017 at 21:09
  • Yes, I did look at that. These are generic golden images that can be used by anyone so I don't know the mac address ahead of time.
    – spuder
    Jan 26, 2017 at 17:16
  • That's the whole point of "use a single time boot script to insert the new mac into it after the clone (or to create it fresh after each clone) " - you insert a new boot script to the golden image that upon boot queries and insert the correct mac to the udev rule.
    – Dani_l
    Jan 27, 2017 at 8:48

5 Answers 5

4
+50

Surely this is a problem that cloud providers (Azure, AWS, RackSpace, Openstack) have already solved when they import vms.

I think OpenStack uses cloud-init, ConfigDrive format, and provides a network configuration that matches the VM hardware. Sources:

If you rule out a first-boot script, there is one obvious answer.

Previously it was practically guaranteed that hosts equipped with a single ethernet card only had a single "eth0" interface. With this new scheme in place, an administrator now has to check first what the local interface name is before he can invoke commands on it where previously he had a good chance that "eth0" was the right name.

I don't like this, how do I disable this?

You basically have three options:

  1. You disable the assignment of fixed names, so that the unpredictable kernel names are used again. For this, simply mask udev's .link file for the default policy: ln -s /dev/null /etc/systemd/network/99-default.link

https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/

Switching back to the old persistent interface names is not one of the options documented.

The other alternative is a setup where network interfaces are enabled by default, regardless of their exact name. I think NetworkManager supports this by default. systemd-networkd can also be told to do this.

As soon as you have more than one network device for a VM, they probably need specific configuration anyway...

Outside of VM's, there is one obvious advantage of the NetworkManager-style approach: a PC might have multiple network interfaces, perhaps of different types, with only one of them being connected. For example this can be seen on some premium motherboards, or on a system where the first network interface did not work as desired and a second interface was installed at some point.

1
  • Great suggestions. I find that ln -s /dev/null /etc/systemd/network/99-default.link makes no difference. my vms still use the new naming convention.
    – spuder
    Jan 19, 2017 at 23:01
4

I gave up on trying to do this cleanly, and came up with the following hack. By running the following script just before shutting down the vm and migrating, the vm will have eth0 as the network adapter when powered on.

ln -s /dev/null /etc/systemd/network/99-default.link;
echo '# This file describes the network interfaces available on your system
# and how to activate them. For more information, see interfaces(5).

source /etc/network/interfaces.d/*

# The loopback network interface
auto lo
iface lo inet loopback

# The primary network interface
auto eth0
iface eth0 inet dhcp
pre-up sleep 2' > /etc/network/interfaces

sed -i.bak 's/GRUB_CMDLINE_LINUX_DEFAULT=.*/GRUB_CMDLINE_LINUX_DEFAULT="net.ifnames=0 bios.devname=0 quiet"/' /etc/default/grub
update-grub
apt-get remove biosdevname -y || true;

Strictly speaking, apt-get remove biosdevname isn't required since that package isn't installed by default on ubuntu 16.04. Also, adding bios.devname=0 to the GRUB_CMDLINE_LINUX_DEFAULT isn't required since biosdevname isn't installed. It does prevent the network from breaking if biosdevname is ever installed in the future.

1
  • Why setting the link and passing the kernel argument? The documentation states one should be enough. Cursory check suggests that's indeed the case. Apr 24, 2018 at 14:19
2

Do you need predictable network interface names?

My solution has been to uninstall biosdevname, and that has reliably resulted in always having network interfaces named as eth0, eth1, and so on. I have not found a good reason to have predictable network interface names nor biosdevname installed.

in /etc/udev/rules.d/70-persistent-net.rules is where you can modify what hardware mac address gets named to eth0, eth1, and so on. I normally delete the contents of this file, save it as a blank file, reboot, then I have a clean slate with correct network adapters showing up...

# This file was automatically generated by the /lib/udev/write_net_rules
# program,run by the persistent-net-generator.rules rules file.
#
# This file was automatically generated by the /lib/udev/write_net_rules
# program,run by the persistent-net-generator.rules rules file.
#
# You can modify it,as long as you keep each rule on a single
# line,and change only the value of the NAME= key.
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="xx:xx:xx:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth0"
SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="xx:xx:xx:xx:xx:xx", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="eth1"

^^ where xx:xx:xx:xx:xx:xx is the unique mac address of your network adapters.

I know you mention deleting this file is not the solution, but i post the example above because at least in Suse it is /lib/udev/write_net_rules that creates this file. So see if back tracking to this file helps, if it is applicable to your distribution you may be able to modify it to solve your problem.

note this is what i know from Suse version 11 which is the old Init way, before systemd. Not sure if this has changed for the latest versions of linux under systemd.

1
2

You can actually use systemd to configure your network irrespective of the name.

Create a configuration file:

cat << EOF > /etc/systemd/network/10-eth0.network
[Match]
Name=*

[Network]
DHCP=ipv4

EOF

Enable systemd networking:

systemctl enable systemd-networkd

The configuration file will activate DHCP on all adapters. However, you can also make more sophisticated configurations. Doing so, you won't necessarily need /etc/network/interfaces anymore.

1

Ran into this upgrading Ubuntu 14.04 hosts to 16.04. biosdevname package is not installed so resorted to "biosdevname=0 net.ifnames=0" in /etc/default.grub as stated by OP.

I run this script, and if the output looks good, redirect the output into /etc/udev/rules.d/70-persistent-net.rules to build new udev rules in case the kernel ever decides to enumerate the ethernet ports in a different order.

#!/bin/bash
count=0

# build array of network devices starting with eth? from /proc
for dev in `cat /proc/net/dev | egrep 'eth.*:' | awk '{print $1};' | cut -d':' -f1 | sort`; do
   edev[$count]="$dev"
   let count="$count+1"
done

# use array to find mac address
for d in ${edev[@]}; do
   mac=`ip addr show "$d" | grep ether | awk '{print $2};'`
   if [ -n "$mac" ]; then
      echo "# mac for $d is $mac"
   fi 

   printf 'SUBSYSTEM=="net", ACTION=="add", DRIVERS=="?*", ATTR{address}=="%s", ATTR{dev_id}=="0x0", ATTR{type}=="1", KERNEL=="eth*", NAME="%s"\n' $mac $d
done

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .