Skip to content

2 IPs and 2 DHCP Leases for 1 Network Interface; Possible Solution for Fedora Silverblue #93

@president-not-sure

Description

@president-not-sure

What is the purpose of this issue?

I encountered this issue in Fedora Silverblue 41. I have a configuration that will solve it and require no change to this project's code base or its maintenance, other than maybe a link to this issue in the README.md. I'm not certain if this is the right place to do this though. I could also do a PR and add extra examples, but I think it would be confusing for users.

Description of the issue

When using the recommended configurations, the IPv4 set in the initramfs survives the switchroot. This might be desirable to some or most users, but if you use Fedora, Ubuntu or many others, you use NetworkManager by default. Right or wrong, NetworkManager creates a second IPv4 resulting in no internet connection.

It was suggested in the issue to add KeepConfiguration=no to 20-wired.network as a solution. Which is a partial solution in my opinion. It will work. Only one IPv4 will be used by NetworkManager, but 2 leases will have been created in the DHCP server. Most people won't care, but I do.

Enabling IPv6 for dual-stack networks results in the same outcome.

Source of the issue

TL;DR

There is a combination of multiple issues:

  • systemd-networkd and NetworkManager don't talk to each other. KeepConfiguration=no fixes that one.
  • The initrd and the booted machine are seen as distinct machines.
    • Silverblue defaults to dracut --no-hostonly with its rpm-ostree initramfs imposed dracut wrapper.
      • dracut --hostonly is unusable on Silverblue because it runs in a container. Consequently, it probably is unable to see the full host configuration resulting in an unbootable initrd.

Full

The initrd and the booted machine are seen as 2 distinct machines, so the DHCP server creates 2 leases.

The fix should be to add the /etc/hostname to the initramfs. But it only fixes it for IPv4, because it identifies itself to the DHCP server with it's MAC address. Although, as a nice bonus, the initrd is now reachable using sshd root@myhostname.mydomain. IPv6, on the other hand, uses a DUID instead of the MAC Address. So it still has 2 leases and 2 IPv6 addresses.

Upon further reading documentation on how the DUID is generated, I learned it uses a combination of the MAC address and the machine-id, which is created during the OS install and resides in /etc/machine-id. The next logical step would be to include the /etc/machine-id in the initramfs, but in somes distributions, it does not work. Silverblue is one of those. Silverblue defaults to dracut --no-hostonly with its rpm-ostree initramfs imposed dracut wrapper.

--no-hostonly make a genric initramfs, that is designed to work on most machines. To do this, it overrides any machine specific files including the /etc/machine-id.

Dracut code responsible for this behavior:

# modules.d/00systemd/module-setup.sh
if ! [[ -e "$initdir/etc/machine-id" ]]; then
    : > "$initdir/etc/machine-id"
    chmod 444 "$initdir/etc/machine-id"
fi

In Silverblue, this can't be bypassed with a hook script, as the root is read-only, as an added constraint.

dracut --hostonly is unusable on Silverblue because it runs in a container. Consequently, it probably is unable to see the full host configuration resulting in an unbootable initrd.

My solution

Use what is been used in container land: Overlayfs. Install the desired files in an unexpected location during the initramfs regeneration, to evade the offending code. Mount the overlayfs during the initrd run time with the lower as /etc and the upper as /overlay/etc, using an added /etc/fstab.

This way:

  • root is untouched
  • dracut-sshd code is unmodified
  • The initrd and the booted machine is seen as the same machine by the DHCP server
  • The initrd is reachable with ssh root@myhostname.mydomain
  • The initramfs is regenerated appropriately every update

The only real downside, from my perspective, is that this method will need to be updated when Silverblue moves on from rpm-ostree. I can create a new issue when that happens with the updated solution and a link to this issue.

Silverblue guide

This solution uses the network-manager dracut hook script, but it could easily be used with the project's systemd-networkd provided examples. As long as KeepConfiguration=no is included.

Required files on the host

# /etc/fstab.initramfs
overlay /etc overlay lowerdir=/etc,upperdir=/overlay/etc,workdir=/overlay/workdir 0 0
# /etc/dracut.conf.d/99-fstab.conf
add_fstab+=" /etc/fstab.initramfs "
# /etc/dracut.conf.d/99-network-manager.conf
add_dracutmodules+=" network-manager "
kernel_cmdline="rd.neednet=1 ip=dhcp"
  • /root/.ssh/authorized_keys

Commands

# Install dracut-sshd repo
sudo curl \
    --output /etc/yum.repos.d/dracut-sshd.repo \
    --location "https://copr.fedorainfracloud.org/coprs/gsauthof/dracut-sshd/repo/fedora-$(rpm -E %fedora)/gsauthof-dracut-sshd-fedora-$(rpm -E %fedora).repo"
# Install dependencies
sudo rpm-ostree install --assumeyes --idempotent --apply-live dracut-sshd dracut-network
# https://github.com/gsauthof/dracut-sshd?tab=readme-ov-file#faq
sudo usermod -p '*' root
# Copy the ssh authorized_keys file to /etc/dracut-sshd
sudo install -vD -m 0600 -t /etc/dracut-sshd ~root/.ssh/authorized_keys
# Create an empty directory that will be copied to the initramfs
# This directory will be used by the Overlayfs as the workdir
sudo mkdir -p /etc/dracut.conf.d/overlay/workdir
# Regenerate the initramfs
sudo rpm-ostree initramfs --enable \
    --arg=--force \
    --arg=--include \
    --arg="/etc/hostname" \
    --arg="/overlay/etc/hostname" \
    --arg=--include \
    --arg="/etc/machine-id" \
    --arg="/overlay/etc/machine-id" \
    --arg=--include \
    --arg="/etc/dracut.conf.d/overlay/workdir" \
    --arg="/overlay/workdir"

Extra

This method could be used to do some other fun stuff, like add the systemd-udevd dracut hook script and some /etc/systemd/network/*.link to set the wake-on-LAN bit before the rootfs is decrypted. Which I do. That way, if the computer loses power before the partition is unlocked, wake-on-LAN will still work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions