Differences between revisions 4 and 6 (spanning 2 versions)
Revision 4 as of 2019-09-12 09:59:53
Size: 13300
Editor: JustinBRye
Comment:
Revision 6 as of 2019-09-12 10:43:39
Size: 13558
Editor: JustinBRye
Comment: still not ready for prime time
Deletions are marked like this. Additions are marked like this.
Line 1: Line 1:
The plan is to turn this into something that the Release Notes can point at as the nearest thing we've got to an official guide.

ToDo: give it a reread in the
morning, add link from [[NetworkFAQ]] (but much of that page needs replacing)
ToDo: the plan is to turn this into something that the Release Notes can point at as the nearest thing we've got to an official guide. What if anything does this page need to say about NetworkMangler and systemd-networkd?
Line 10: Line 8:
== Table of Contents == <<TableOfContents()>> <<TableOfContents()>>
Line 22: Line 20:
At least in theory, if module probes completed in a different order,
`eth0` and `eth1` might switch places on successive boots. As boot
processes became less linear and interfaces became more hotpluggable
this became more of a concern.
At least in theory, if module probes completed in a different order, `eth0` and `eth1` might switch places on successive boots. As boot processes became less linear and interfaces became more hotpluggable this became more of a concern.
Line 29: Line 24:
If you wipe out all other mechanisms (booting with the `ifnames`
mechanism deactivated and no
`/etc/udev/rules.d/75-persistent-net.rules` file, or maybe just a
`udev` that has finally stopped supporting it) then I suppose you'll
If you wipe out all other mechanisms (booting with the `net.ifnames` mechanism deactivated and no `/etc/udev/rules.d/75-persistent-net.rules` file, or maybe just a `udev` that has finally stopped supporting it) then presumably you'll
Line 34: Line 26:

(Is this account missing old approaches to interface-renaming that
still need to be dealt with? For instance, does the package
[[DebianPkg:ifrename|ifrename]] still work?)
Line 42: Line 30:
= THE "PERSISTENT NAMES" APPROACH = = THE "PERSISTENT NAMES" SCHEME =
Line 44: Line 32:
This scheme, introduced somewhere around Debian 5 "Lenny", used `udev`
to identify interfaces by MAC address and assign a fixed interface
number to any interface it recognized (writing the rules to
`/etc/udev/rules.d/75-persistent-net.rules`). This could have annoying
side-effects (e.g. if you were replacing a machine's sole NIC, you'd
also have to take special care to ensure it took over as network
interface number 0) but these were minor and predictable.
This scheme, introduced somewhere around Debian 5 "Lenny", used `udev` to identify interfaces by MAC address and assign a fixed interface number to any interface it recognized (writing the rules to `/etc/udev/rules.d/75-persistent-net.rules`). This could have annoying side-effects (e.g. if you were replacing a machine's sole NIC, you'd also have to take special care to ensure it took over as network interface number 0) but these were minor and predictable.
Line 54: Line 36:
This still had subtle race conditions, required `/etc` to be on a
writable file system, and had problems with virtualization, so it's no
longer supported upstream; the plan (still taken for granted in most
of the documentation) was for it not to be supported in Debian 10
"Buster", but in the end it has scraped through into another release
cycle.
This still had subtle race conditions, required `/etc` to be on a writable file system, and had problems with virtualization, so it's no longer supported upstream; the plan (still taken for granted in most of the documentation) was for it not to be supported in Debian 10 "Buster", but in the end it has scraped through into another release cycle.
Line 63: Line 40:
First, make sure you've got a working "legacy"
`/etc/udev/rules.d/75-persistent-net.rules` file. Then deactivate the
replacement scheme. The simple way of doing that latter (which you
might want to try for one-off testing) is just to boot with the kernel
parameter `net.ifnames=0`, which can be set in an interactive `grub`
session at boot (or made persistent by editing `/etc/default/grub` and
running `update-grub`).
First, make sure you've got a working "legacy" `/etc/udev/rules.d/75-persistent-net.rules` file. Then deactivate the replacement scheme. The simple way of doing that latter (which you might want to try for one-off testing) is just to boot with the kernel parameter `net.ifnames=0`, which can be set in an interactive `grub` session at boot or made persistent by editing `/etc/default/grub` and running `update-grub`.
Line 71: Line 42:
Alternatively, you can override `/lib/systemd/network/99-default.link`,
with a custom version in `/etc/systemd/network/`, '''or''' similarly
override `/lib/udev/rules.d/80-net-setup-link.rules`, '''or''' mask
the latter by using a `/dev/null` symlink instead of a custom version,
or... there seem to be lots of ways of doing this, so make sure you
haven't done it in more than one way or it'll trip you up in a couple
of years when you try to undo it. Oh, and beware of [[#initrd|initrd skew]].
Alternatively, you can override `/lib/systemd/network/99-default.link`, with a custom version in `/etc/systemd/network/`, '''or''' similarly override `/lib/udev/rules.d/80-net-setup-link.rules`, '''or''' mask the latter by using a `/dev/null` symlink instead of a custom version, or... there seem to be lots of ways of doing this, so make sure you haven't done it in more than one way or it'll trip you up in a couple of years when you try to undo it. Oh, and beware of [[#initrd|initrd skew]].
Line 79: Line 44:
Unfortunately, none of this will carry on working beyond the point
when `udev` stops supporting the legacy `75-persistent-net.rules`
mechanism, so you should be ready to switch to a different system when
that happens.
Unfortunately, none of this will carry on working beyond the point when `udev` stops supporting the legacy `75-persistent-net.rules` mechanism, so you should be ready to switch to a different system when that happens.
Line 90: Line 52:
<<Anchor(biosdevname)>>
= ANOTHER APPROACH SOMETIMES SEEN ON NON-DEBIAN SYSTEMS =
<<Anchor(misc)>>
= MISCELLANEOUS SCHEMES =

(Contributions welcome)

Several workarounds for renaming interfaces grew up in the early days of hotpluggable wireless interfaces, but if they still work it'll be because like [[DebianPkg:ifrename]] they now use `udev` rules under the hood. It's not clear what remaining advantage this has over [[#alt|the canonical .link approach]] - is it perhaps useful for non-systemd machines?
Line 100: Line 66:
The new "net.ifnames" approach uses names usually derived from the
location of the interface in terms of hardware buses etc.
The new "net.ifnames" approach uses names usually derived from the location of the interface in terms of hardware buses etc: `eno1`, 'wlp1s3`...
Line 103: Line 68:
(This system is often advertised as providing "Predictable Names",
but the main thing that's predictable about it is that calling it
this will cause furious users to pop up disputing the appropriateness
of that name. Can we just skip all that here, please?)
(This system is often advertised as providing "Predictable Names", but the main thing that's predictable about it is that calling it this will cause furious users to pop up disputing the appropriateness of that name. Can we just skip all that here, please?)
Line 110: Line 72:
This should be easy enough; before you start configuring firewalls
etc., just look at the output of (e.g.) `ip a`.
This should be easy enough; before you start configuring firewalls etc., just look at the output of (e.g.) `ip a`.
Line 113: Line 74:
Unlike the old days, when the only way to guess which cable was
plugged into `eth0` and which was `eth1` was to keep track of MAC
addresses, this system provides extra clues in the interface names.
/* Either `enp0s1` is the one on the left and `enp1s0` is the one on
the right, or equally likely it's the other way round. See? So much
easier. */
Unlike the old days, when the only way to guess which cable was plugged into `eth0` and which was `eth1` was to keep track of MAC addresses, this system provides extra clues in the interface names.
/* Either `enp0s1` is the one on the left and `enp1s0` is the one on the right, or equally likely it's the other way round. See? So much easier. */
Line 122: Line 79:
It's advisable to do this as a separate thing in its own right, not
as part of a general dist-upgrade. However, if your PC only has one
network interface and not much is at stake you can try:
It's advisable to do this as a separate thing in its own right, not as part of a general dist-upgrade. However, if your PC only has one network interface and not much is at stake you can try:
Line 132: Line 87:
You should probably at least check in advance to see what files
hard-code interface names, by running something like
You should probably at least check in advance to see what files hard-code interface names, by running something like
Line 139: Line 93:
(Obvious possibilities include `/etc/network/interfaces` and
configuration files for firewalls, wifi, DHCP...)
(Obvious possibilities include `/etc/network/interfaces` and configuration files for firewalls, wifi, DHCP...)
Line 144: Line 97:
This strategy, more or less compulsory for remote servers, runs along
the lines of:
This strategy, more or less compulsory for remote servers, runs along the lines of:
Line 157: Line 109:
To find out what names `udev` would be choosing between if you switched
over to the new system, first get a list of the network devices the
system knows about:
To find out what names `udev` would be choosing between if you switched over to the new system, first get a list of the network devices the system knows about:
Line 165: Line 115:
For each device (other than `lo`), ask `udevadm` what NET_IDs it knows: For each device path (other than `/sys/class/net/lo`), ask `udevadm` what NET_IDs it knows:
Line 171: Line 121:
It's likely to tell you about things like ID_OUI_FROM_DATABASE and an ID_NET_NAMING_SCHEME, but the lines that matter are the ones (given
in unhelpfully random order) starting with ID_NET_NAME_. One of these
is the name that `udev` will give priority to - the list of candidates
may be so short that all you need to know is that ..._PATH beats
..._MAC, but there are also some rarer possibilities, and in general
if something unusual shows up then it will take priority.
It's likely to tell you about things like ID_OUI_FROM_DATABASE and an ID_NET_NAMING_SCHEME, but the lines that matter are the ones (given in unhelpfully random order) starting with ID_NET_NAME_. One of these is the name that `udev` will give priority to - the list of candidates may be so short that all you need to know is that ..._PATH beats ..._MAC, but there are also some rarer possibilities, and in general if something unusual shows up then it will take priority.
Line 181: Line 126:
/* My theory is that the global vampire conspiracy set this up so that
we've technically already invited them to cross the threshold. */
/* My theory is that the global vampire conspiracy set this up so that we've technically already invited them to cross the threshold. */
Line 193: Line 137:
and it would list the interfaces it knows with their available names
ordered by the priority policy currently in force... or, wait, surely
in a ''sane'' world we'd be free to use any of these names, the way we
can use any of the aliases in `/dev/disks` to refer to a hard disk.
But that would be too simple. */
and it would list the interfaces it knows with their available names ordered by the priority policy currently in force... or, wait, surely in a ''sane'' world we'd be free to use any of these names, the way we can use any of the aliases in `/dev/disks` to refer to a hard disk. But that would be too simple. */
Line 209: Line 149:
 * INITRD SKEW:: it's all very well having everything sorted out in `/etc`; but to make sure your initrd doesn't contain out-of-date versions of important `systemd` unit files, regenerate it with `sudo update-initramfs -u`  * INITRD SKEW:: it's all very well having everything sorted out in `/etc`, but interface renaming has to happen very early during boot; to make sure your initrd doesn't contain out-of-date versions of important `systemd` files, regenerate it with `sudo update-initramfs -u`
Line 219: Line 159:
 * ANTIQUE SYSTEMS:: on Debian 9 "Stretch" or newer, merely booting without an `ifnames=0` override should be enough to let you to test the new scheme, but on Debian 8 "Jessie" or older you'll need to actively set it to `ifnames=1`.  * ANTIQUE SYSTEMS:: on Debian 9 "Stretch" or newer, merely booting without a `net.ifnames=0` override should be enough to let you to test the new scheme, but on Debian 8 "Jessie" or older you'll need to actively set it to `net.ifnames=1`.
Line 224: Line 164:
= ALTERNATIVE APPROACHES = = ALTERNATIVE SCHEMES =
Line 226: Line 166:
You can also use `.link` files to set up naming schemes to suit
yourself - so
for instance if you have two PCs each of which has only
a single wireless card, but one calls it `wlp0s1` and the other
`wlp1s0`, you can arrange for them both to use the name `wifi0` to
simplify sharing firewall configurations. For details see
[[DebianMan:5/systemd.link|systemd.link(5)]].
The above is the new standard default scheme, but there's also a canonical way of overriding the default: you can use `.link` files to set up naming policies to suit your needs. Thus for instance if you have two PCs each of which has only a single wireless card, but one calls it `wlp0s1` and the other `wlp1s0`, you can arrange for them both to use the name `wifi0` to simplify sharing firewall configurations. For details see [[DebianMan:5/systemd.link|systemd.link(5)]].
Line 234: Line 169:
!NamePolicy defined in `/lib/systemd/network/99-default.link` (so that
for instance all network cards are named by MAC address).
!NamePolicy defined in `/lib/systemd/network/99-default.link` (so that for instance all network cards are named by MAC address).
Line 244: Line 178:
There's some information in `/usr/share/doc/udev/README.Debian.gz`,
and more in
[[https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/]]. The big problem with the latter is that it delegates all its technical details to a link pointing at the sourcecode:
[[https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-net_id.c]]
...but unfortunately most of the useful comments that used to be at
the top of that file have been thrown out, so you need to find your
way back through the `git` tree to a previous version such as
[[https://github.com/systemd/systemd/blob/eefe36e64c1a583bb9470884ed92115e0ce4647e/src/udev/udev-builtin-net_id.c]]
There's some information in `/usr/share/doc/udev/README.Debian.gz`, and more in
[[https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/]]. The big problem with the latter is that it delegates all its technical details to a link pointing at the sourcecode:[[https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-net_id.c]] ...but unfortunately most of the useful comments that used to be at the top of that file have been thrown out, so you need to find your way back through the `git` tree to a previous version such as [[https://github.com/systemd/systemd/blob/eefe36e64c1a583bb9470884ed92115e0ce4647e/src/udev/udev-builtin-net_id.c]]
Line 253: Line 181:
A guide that mentions ID_NET_NAME_FROM_DATABASE:
[[https://major.io/2015/08/21/understanding-systemds-predictable-network-device-names/]]
A guide that mentions ID_NET_NAME_FROM_DATABASE:[[https://major.io/2015/08/21/understanding-systemds-predictable-network-device-names/]]
Line 257: Line 184:
[[https://askubuntu.com/questions/659267/how-do-i-override-or-configure-systemd-services]]
[[https://wiki.archlinux.org/index.php/systemd]]
[[https://askubuntu.com/questions/659267/how-do-i-override-or-configure-systemd-services]], [[https://wiki.archlinux.org/index.php/systemd]]

ToDo: the plan is to turn this into something that the Release Notes can point at as the nearest thing we've got to an official guide. What if anything does this page need to say about ?NetworkMangler and systemd-networkd?

Warning: Anything that changes the names of your network interfaces may result in the machine suddenly not being reachable over SSH, so if you're editing settings on a remote server, plan your changes carefully and doublecheck your safety nets.


THE ORIGINAL SIMPLE SCHEME

Back in the nineties, eth0, eth1, etc were simply assigned by the kernel.

Why it was abandoned

At least in theory, if module probes completed in a different order, eth0 and eth1 might switch places on successive boots. As boot processes became less linear and interfaces became more hotpluggable this became more of a concern.

How to get it back

If you wipe out all other mechanisms (booting with the net.ifnames mechanism deactivated and no /etc/udev/rules.d/75-persistent-net.rules file, or maybe just a udev that has finally stopped supporting it) then presumably you'll be back to this one.


THE "PERSISTENT NAMES" SCHEME

This scheme, introduced somewhere around Debian 5 "Lenny", used udev to identify interfaces by MAC address and assign a fixed interface number to any interface it recognized (writing the rules to /etc/udev/rules.d/75-persistent-net.rules). This could have annoying side-effects (e.g. if you were replacing a machine's sole NIC, you'd also have to take special care to ensure it took over as network interface number 0) but these were minor and predictable.

Why this one was abandoned

This still had subtle race conditions, required /etc to be on a writable file system, and had problems with virtualization, so it's no longer supported upstream; the plan (still taken for granted in most of the documentation) was for it not to be supported in Debian 10 "Buster", but in the end it has scraped through into another release cycle.

How to cling to it for now

First, make sure you've got a working "legacy" /etc/udev/rules.d/75-persistent-net.rules file. Then deactivate the replacement scheme. The simple way of doing that latter (which you might want to try for one-off testing) is just to boot with the kernel parameter net.ifnames=0, which can be set in an interactive grub session at boot or made persistent by editing /etc/default/grub and running update-grub.

Alternatively, you can override /lib/systemd/network/99-default.link, with a custom version in /etc/systemd/network/, or similarly override /lib/udev/rules.d/80-net-setup-link.rules, or mask the latter by using a /dev/null symlink instead of a custom version, or... there seem to be lots of ways of doing this, so make sure you haven't done it in more than one way or it'll trip you up in a couple of years when you try to undo it. Oh, and beware of initrd skew.

Unfortunately, none of this will carry on working beyond the point when udev stops supporting the legacy 75-persistent-net.rules mechanism, so you should be ready to switch to a different system when that happens.

How to let go and move on

If you've currently got a legacy /etc/udev/rules.d/75-persistent-net.rules file but have decided to switch to the new regime, you can do that just by disabling the .rules file; see the udev README.Debian.gz


MISCELLANEOUS SCHEMES

(Contributions welcome)

Several workarounds for renaming interfaces grew up in the early days of hotpluggable wireless interfaces, but if they still work it'll be because like ifrename they now use udev rules under the hood. It's not clear what remaining advantage this has over the canonical .link approach - is it perhaps useful for non-systemd machines?

Old releases of RedHat (among others) used a "biosdevname" system, but that's never been supported under Debian. If you need to know about it there's bound to be documentation somewhere.


THE NEW APPROACH TO NETWORK INTERFACE NAMES

The new "net.ifnames" approach uses names usually derived from the location of the interface in terms of hardware buses etc: eno1, 'wlp1s3`...

(This system is often advertised as providing "Predictable Names", but the main thing that's predictable about it is that calling it this will cause furious users to pop up disputing the appropriateness of that name. Can we just skip all that here, please?)

How to cope with it on fresh installs

This should be easy enough; before you start configuring firewalls etc., just look at the output of (e.g.) ip a.

Unlike the old days, when the only way to guess which cable was plugged into eth0 and which was eth1 was to keep track of MAC addresses, this system provides extra clues in the interface names.

How to switch to this scheme on upgraded systems

It's advisable to do this as a separate thing in its own right, not as part of a general dist-upgrade. However, if your PC only has one network interface and not much is at stake you can try:

strategy A

  • wait until udev breaks your networking, if it's going to, or trigger the change by disabling the persistent-names system.

  • ask ip what new name it's using, and fix your config files.

You should probably at least check in advance to see what files hard-code interface names, by running something like

        sudo rgrep ''wlan0'' /etc

(Obvious possibilities include /etc/network/interfaces and configuration files for firewalls, wifi, DHCP...)

strategy B

This strategy, more or less compulsory for remote servers, runs along the lines of:

  • devise a migration plan
  • consider a dead-man's-handle etckeeper cronjob or the like

  • consult the list of corner cases below and search the Internet for others

  • once you're sure you're safe, implement your migration plan
  • you've got backups, right?

To find out what names udev would be choosing between if you switched over to the new system, first get a list of the network devices the system knows about:

        echo /sys/class/net/*

For each device path (other than /sys/class/net/lo), ask udevadm what NET_IDs it knows:

        udevadm test-builtin net_id /sys/class/net/''enp0s1'' 2>/dev/null

It's likely to tell you about things like ID_OUI_FROM_DATABASE and an ID_NET_NAMING_SCHEME, but the lines that matter are the ones (given in unhelpfully random order) starting with ID_NET_NAME_. One of these is the name that udev will give priority to - the list of candidates may be so short that all you need to know is that ..._PATH beats ..._MAC, but there are also some rarer possibilities, and in general if something unusual shows up then it will take priority.

From highest priority to lowest, the list is:

* ID_NET_NAME_FROM_DATABASE=

very rare (possibly mythical) and not to be confused with ID_OUI_FROM_DATABASE; if present, it gets maximum priority. Nobody seems to know why - it's mentioned in systemd.link(5), but otherwise undocumented. The database is hardcoded into udev and has only one known entry, the spooky-sounding idrac.

* ID_NET_NAME_ONBOARD=

appears for some but not all kinds of onboard network card (Ethernet only, or wireless too?) - it's usually a nice simple name like eno0.

* ID_NET_NAME_SLOT=

appears for some PCI-hotplug cards. Usually looks like ens0 (again, any wifi cases? Does it ever occur along with _ONBOARD?)

* ID_NET_NAME_PATH=

always present; usually something just complicated enough to be easy to forget, like wlp3s5 or enp1s3f0. Note that all numbers are in hex.

* ID_NET_NAME_MAC=

also always present, but with a low enough priority that by default it won't be used; e.g. wlx800e1319c734

Complications and corner cases

(Additions welcome, but please try to avoid ballooning this section with tales of "I don't know how this happened but it all went wrong for me"...)

* TRIGGERING THE SWITCH

you don't need to delete /etc/udev/rules.d/70-persistent-net.rules to test what network interface names you'll get without it. Just renaming it (e.g. to 70-persistent-net.rules.old) or commenting out particular lines should be enough (as long as you update your initrd before you reboot).

* THE ID_NET_NAME_ HIERARCHY
if you're ignoring ID_NET_NAME_SOMETHING on the assumption that anything you don't understand probably isn't important, you need to reread the above - the general rule is, if you don't recognise it, it'll mess you up.

* INITRD SKEW

it's all very well having everything sorted out in /etc, but interface renaming has to happen very early during boot; to make sure your initrd doesn't contain out-of-date versions of important systemd files, regenerate it with sudo update-initramfs -u

* LEFTOVERS

the old persistent-names system first started being publicly deprecated in NEWS files back in mid-2015, so this upgrade has been hanging ominously over people's heads for a long time. Are you sure you didn't do something about it the last time the subject came up, like setting up a net.ifnames=0 kernel parameter, and/or masking some systemd config file? If so, this may result in confusing symptoms when you try to go over to the new system. Check your administrative logbooks. What do you mean, you don't keep logs?

* USB DEVICES

since they might get plugged into a different socket each time, these use ID_NET_NAME_MAC - automated via /lib/udev/rules.d/73-usb-net-by-mac.rules.

* VIRTUAL MACHINES

on virtual machines (according to the udev README) you will need to remove the files /etc/systemd/network/99-default.link and (if using virtio network devices) /etc/systemd/network/50-virtio-kernel-names.link, then rebuild the initrd.

* UNPREDICTABILITY
it turns out even after all this there are still reported cases of interfaces changing their name on a reboot. All that needs to happen is that some buggy BIOS, or some new, less buggy version of a driver module, changes its mind about whether or not your hardware counts as the kind that should have an ONBOARD or SLOT name.
* ANTIQUE SYSTEMS

on Debian 9 "Stretch" or newer, merely booting without a net.ifnames=0 override should be enough to let you to test the new scheme, but on Debian 8 "Jessie" or older you'll need to actively set it to net.ifnames=1.


ALTERNATIVE SCHEMES

The above is the new standard default scheme, but there's also a canonical way of overriding the default: you can use .link files to set up naming policies to suit your needs. Thus for instance if you have two PCs each of which has only a single wireless card, but one calls it wlp0s1 and the other wlp1s0, you can arrange for them both to use the name wifi0 to simplify sharing firewall configurations. For details see systemd.link(5).

It's also possible to reorganize the naming policy by overriding the NamePolicy defined in /lib/systemd/network/99-default.link (so that for instance all network cards are named by MAC address).


EXTERNAL REFERENCES

Stretch and Buster Release Notes

There's some information in /usr/share/doc/udev/README.Debian.gz, and more in https://www.freedesktop.org/wiki/Software/systemd/PredictableNetworkInterfaceNames/. The big problem with the latter is that it delegates all its technical details to a link pointing at the sourcecode:https://github.com/systemd/systemd/blob/master/src/udev/udev-builtin-net_id.c ...but unfortunately most of the useful comments that used to be at the top of that file have been thrown out, so you need to find your way back through the git tree to a previous version such as https://github.com/systemd/systemd/blob/eefe36e64c1a583bb9470884ed92115e0ce4647e/src/udev/udev-builtin-net_id.c

A guide that mentions ID_NET_NAME_FROM_DATABASE:https://major.io/2015/08/21/understanding-systemds-predictable-network-device-names/

General guides to overriding systemd configuration: https://askubuntu.com/questions/659267/how-do-i-override-or-configure-systemd-services, https://wiki.archlinux.org/index.php/systemd


CategoryNetwork