nix icon indicating copy to clipboard operation
nix copied to clipboard

Nix multi-user installer fails on Fedora Rawhide due to SELinux denial

Open outergod opened this issue 6 years ago • 54 comments

I have just come across this trying to install Nix on Fedora 28 Workstation with SELinux enabled (default) using the ./install-multi-user script from the nix-2.0.4-x86_64-linux bundle.

---- sudo execution ------------------------------------------------------------
I am executing:

    $ sudo systemctl link /nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.service                                                                                

to set up the nix-daemon service

Failed to link unit: Access denied

I can confirm this is an SELinux denial due to this AVC message in /var/log/audit/audit.log:

type=AVC msg=audit(1535267537.912:2983): avc:  denied  { read } for  pid=1 comm="systemd" name="default" dev="nvme0n1p7" ino=2095622 scontext=system_u:system_r:init_t:s0 tcontext=unconfined_u:object_r:default_t:s0 tclass=lnk_file permissive=0 

This issue seems to be the same as the one discussed in #nixos-dev.

Based on the nature of the error, I would naturally assume all SELinux-enabled systems would be affected by this.

outergod avatar Aug 26 '18 07:08 outergod

Yeah, probably the installer should bail out if SELinux is enforcing (at least for now).

dezgeg avatar Aug 27 '18 11:08 dezgeg

This bug is especially important now, the default installer as of 2.1 will detect systemd and default to the multi-user installer. See the attached PDF for a demonstration of the problem. (caution: big) report-d-2.pdf

grahamc avatar Aug 31 '18 01:08 grahamc

Adding this logic:

        if /usr/sbin/sestatus && /usr/sbin/sestatus 2>&1 | grep -q enforcing; then
            echo "punting to no-daemon"
                curl "${installUrl}" | sh -s -- --no-daemon
        else 
                  curl "${installUrl}" | sh
        fi

worked in the test harness, but the following did not:

        if sestatus && sestatus 2>&1 | grep -q enforcing; then
            echo "punting to no-daemon"
                curl "${installUrl}" | sh -s -- --no-daemon
        else 
                  curl "${installUrl}" | sh
        fi

because the install script, when run over SSH, doesn't have /usr/sbin in the PATH.

I'm not sure the nicest way to do this, but we could try adding a few directories to the PATH (/sbin, /usr/sbin, others ...?) just for this check.

Another option is we do a naive check for sestatus and assume it is in the PATH and leave it up to the users to handle it otherwise.

Any ideas / recommendations?

grahamc avatar Aug 31 '18 01:08 grahamc

The getenforce command should be better for scripting.

Perhaps:

getenforce=$(PATH=$PATH:/sbin:/usr/sbin command -v getenforce)
if [ -n "$getenforce" ] && [ "$($getenforce)" = Enforcing ]; then
    echo "No multi-user for you, sorry"
fi

dezgeg avatar Aug 31 '18 15:08 dezgeg

Sorry for the stupid question, but why not just set proper SELinux file contexts for everything in /nix and restorecon those contexts on installation as well as after manipulating the store? I could just get a service in /nix/store to run using my system's systemd after executing

semanage fcontext -a -t bin_t '/nix/store/[^/]+/bin(/.*)?' 
semanage fcontext -a -t lib_t '/nix/store/[^/]+/lib(/.*)?' 
restorecon -R /nix/store

This is also akin to the default file contexts for /opt:

/opt/(.*/)?bin(/.*)?	system_u:object_r:bin_t:s0
/opt/(.*/)?lib(/.*)?	system_u:object_r:lib_t:s0
/opt/(.*/)?man(/.*)?	system_u:object_r:man_t:s0
(etc)

This could be easily integrated into the installation, and later more ideally with Nix in general and nix-store in particular.

Edit: After setting the profile symlinks in /nix/var/nix/profiles/ to usr_t, I was also able to run a service pointing to a profile directory because now systemd happily follows the symlinks, and it's easily arguable that user environments correspond to /usr.

outergod avatar Sep 01 '18 08:09 outergod

Because I personally don't know anything about writing SELinux rules for Fedora (nor CentOS for that matter.

Don't you also need something to allow systemd to use socket activation for the Nix daemon? At least I ran into similar issue to https://github.com/ganto/copr-lxd/issues/12.

dezgeg avatar Sep 01 '18 10:09 dezgeg

Since I need to be able to run Nix based services, I will try my best to provide patches for the installer and possibly nix-store to integrate with SELinux properly.

outergod avatar Sep 01 '18 12:09 outergod

Yes, that sounds good. I think we still need some quick solution for Nix 2.1.

dezgeg avatar Sep 01 '18 14:09 dezgeg

Newly filed, related issue: https://github.com/systemd/systemd/issues/9997

outergod avatar Sep 03 '18 08:09 outergod

@dezgeg you might want to check out https://github.com/e-user/nix/commit/2d53311c90a195ba7674f09605eb74124adfbff0, which depends on https://github.com/NixOS/nixpkgs/pull/46028 to be built. You could easily argue the policy belongs directly into nixpkgs because it provides value beyond the installation on non-NixOS systems. But as a first step, this should solve the issue of running Nix in multi-user mode in SELinux-enabled systems, but will not work once Nix is updated after installation - that could be fixed as a second step but requires some discussion as to how file contexts are preserved/restored when writing out derivations into the store:

  1. SELinux file contexts can be baked directly into all derivations - which would make SELinux an integral part of Nix and might not be desired but requires no further changes to nix-store.
  2. nix-store could be compiled with optional, direct SELinux support and write out file labels according to current, active policies. This is what systemd does when e.g. creating listening sockets.
  3. nix-env and nix-store could should invoke restorecon after operating on profiles and the store, respectively - it's cheap and requires no deep, further modifications to any other tool.

outergod avatar Sep 04 '18 10:09 outergod

If anyone wants this issue fixed as much as I do, please help me test #2670.

outergod avatar Feb 15 '19 16:02 outergod

I marked this as stale due to inactivity. → More info

stale[bot] avatar Feb 21 '21 15:02 stale[bot]

This is still happening, I have the same output when installing nix as the initial comment.

sonirico avatar May 13 '21 12:05 sonirico

I marked this as stale due to inactivity. → More info

stale[bot] avatar Nov 16 '21 11:11 stale[bot]

Bad stale bot.

This is obviously still not fixed.

teohhanhui avatar Nov 18 '21 03:11 teohhanhui

I feel like I should point out here that the point of the stale bot is not to care about whether or not something is fixed, but to make a guesstimate that something will not be fixed because no one has bothered to fix it till now. To put the issue to rest either way, perhaps a maintainer would be so kind as to close this issue as 'wontfix' and make a note that Nix doesn't support Fedora or other SELinux distros.

yawaramin avatar Nov 20 '21 02:11 yawaramin

I think I'm hitting this, too.

Fedora 34 Workstation (KDE Plasma Spin).

Tried a multi-user install with sh <(curl -L https://nixos.org/nix/install) --daemon and got (snipped for brevity):

---- sudo execution ------------------------------------------------------------
I am executing:

    $ sudo systemctl link /nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.service

to set up the nix-daemon service

Failed to link unit: Access denied

---- oh no! --------------------------------------------------------------------
Jeeze, something went wrong. If you can take all the output and open
an issue, we'd love to fix the problem so nobody else has this issue.

:(

We'd love to help if you need it.

You can open an issue at https://github.com/nixos/nix/issues

Or feel free to contact the team:
 - Matrix: #nix:nixos.org
 - IRC: in #nixos on irc.libera.chat
 - twitter: @nixos_org
 - forum: https://discourse.nixos.org

Since this issue has been open for 3.5 years, I'm assuming this isn't likely to get fixed anytime soon.

If it's not going to get a proper fix, it would be nice if the multi-user install would at least check for SELinux at the top and bail before starting to make changes on the system.

I'm also open to suggestions on the best way to back out this partial install I have now.

EDIT: I apologize for the grumpy tone. I'm tired and out of time to fiddle with this anymore tonight. I was excited to give Nix a try, but my initial experience was... probably not what any of us would have hoped for.

Anyway, any help or suggestions are appreciated.

EDIT 2: I went back through the install output (which seems to be very thorough) and manually un-did everything the install script reported doing, so I've probably fixed my system/cleaned up the partial Nix install.

So at this point, just consider this post a request that the Nix multi-user install either:

  1. Be improved to work under SELinux; or, failing that, at least
  2. Check for SELinux at the beginning of the install and abort gracefully before making any changes if SELinux is in place.

cgoetzke avatar Dec 17 '21 01:12 cgoetzke

Can confirm with Fedora 35.

Snippet:

---- sudo execution ------------------------------------------------------------
I am executing:

    $ sudo systemctl link /nix/var/nix/profiles/default/lib/systemd/system/nix-daemon.service

to set up the nix-daemon service

Failed to link unit: Access denied

---- oh no! --------------------------------------------------------------------

full output

My declarative adventure has been put on hold, it seems.

ryleu avatar Jan 11 '22 03:01 ryleu

Any workaround for Fedora users?

emlautarom1 avatar Jan 15 '22 20:01 emlautarom1

I'm facing the same issue on CentOS Stream 9

 $ uname -a
Linux <hostname> 5.14.0-47.el9.x86_64 #1 SMP PREEMPT Sat Jan 22 02:21:23 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux

 $ cat /etc/centos-release
CentOS Stream release 9

eoghanlawless avatar Feb 02 '22 10:02 eoghanlawless

It seems that this will not be fixed, considering that it’s 3 years old. I’ll just have to find another declarative package manager, I suppose.

ryleu avatar Feb 09 '22 00:02 ryleu

So, this just failed for me on Fedora 35 as well. Since the issue has been known for so long, I'm surprised that there isn't at least an early-out check in the installer, because now it has done a lot of things on my system, which I have no idea how to undo. :-(

Also a warning could be added to the installation instructions about this problem.

This message from the install script prompted me to go here, but it leaves me a bit speechless finding this old issue:

Jeeze, something went wrong. If you can take all the output and open
an issue, we'd love to fix the problem so nobody else has this issue.

How many people still need to run into this and are left with a half-finished Nix install on their system?

bjorn avatar Mar 01 '22 12:03 bjorn

At least three. I’m incredibly annoyed that it didn’t at least check before doing a ton on random stuff to my computer that may leave it in an insecure state, for all I know.

ryleu avatar Mar 01 '22 13:03 ryleu

Same issue here with Fedora 35. Many years later and not even a workaround has been provided.

I understand they must be swamped with so many github issues, but not properly documenting this is going to cost them so many more issues being submitted

kiteloopdesign avatar Mar 13 '22 17:03 kiteloopdesign

I was able to get Nix on Fedora Silverblue installed by using these workarounds.

https://gist.github.com/matthewpi/08c3d652e7879e4c4c30bead7021ff73#file-readme-md

matthewpi avatar Mar 13 '22 18:03 matthewpi

Ran into the same issue on Fedora 35. Install script failed halfway through due to SELinux. For now, you either have to permanently disable SELinux or write your own SELinux rules. I'm opting to turn off SELinux permanently, but do so at your own risk. There are security implications.

Turn off SELinux: https://tecadmin.net/how-to-disable-selinux-on-fedora/

Here are the commands I ran to clean up the installation enough to reinstall:

sudo rm /etc/bashrc
sudo mv /etc/bashrc.backup-before-nix /etc/bashrc
sudo rm -r /nix
sudo systemctl disable nix-daemon

The systemctl disable might not be necessary, I just had to do that because I tried to enable and start the service before realizing there was way more unfinished business left in the installation process.

stelcodes avatar Mar 16 '22 04:03 stelcodes

After this, rerun the installation script and it should work.

@stelcodes So you mean, if no cleanup is necessary, the only thing to make the install work is running sudo setenforce 0 beforehand? Is this change temporary? If not, should or can it be re-enabled after installation? Or would the more specific permission changes by @matthewpi be preferred?

bjorn avatar Mar 16 '22 07:03 bjorn

@bjorn Sorry for the confusion, I just edited my comment to make it more clear. I'm deciding to turn off SELinux permanently. The more specific permission changes should definitely be preferred, and I will try that in the future. If you're disabling SELinux, I would highly recommend locking down your ports with a firewall like firewalld or ufw.

stelcodes avatar Mar 16 '22 16:03 stelcodes

The solution is to create SELinux policies, but the ability to do so is an exceptionally rare skill. I am learning how to do so, but it may take me multiple months. I'll send them over once they're ready. From there, the devs can work on getting it merged into distros that use SELinux.

ryleu avatar Apr 10 '22 02:04 ryleu

I have created an alternate set of installers using distribution native packaging formats over https://nix-community.github.io/nix-installers/. Currently supported distributions are rpm-based, deb-based and pacman-based. All of these come with selinux policies and it's been tested on Fedora along with Ubuntu & Arch.

I hope that after more testing & polishing this can become our default recommended installation method for the supported distributions.

Please note that this doesn't work for rpm-ostree distros such as Fedora Silverblue, but it works for regular Fedora.

adisbladis avatar Apr 20 '22 09:04 adisbladis