Describe the bug
From man configuration.nix:
networking.hostName
The name of the machine. Leave it empty if you want to obtain it from a DHCP server (if using DHCP).
So having empty hostname is supposed to work.
However, this happens when setting networking.hostName = "" and booting on a network where the DHCP server passes the hostname "clientA" to the NixOS machine:
localhost NetworkManager[928]: <warn> [1575302169.8262] hostname: couldn't set the system hostname to 'clientA' using hostnamed: GDBus.Error:org.freedesktop.DBus.Error.NotSupported: Changing system settings via systemd is not supported on NixOS.
localhost NetworkManager[928]: <warn> [1575302169.8263] policy: set-hostname: couldn't set the system hostname to 'clientA': (1) Operation not permitted
localhost NetworkManager[928]: <warn> [1575302169.8263] policy: set-hostname: you should use hostnamed when systemd hardening is in effect!
To Reproduce
Steps to reproduce the behavior:
networking.hostName = ""Expected behavior
I expect the hostname given by the DHCP server to be set as a "transient hostname". https://www.freedesktop.org/software/systemd/man/hostnamectl.html.
Additional context
I'm runnign GNOME3 with NetworkManager. Perhaps non-NetworkManager setups work?
Metadata
NixOS 19.09.
This is because of GDBus.Error:org.freedesktop.DBus.Error.NotSupported: Changing system settings via systemd is not supported on NixOS., networkmanager probably uses systemd for this and it's patched out in our fork.
Perhaps we can update that patch to allow setting the _transient_ hostname only?
Simpler reproduce steps:
$ hostnamectl --transient set-hostname foobar
Could not set property: Changing system settings via systemd is not supported on NixOS.
That sounds like it should be at least allowed. We should move this issue to the systemd nixos repo.
(or at least open an issue there).
I cannot create issue in https://github.com/NixOS/systemd. Either issues are disabled or I don't have rights. (It seems I can create a pull though.)
@Mic92 ^
I don't have the power to enable issues up there, but I also don't, we really need a second issue tracker. It might just create confusion, where to open issues and people have to look in two places.
Thank you for your contributions.
This has been automatically marked as stale because it has had no activity for 180 days.
If this is still important to you, we ask that you leave a comment below. Your comment can be as simple as "still important to me". This lets people see that at least one person still cares about this. Someone will have to do this at most twice a year if there is no other activity.
Here are suggestions that might help resolve this more quickly:
cc @NixOS/systemd
No need to create issues over there, nixpkgs uses vanilla systemd by now, and that behaviour is part of a downstream patch.
To add some additional information:
pkgs/os-specific/linux/systemd/0007-hostnamed-localed-timedated-disable-methods-that-cha.patch) that forbids setting the hostname via D-Bus (sd-bus).networking.hostName is empty (but this might be a bit difficult to implement and maintain, depending on how we implement it)Update after having a quick look at src/hostname/hostnamed.c (systemd): It would probably be best to allow org.freedesktop.hostname1.set-hostname and only deny org.freedesktop.hostname1.set-static-hostname. This would allow NetworkManager and other tools to change the transient hostname but the kernel hostname would only be updated if /etc/hostname isn't empty (i.e. networking.hostName should work as expected).
Additionally it might be nice if we could drop 0007-hostnamed-localed-timedated-disable-methods-that-cha.patch entirely and replace it with custom Polkit rules (I think that should be possible, but I know very little about Polkit). If that works we could also change the rules dynamically based on networking.hostName and without having to recompile systemd (or anything else).
Update: Denying via Polkit should work as expected:
org.freedesktop.hostname1.)-> I think using Polkit instead of the patch is the way to go
Being able to drop more of our patches sounds good, but can polkit be used to even disallow root to do these actions?
What happens on systems with polkit disabled?
can polkit be used to even disallow root to do these actions?
Idk, but probably not. I guess it's only intended to grant additional privileges (but it could be possible). But ideally no services should be running as root.
What happens on systems with polkit disabled?
This obviously has to be checked properly, but as long as it's implemented sane (I'd consider everything else as a critical security bug) it should obviously reject everything (of course limited to the Polkit authorization, not other mechanisms).
src/shared/bus-polkit.c seems to confirm this, but I wouldn't take it as proof as there are additional control-flow paths and I didn't check the whole function:
/* Treat no PK available as access denied */
if (sd_bus_error_has_name(e, SD_BUS_ERROR_SERVICE_UNKNOWN) ||
sd_bus_error_has_name(e, SD_BUS_ERROR_NAME_HAS_NO_OWNER))
return -EACCES;
Hmm, I think https://github.com/NixOS/nixpkgs/pull/26608 remove a similar restriction in our downstream patch, by just not creating that file via NixOS.
Looping in @lheckemann.
@flokli that also seems like a nice and easy fix. The implementation is here. This would be a viable alternative to using Polkit (though it might require a reboot after changing networking.hostName but I guess that wouldn't be a big problem).
cross-referencing for context: https://github.com/NixOS/nixpkgs/issues/80038
@primeos do you want to give this a try?
You should be able to test this without rebuilding the world, by just passing that other systemd via systemd.package.
@flokli I thought about it, but unfortunately I cannot easily test this currently due to some ongoing setup changes. Would be best if someone who uses NetworkManager could give it a shot (is anyone in this thread interested and has time?). If it would help I could create a PR, but testing is the actual work.
As for the implementation: I think it would be best to drop that part of our systemd patch entirely. I.e. always allow method_set_hostname (unconditionally) and only deny method_set_static_hostname. Then depending on if networking.hostName is empty or not it should only allow to set the transient hostname (vs. additionally the static hostname).
From man hostnamectl:
This tool distinguishes three different hostnames: the high-level "pretty"
hostname which might include all kinds of special characters (e.g. "Lennart's
Laptop"), the static hostname which is used to initialize the kernel hostname at
boot (e.g. "lennarts-laptop"), and the transient hostname which is a fallback
value received from network configuration. If a static hostname is set, and is
valid (something other than localhost), then the transient hostname is not used.
Happy to give this a spin, once there's a PR open :+1:
@flokli ok, I've opened #91232 ;) I've also had time to quickly test this manually, but not with NetworkManager.
Thanks for fixing this!