nix-community / home-manager

Manage a user environment using Nix [maintainer=@rycee]
https://nix-community.github.io/home-manager/
MIT License
6.29k stars 1.68k forks source link

Bad owner or permissions on ~/.ssh/config ssh error #322

Open alexvorobiev opened 5 years ago

alexvorobiev commented 5 years ago

The ~/.ssh/config symlink points to a file in nix store owned by admin user running nix-daemon (not root in my environment). Is it possible to come up with a workaround like create a file with different name then copy/chown/chmod it to what ssh would like?

rycee commented 5 years ago

Sorry about the delay! I'm not sure there is an ideal workaround. I think the most straight-forward would be to clone the repo and change https://github.com/rycee/home-manager/blob/99c900946dbbaf5ba1fd3b1c1fe83b18fb66c84e/modules/programs/ssh.nix#L259-L278 to instead read something like

    home.activation.copySshConfig =
      let
        cfgFile = pkgs.writeText "ssh-config" ''
          ${concatStringsSep "\n" (
            mapAttrsToList (n: v: "${n} ${v}") cfg.extraOptionOverrides)}

          ${concatStringsSep "\n\n" (
            map matchBlockStr (
            builtins.attrValues cfg.matchBlocks))}

          Host *
            ForwardAgent ${yn cfg.forwardAgent}
            Compression ${yn cfg.compression}
            ServerAliveInterval ${toString cfg.serverAliveInterval}
            HashKnownHosts ${yn cfg.hashKnownHosts}
            UserKnownHostsFile ${cfg.userKnownHostsFile}
            ControlMaster ${cfg.controlMaster}
            ControlPath ${cfg.controlPath}
            ControlPersist ${cfg.controlPersist}

            ${replaceStrings ["\n"] ["\n  "] cfg.extraConfig}
        '';
      in
        dagEntryAfter ["writeBoundary"] ''
          install -m600 -D ${cfgFile} $HOME/.ssh/config
        '';

This should copy the configuration file into place, unconditionally overwriting the existing $HOME/.ssh/config file.

Note, I haven't tested this so I might have missed some detail.

In any case, I hope some day to have a more elegant solution to this problem (and similar problems, like handling key files).

alexvorobiev commented 5 years ago

Thanks, that's exactly what I had in mind! I agree this approach would also be useful in other cases where more control over file permissions is desired. I was thinking that some kind of a collection to store all such file paths together with their permissions (and a corresponding function to create a file and add a tuple "source path/target path/permissions" to the collection) would be useful. Then there would be an extra step in the home-manager switch process to traverse this collection and call install -mXXX for each tuple.

league commented 4 years ago

Do either of you know what are the conditions under which ssh issues "bad owner or permissions"? I have my ~/.ssh/config in the nix store, managed by home-manager, and I never encountered this… until I tried to use git from within Android Studio (IntelliJ). I configured it to use the native git command-line instead of its built-in, and specified the path as /home/league/.nix-profile/bin/git, so I think it should behave the same in IntelliJ as on my terminal.

I wonder whether it's picking up a different ssh in IntelliJ vs. my terminal.

myme commented 4 years ago

I think the issue surfaces in FHS user envs. Android studio is running in one. I'm having the same issue when using ssh in a build environment for a project at $WORK.

stale[bot] commented 3 years ago

Thank you for your contribution! I marked this issue as stale due to inactivity. If this remains inactive for another 7 days, I will close this issue. Please read the relevant sections below before commenting.

If you are the original author of the issue

* If this is resolved, please consider closing it so that the maintainers know not to focus on this. * If this might still be an issue, but you are not interested in promoting its resolution, please consider closing it while encouraging others to take over and reopen an issue if they care enough. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

If you are not the original author of the issue

* If you are also experiencing this issue, please add details of your situation to help with the debugging process. * If you know how to solve the issue, please consider submitting a Pull Request that addresses this issue.

Memorandum on closing issues

If you have nothing of substance to add, please refrain from commenting and allow the bot close the issue. Also, don't be afraid to manually close an issue, even if it holds valuable information.

Closed issues stay in the system for people to search, read, cross-reference, or even reopen--nothing is lost! Closing obsolete issues is an important way to help maintainers focus their time and effort.

VergeDX commented 2 years ago

Same issues here, git push command cannot use in Android Studio : (

kokobd commented 1 year ago

In case someone else find this issue, another workaround without forking anything would be applying a patch to openssh, like this:

# In configuration.nix
  nixpkgs.overlays = [
    (final: prev: {
      openssh = prev.openssh.overrideAttrs (old: {
        patches = (old.patches or [ ]) ++ [ ./openssh.patch ];
        doCheck = false;
      });
    })
  ];

Patch file:

diff --git a/readconf.h b/readconf.h
index ded13c9..94f489e 100644
--- a/readconf.h
+++ b/readconf.h
@@ -203,7 +203,7 @@ typedef struct {
 #define SESSION_TYPE_SUBSYSTEM 1
 #define SESSION_TYPE_DEFAULT   2

-#define SSHCONF_CHECKPERM  1  /* check permissions on config file */
+#define SSHCONF_CHECKPERM  0  /* check permissions on config file */
 #define SSHCONF_USERCONF   2  /* user provided config file not system */
 #define SSHCONF_FINAL      4  /* Final pass over config, after canon. */
 #define SSHCONF_NEVERMATCH 8  /* Match/Host never matches; internal only */
Princemachiavelli commented 1 year ago

If this issue is effecting you, check the dereferenced owner and group e.g ls -Ll ~/.ssh/config. I have no issues if the symbolic link is owned by the user and user's group and the txt file itself in the Nix store is owned by root:root.

However, if the permissions on the actual Nix store file are incorrect then this error will occur. It's not obvious because many commands will only show the symlink's owner & group not the linked files. The permissions on the Nix store file can be changed if you are using a non-NixOS Nix multi-user setup where Nix store is writable by root. If you ever run a sudo chown baduser:badgroup ~/.ssh then the Nix store will have incorrect permissions.

You will probably only encounter this if many home-manager users share a common SSH config and therefore the symbolic link resolves to the same Nix store text file.

I'm not sure if a root RW nix store is correct for a Nix multi-user install but I checked a few different systems and all have a root RW store. With my home manager config, both the ssh and git commands are included in the home manager profile but I don't think the upstream Nix packages change this behavior.

MAHDTech commented 1 year ago

I've noticed this when using the vscode.fhs package. The integrated terminal receives the error.

ls -Ll ~/.ssh/config

-r--r--r-- 1 nobody nogroup 425 Jan  1  1970 /home/mahdtech/.ssh/config
ls -Ll ~/.ssh/config

-r--r--r-- 1 root root 425 Jan  1  1970 /home/mahdtech/.ssh/config

What is it about FHS environments that causes the change?

nixos-discourse commented 10 months ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nixos-home-manager-ssh-config-permissions/32056/2

nixos-discourse commented 10 months ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/nixos-home-manager-ssh-config-permissions/32056/3

Arahizzz commented 6 months ago

Another workaround if you don't want to mess with openssh (based on Stackoverflow answer).

home.file.".ssh/config" = {
  target = ".ssh/config_source";
  onChange = ''cat ~/.ssh/config_source > ~/.ssh/config && chmod 400 ~/.ssh/config'';
};
xhos commented 1 week ago

Any update on this? I can't figure out how to use the fix above when configuring ssh like this:

  programs.ssh = {
    enable = true;
    matchBlocks = {
      "somehost" = {
        host = "somehost";
        hostname = "somename";
        identityFile = [ "~/.ssh/somekey" ];
      };
    };
  };