KEMBAR78
nixos/systemd: Support setting machineId by nicoonoclaste · Pull Request #268995 · NixOS/nixpkgs · GitHub
Skip to content

Conversation

nicoonoclaste
Copy link
Contributor

Description of changes

  • Add new systemd.machineId configuration option.
    In principle, machine-id(5) can be an arbitrary, 128b string in hex-encoding; however, systemd v30 onwards (2011) generate UUIDv4 values, and various tools may rely on that.

  • Set the machine-id through boot.kernelParams.

Things done

  • Built on platform(s)
    • x86_64-linux
    • aarch64-linux
  • Tested, as applicable:
    • Didn't write a NixOS test for this 😅
  • Tested basic functionality
  • 23.11 Release Notes (or backporting 23.05 Release notes)
    • (Module updates) Added a release notes entry if the change is significant
  • Fits CONTRIBUTING.md.

Priorities

Add a 👍 reaction to pull requests you find important.

@nicoonoclaste nicoonoclaste requested a review from a team as a code owner November 21, 2023 16:42
@github-actions github-actions bot added 6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/` labels Nov 21, 2023
@aanderse
Copy link
Member

i'm trying to understand the implications of this statement from the documentation you linked:

This ID uniquely identifies the host. It should be considered "confidential", and must not be exposed in untrusted environments, in particular on the network.

do you know the details on that?

@flokli
Copy link
Contributor

flokli commented Nov 21, 2023

Quoting more from the manpage:

The machine ID is usually generated from a random source during system installation or first boot and stays constant for all subsequent boots. Optionally, for stateless systems, it is generated during runtime during early boot if necessary.

We should make sure systemd is able to write to this during installation / first boot, but putting it into NixOS configuration sounds wrong.

For the special usecases where it's desired to set this via kernel cmdline, we already have the cmdline config option, but I wouldn't encourage further to set this.

@nicoonoclaste
Copy link
Contributor Author

This ID uniquely identifies the host. It should be considered "confidential", and must not be exposed in untrusted environments, in particular on the network.

do you know the details on that?

I'm not aware of anything in systemd itself which relies on machine-id being secret (and I've looked for such a thing before).

Theoretically, putting machine-id in the kernel's cmdline is more exposure than the current situation (with /etc/machine-id on the FS) and I'll happily rewrite this to use environment.etc if that's preferred. The reason I set it through cmdline in the first place was so distinct machines with otherwise-identical config share more drvs (which is somewhat helpful in network-boot contexts etc.)

The machine ID is usually generated from a random source during system installation or first boot and stays constant for all subsequent boots. Optionally, for stateless systems, it is generated during runtime during early boot if necessary.

We should make sure systemd is able to write to this during installation / first boot, but putting it into NixOS configuration sounds wrong.

For the special usecases where it's desired to set this via kernel cmdline, we already have the cmdline config option, but I wouldn't encourage further to set this.

Are “impermanent” / root-on-tmpfs systems such a special usecase? I made the PR because someone asked me to upstream that option (which I wrote in my config monorepo some years ago) and it seems to be a common pitfall for impermanent systems.

It causes unexpected behavior with the journal, among other things: every boot gets a different machine-id so journalctl does not show previous boots by default, etc.

@nicoonoclaste nicoonoclaste force-pushed the nixos/systemd/machineId branch from 5a2eaa8 to 6542d06 Compare November 21, 2023 19:26
This is quite useful for “impermanent” (root-on-tmpfs) configurations.
@nicoonoclaste nicoonoclaste force-pushed the nixos/systemd/machineId branch from 6542d06 to 9ac50e1 Compare November 21, 2023 19:30
@flokli
Copy link
Contributor

flokli commented Nov 21, 2023

I set it through cmdline in the first place was so distinct machines with otherwise-identical config share more drvs (which is somewhat helpful in network-boot contexts etc.)

In the netboot scenario, can't you set / extend the kernel cmdline independently of the system closure?

That's what I used to do, in cases where I wanted to pass along the ipxe machine UUID to systemd. Similar things were also suggested to people asking for this to be added into CoreOS:
coreos/bugs#2166

Are “impermanent” / root-on-tmpfs systems such a special usecase?

If you don't want to have a new machine UUID on such systems, simply exclude this file from being wiped on every reboot.

Having a static value part of your system config is only a big footgun, having two machines with the same UUID. I don't think we should introduce this as a config option.

@nicoonoclaste
Copy link
Contributor Author

I set it through cmdline in the first place was so distinct machines with otherwise-identical config share more drvs (which is somewhat helpful in network-boot contexts etc.)

In the netboot scenario, can't you set / extend the kernel cmdline independently of the system closure?

Yes, there are other options too in the netboot scenario specifically.

Having a static value part of your system config is only a big footgun, having two machines with the same UUID. I don't think we should introduce this as a config option.

I don't see how it's more of a footgun than the plethora of extent options for setting a MAC address (worse, those have the potential for breaking the entire LAN the devices sit on) but I won't insist either; close as “won't fix” if the maintainers do not wish to provide such an option.

Comment on lines +642 to +645
boot.kernelParams = lib.foldr (a: b: a ++ b) [] [
(optional (cfg.machineId != null) "systemd.machine_id=${cfg.machineId}")
(optional (!cfg.enableUnifiedCgroupHierarchy) "systemd.unified_cgroup_hierarchy=0")
];
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick. My brain and nix processes this code much faster (also less parentheses):

Suggested change
boot.kernelParams = lib.foldr (a: b: a ++ b) [] [
(optional (cfg.machineId != null) "systemd.machine_id=${cfg.machineId}")
(optional (!cfg.enableUnifiedCgroupHierarchy) "systemd.unified_cgroup_hierarchy=0")
];
boot.kernelParams = optional (cfg.machineId != null) "systemd.machine_id=${cfg.machineId}"
++ optional (!cfg.enableUnifiedCgroupHierarchy) "systemd.unified_cgroup_hierarchy=0";

Copy link
Contributor

@flokli flokli left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Having a static value part of your system config is only a big footgun, having two machines with the same UUID. I don't think we should introduce this as a config option.

I don't see how it's more of a footgun than the plethora of extent options for setting a MAC address (worse, those have the potential for breaking the entire LAN the devices sit on) but I won't insist either; close as “won't fix” if the maintainers do not wish to provide such an option.

The machine-id is even more considered state:

The machine ID is usually generated from a random source during system installation or first boot and stays constant for all subsequent boots.

Pease pass it in externally where you have to keep it static across reboots, but can't keep state that state on the machine (for example netboot scenarios by appending via kernel cmdline), use it as state wherever you can (impermanence setups), and only resort to setting the kernel cmdline via NixOS options where you can't do otherwise. I don't think there should be a NixOS config option for this.

@arianvp
Copy link
Member

arianvp commented Nov 22, 2023

I'm also not a big fan of this change.

https://systemd.io/BUILDING_IMAGES/ also recommends people not setting machine-id when building images.

Also there are multiple ways for people to set this. (kernel command line vs environment.etc). I think people should just use environment.etc or the kernel command line if they want to mess with this.

@flokli flokli closed this Nov 22, 2023
@RaitoBezarius
Copy link
Member

RaitoBezarius commented Nov 22, 2023

After speaking about @flokli on this,

@nbraud I would recommend the way forward is to document it in the NixOS manual about which situations may require to use a persistent machine-id you pass on the command line and to provide a simple snippet to do so.
More involved situations should probably have an out-of-tree NixOS module to perform the regex testing if needed.

@nicoonoclaste nicoonoclaste deleted the nixos/systemd/machineId branch November 22, 2023 12:28
@nicoonoclaste
Copy link
Contributor Author

document it in the NixOS manual about which situations may require to use a persistent machine-id you pass on the command line and to provide a simple snippet to do so.

@RaitoBezarius What part of the manual do you think this should go in?

@RaitoBezarius
Copy link
Member

document it in the NixOS manual about which situations may require to use a persistent machine-id you pass on the command line and to provide a simple snippet to do so.

@RaitoBezarius What part of the manual do you think this should go in?

This could go in https://nixos.org/manual/nixos/stable/#ch-running under its own section potentially.

nicoonoclaste added a commit to nicoonoclaste/nixpkgs that referenced this pull request Dec 12, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

6.topic: nixos Issues or PRs affecting NixOS modules, or package usability issues specific to NixOS 8.has: module (update) This PR changes an existing module in `nixos/`

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants