NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.31k stars 13.54k forks source link

cifs-utils mount.cifs fails if using kerberos auth #34638

Open mlieberman85 opened 6 years ago

mlieberman85 commented 6 years ago

Issue description

mount.cifs with sec=krb5 fails with

mount.cifs -o sec=krb5,user=test,domain=TEST.EXAMPLE.COM //server.test.example.com/test /mount/ch
mount error(2): No such file or directory

Steps to reproduce

Have cifs-utils package installed and try to mount a share with krb5 or krb5i security option.

To temporarily fix it you can create a symlink from wherever request-key is to /sbin/request-key

Technical details

This is happening because the linux kernel hardcodes the request_key binary it uses to "/sbin/request-key":

See: https://github.com/torvalds/linux/blob/master/security/keys/request_key.c#L98

mlieberman85 commented 6 years ago

Looking through the kernel patches. I do have an idea of how to fix it, but request_key had a pretty big refactor between kernel versions and not sure what the best way is to upload the two patches for the above request_key.c and the older version that can be seen here: https://kernel.googlesource.com/pub/scm/linux/kernel/git/stable/linux-stable/+/linux-4.9.y/security/keys/request_key.c#164

copumpkin commented 6 years ago

Just pinging @bjornfor, @edolstra, and @wkennington as folks who seem to have touched the CIFS module.

It seems like our best bet here is either to patch the kernel to look for it elsewhere, or to somehow make sure /sbin/request-key appears at activation time.

bjornfor commented 6 years ago

Make /sbin a symlink to /run/current-system/sw/bin? Too controversial?

copumpkin commented 6 years ago

That's what we do locally and it works, but it feels pretty icky 😄 but then again, the whole idea of the kernel calling back out to userland for this is pretty icky.

It's also not clear to me how such a symlink should work w.r.t. cleanup. If you ever change your configuration, you're going to get a broken symlink into /run/current-system. I guess our activation script can make sure the target needs to be there and if not, clean up after itself?

juselius commented 5 years ago

I just tested (using the icky /sbin link) on 19.09pre189585.1412af4b2cf:

sudo mount -t cifs //itpfil/data /mnt -o user=$USER,cruid=$USER,sec=krb5
mount error(126): Required key not available

It turns out that ${keyutils}/etc/request-key.conf looks like this:

#OP     TYPE    DESCRIPTION     CALLOUT INFO    PROGRAM ARG1 ARG2 ARG3 ...
#====== ======= =============== =============== ===============================
create  dns_resolver *          *               /sbin/key.dns_resolver %k
create  user    debug:*         negate          /bin/keyctl negate %k 30 %S
create  user    debug:*         rejected        /bin/keyctl reject %k 30 %c %S
create  user    debug:*         expired         /bin/keyctl reject %k 30 %c %S
create  user    debug:*         revoked         /bin/keyctl reject %k 30 %c %S
create  user    debug:loop:*    *               |/bin/cat
create  user    debug:*         *               /usr/share/keyutils/request-key-debug.sh %k %d %c %S
negate  *       *               *               /bin/keyctl negate %k 30 %S

This doesn't look even remotely correct. Also, there is no configuration for cifs, e.g.:

create  cifs.spnego     *       * /sbin/cifs.upcall %k

I tried fixing the issues using an overlay for keyutils in configuration.nix, but you end up almost recompiling the whole system. I gave up after 2+ hours of compilation.

Shados commented 5 years ago

@juselius working config, no rebuilds required:

{ config, lib, pkgs, ... }:
{
    # Remove this once https://github.com/NixOS/nixpkgs/issues/34638 is resolved
    # The TL;DR is: the kernel calls out to the hard-coded path of
    # /sbin/request-key as part of its CIFS auth process, which of course does
    # not exist on NixOS due to the usage of Nix store paths.
    system.activationScripts.symlink-requestkey = ''
      if [ ! -d /sbin ]; then
        mkdir /sbin
      fi
      ln -sfn /run/current-system/sw/bin/request-key /sbin/request-key
    '';
    # request-key expects a configuration file under /etc
    environment.etc."request-key.conf" = {
      text = let
        upcall = "${pkgs.cifs-utils}/bin/cifs.upcall";
        keyctl = "${pkgs.keyutils}/bin/keyctl";
      in ''
        #OP     TYPE          DESCRIPTION  CALLOUT_INFO  PROGRAM
        # -t is required for DFS share servers...
        create  cifs.spnego   *            *             ${upcall} -t %k
        create  dns_resolver  *            *             ${upcall} %k
        # Everything below this point is essentially the default configuration,
        # modified minimally to work under NixOS. Notably, it provides debug
        # logging.
        create  user          debug:*      negate        ${keyctl} negate %k 30 %S
        create  user          debug:*      rejected      ${keyctl} reject %k 30 %c %S
        create  user          debug:*      expired       ${keyctl} reject %k 30 %c %S
        create  user          debug:*      revoked       ${keyctl} reject %k 30 %c %S
        create  user          debug:loop:* *             |${pkgs.coreutils}/bin/cat
        create  user          debug:*      *             ${pkgs.keyutils}/share/keyutils/request-key-debug.sh %k %d %c %S
        negate  *             *            *             ${keyctl} negate %k 30 %S
      '';
    };
    environment.systemPackages = with pkgs; [
      # Doesn't *need* to be in the system profile for this to work, but we
      # want it installed so that e.g. the man pages are available
      cifs-utils
      # This *does* need to be installed in the system profile, as we link to
      # it there in the symlink-requestkey activation script defined above
      keyutils
    ];
}
juselius commented 5 years ago

Thank you @Shados! Nice solution, it works!

I didn't think keytuils looked in /etc for request-key.conf, since it isn't installed there during installation. I still think the keyutils package is broken and should be fixed.

stale[bot] commented 4 years ago

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:

  1. Search for maintainers and people that previously touched the related code and @ mention them in a comment.
  2. Ask on the NixOS Discourse.
  3. Ask on the #nixos channel on irc.freenode.net.
chvp commented 4 years ago

Still important to me.

stale[bot] commented 3 years ago

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

fabianhauser commented 3 years ago

Still important to me.

stale[bot] commented 3 years ago

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

chvp commented 3 years ago

Still important to me.

arjan-s commented 2 years ago

I think this issue should be closed. The original issue is the hardcoded call to /sbin/request-key which has been fixed in PR https://github.com/NixOS/nixpkgs/pull/73989 in Dec 2019. Kerberos CIFS mounts work just fine when simply adding /etc/request-key.conf like in this comment by @Shados: https://github.com/NixOS/nixpkgs/issues/34638#issuecomment-524688091. However, adding /etc/request-key.conf to the keyutils package would be good in my opinion, so perhaps that should become the main point of this issue, or a new issue could be created.

marienz commented 9 months ago

Looks like request-key also looks at /etc/request-key.d/*, so packages like cifs-utils and/or modules can drop a file there (avoiding keyutils having to know the path to cifs.upcall). Looks like #73989 made the nfs module write /etc/request-key.conf: I think that should be a drop-in in /etc/request-key.conf.d so it can coexist with cifs.upcall more easily.

Does an approach like that sound reasonable? And does it seem better to do this in modules (similar to what the nfs module does) or in the relevant packages (keyutils, cifs-utils, nfs-utils)?

(I'd like to fix this as I just hit it via #265521. Looking at its source, request-key doesn't really do anything without configuration (it has no built-in actions, all calls to it will fail with "No matching action"). So especially with NixOS going to the trouble of patching the kernel so it can call request-key, also configuring request-key so it can do more than NFS would be nice.)

justinvson-pd commented 4 months ago

For me, smb mounts using cifs were broken until I added this line to /etc/request-key.conf:

create dns_resolver * * /run/current-system/sw/bin/key.dns_resolver %k

cifs mounts would just always fail with ENOKEY, mount error(126): Required key not available Refer to the mount.cifs(8) manual page (e.g. man mount.cifs) and kernel log messages (dmesg)

with the nfs module's addition already being there:

create id_resolver * * /nix/store/4mgp5ybsvnhh11082gf5gix22dq8xwnv-nfs-utils-2.6.2/bin/nfsidmap -t 600 %k %d