-
-
Notifications
You must be signed in to change notification settings - Fork 13.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
systemd confinement for services using systemd.packages (e.g. mpd) #157787
Comments
Hm, why not just put the confinement stuff in
Unfortunately, this would involve an IFD because we need to already know the runtime closure of the package(s) in hand. |
If we can do that it'd work, yes. I don't think we should worry about the "no foo.service" case, it doesn't make sense without Start/Stop/whatever directives anyway. |
I thought more about doing this: diff --git a/nixos/modules/security/systemd-confinement.nix b/nixos/modules/security/systemd-confinement.nix
index 0e3ec5af323..f3a2de3bf87 100644
--- a/nixos/modules/security/systemd-confinement.nix
+++ b/nixos/modules/security/systemd-confinement.nix
@@ -175,8 +175,8 @@ in {
serviceName = "${name}.service";
excludedPath = rootPaths;
} ''
- mkdir -p "$out/lib/systemd/system"
- serviceFile="$out/lib/systemd/system/$serviceName"
+ mkdir -p "$out/lib/systemd/system/$serviceName.d"
+ serviceFile="$out/lib/systemd/system/$serviceName.d/confinement.conf"
echo '[Service]' > "$serviceFile"
The tests still succeed with that change. Can you please check whether it works for your |
Oh, for some reason I was convinced systemd.packages would not preserve subdirectories. Just checked, it works:
I'll let you open a PR with that? thanks! |
Thanks for testing, PR |
In issue NixOS#157787 @martined wrote: Trying to use confinement on packages providing their systemd units with systemd.packages, for example mpd, fails with the following error: system-units> ln: failed to create symbolic link '/nix/store/...-system-units/mpd.service': File exists This is because systemd-confinement and mpd both provide a mpd.service file through systemd.packages. (mpd got updated that way recently to use upstream's service file) To address this, we now place the unit file containing the bind-mounted paths of the Nix closure into a drop-in directory instead of using the name of a unit file directly. This does come with the implication that the options set in the drop-in directory won't apply if the main unit file is missing. In practice however this should not happen for two reasons: * The systemd-confinement module already sets additional options via systemd.services and thus we should get a main unit file * In the unlikely event that we don't get a main unit file regardless of the previous point, the unit would be a no-op even if the options of the drop-in directory would apply Another thing to consider is the order in which those options are merged, since systemd loads the files from the drop-in directory in alphabetical order. So given that we have confinement.conf and overrides.conf, the confinement options are loaded before the NixOS overrides. Since we're only setting the BindReadOnlyPaths option, the order isn't that important since all those paths are merged anyway and we still don't lose the ability to reset the option since overrides.conf comes afterwards. Fixes: NixOS#157787 Signed-off-by: aszlig <aszlig@nix.build>
In issue #157787 @martined wrote: Trying to use confinement on packages providing their systemd units with systemd.packages, for example mpd, fails with the following error: system-units> ln: failed to create symbolic link '/nix/store/...-system-units/mpd.service': File exists This is because systemd-confinement and mpd both provide a mpd.service file through systemd.packages. (mpd got updated that way recently to use upstream's service file) To address this, we now place the unit file containing the bind-mounted paths of the Nix closure into a drop-in directory instead of using the name of a unit file directly. This does come with the implication that the options set in the drop-in directory won't apply if the main unit file is missing. In practice however this should not happen for two reasons: * The systemd-confinement module already sets additional options via systemd.services and thus we should get a main unit file * In the unlikely event that we don't get a main unit file regardless of the previous point, the unit would be a no-op even if the options of the drop-in directory would apply Another thing to consider is the order in which those options are merged, since systemd loads the files from the drop-in directory in alphabetical order. So given that we have confinement.conf and overrides.conf, the confinement options are loaded before the NixOS overrides. Since we're only setting the BindReadOnlyPaths option, the order isn't that important since all those paths are merged anyway and we still don't lose the ability to reset the option since overrides.conf comes afterwards. Fixes: #157787 Signed-off-by: aszlig <aszlig@nix.build>
Describe the bug
Trying to use confinement on packages providing their systemd units with systemd.packages, for example mpd, fails with the following error:
This is because systemd-confinement and mpd both provide a mpd.service file through
systemd.packages
. (mpd got updated that way recently to use upstream's service file)Steps To Reproduce
Steps to reproduce the behavior:
systemd.services.mpd.confinement.enable = true;
on nixpkgs >= 746e627 (Jan 11)Expected behavior
Should work regardless of original service? Or at least try to.
Additional context
Using upstream service directly is a bit annoying with confinement, as we can't inspect it to check for e.g. ProtectSystem or other incompatible options, but it should be possible to just mash all the files together as overrides.
In
nixos/lib/systemd-lib.nix
for systemd.units units we check if the original unit exists and if so install the unit as foo.d/override.conf, a similar check could be added to install overlapping units from systemd.packages as override as well.Note care would need to be taken about the override name, because in this case we'd get 2 overrides, so the overrides will also need different names, so this is not trivial.
Alternatively, the confinement code could try to generate the list of bind paths not as a separate unit file but as a list to fill in
systemd.services.<servicename>.serviceConfig.Bind(ReadOnly)Paths
directly; that would avoid one level of collision and solve the issue at hand. there's quite a few readink calls involved so I'm not sure if that's possible however...Notify maintainers
@aszlig (for confinement) -- letting you pull in more people if you'd like.
The text was updated successfully, but these errors were encountered: