Follow up on #1923:
Currently using ssh urls for fetchgit results into:
Could not create directory '/var/empty/.ssh'.
Host key verification failed.
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
Could not create directory '/var/empty/.ssh'.
Host key verification failed.
Maybe fetchgit should grow an extra parameters?
(I guess the above output was from that short time period when git wrapped ssh? When using an ssh URL with fetchgit now I get error: cannot run ssh: No such file or directory
.)
+1 for having something like an sshPrivateKey = "/path/to/id_rsa"
argument to fetchgit. That would be nice supplement to fetchgitPrivate, which requires a ssh config file in NIX_PATH, which in turn points to the private key.
However, wouldn't this bring ssh as a hard dependency of fetchgit? Or can it be a "lazy" dependency, only pulled in if "sshPrivateKey" arg is provided?
Further, the private key must not be put in the nix store.
@domenkozar is this fixed?
No response, so close @zimbatm.
@Profpatsch this is still an issue. You can repro by running nix-build against https://gist.github.com/anonymous/fb9353cabf8dd9fecd28
I just ran into this issue. For other people who have this same issue, you can work around it by using HTTP auth (i.e. https://${username}:${password}@github.com/your-name/your-project.git
). The following link explains how to deal with two-factor authentication:
Needless to say, do not actually save your username
and password
in the Nix expression. Provide them on the command line via --arg
or something similar and use them to template the URL.
Okay, so I think this is basically solved by fetchgitPrivate
which uses the SSH_AUTH_SOCK
to reuse your SSH agent instead of passing in a specific private key. However, I'm also going to suggest two possible enhancements to the implementation of fetchgitPrivate
.
First, using a variation on the gist that @zimbatm linked to, I can successfully build the repository by replacing fetchgit
with fetchgitPrivate
(and fixing the sha256
field):
# default.nix
{ pkgs ? import <nixpkgs> {} }:
pkgs.buildRubyGem rec {
src = pkgs.fetchgitPrivate {
url = "[email protected]:flori/json.git";
rev = "80e8213ce940005a1c7314793d39a0c4cc786821";
sha256 = "0ki6a4vnccb86rmssbc5x3d067zvkhyi6y973068hz81q0rjqf8a";
};
gemName = "json";
version = "1.8.3";
sha256 = "1nsby6ry8l9xg3yw4adlhk2pnc7i0h0rznvcss4vk3v74qg0k8lc";
}
... and supplying the appropriate SSH config file and SSH_AUTH_SOCK
on the command line (since that is how fetchgitPrivate
is configured to work):
nix-build default.nix -I ssh-config-file=/path/to/.ssh/config -I ssh-auth-sock=$SSH_AUTH_SOCK
So that alone is probably enough to mark this issue closed, but I'd like to also suggest two improvements to fetchgitPrivate
to reduce the need to supply these parameters on the command line:
impureEnvVars
to automatically inherit the SSH_AUTH_SOCK
from the user's environmentnix
argumentThis would involve simplifying pkgs/build-support/fetchgit/private.nix
to this:
{ fetchgit, writeScript, openssh, stdenv }:
sshConfigFile: fetchGitArgs:
derivation ((fetchgit fetchGitArgs).drvAttrs // {
impureEnvVars = [ "SSH_AUTH_SOCK" ];
GIT_SSH = writeScript "fetchgit-ssh" ''
#! ${stdenv.shell}
exec -a ssh ${openssh}/bin/ssh -F ${sshConfigFile} "$@"
'';
})
... and then you'd just provide the ~/.ssh/config
file in nix
:
{ pkgs ? import <nixpkgs> {} }:
pkgs.buildRubyGem rec {
src = pkgs.fetchgitPrivate /path/to/.ssh/config {
url = "[email protected]:flori/json.git";
rev = "80e8213ce940005a1c7314793d39a0c4cc786821";
sha256 = "0ki6a4vnccb86rmssbc5x3d067zvkhyi6y973068hz81q0rjqf8a";
};
gemName = "json";
version = "1.8.3";
sha256 = "1nsby6ry8l9xg3yw4adlhk2pnc7i0h0rznvcss4vk3v74qg0k8lc";
}
... and now you can run the build command without any command line arguments:
$ nix-build default.nix
Would people be okay with that proposed change?
src = pkgs.fetchgitPrivate /path/to/.ssh/config {
You mean it鈥檚 okay if that鈥檚 an argument, since fetchgitPrivate
will only be used from private nix files?
I guess that鈥檚 nice.
let
myGit = fetchgitPrivate "${myuser.home}/.ssh";
myGithub = set: fetchFromGitHubPrivate "${myuser.home}/.ssh" ({ owner = "me"; } // set);
in
fetchFromGitHubPrivate
should exist, too. And maybe all other flavors of fetchFoo
.
Yeah, the .ssh/config
file can be made a private file if it contains any secrets, although it shouldn't need to. The impure SSH_AUTH_SOCK
environment variable forwarded from your environment actually does the authentication for you using your ambient ssh
agent. For example, in my case the .ssh/config
file was just empty so I could pass writeText "ssh-config" ""
if I wanted to.
Actually, I've come to the conclusion that the current behavior of fetchgitPrivate
is the ideal behavior and requires no modification
The thing that convinced me that the current behavior is the way to go was getting a package to work with hydra
. The only way to securely provision a secret to a hydra
build is via the Nix search path.
Also, the SSH_AUTH_SOCK
argument is not necessary (and won't even work in some cases like remote builds). Another approach is to provide an ssh-config-file
with an IdentityFile
line, such as this:
StrictHostKeyChecking No
UserKnownHostsFile /dev/null
IdentityFile /path/to/.ssh/id_rsa
... and then supply the path to that on the Nix path like this:
$ nix-build example.nix -I ssh-config-file=path/to/above/config
So the conclusion I came to is that this issue is solved by fetchgitPrivate
but could perhaps use better documentation on how to correctly use it in various circumstances (like local vs remote builds, hydra
, nixops
, etc.).
The only issue with fetchgitPrivate
is that tools like nix-prefetch-git don't make a distinction between private and public repos and then the packaging tools like npm2nix, bundix, ... also don't make the distinction. Is there a heuristic that could be used to make that distinction possible?
Actually, there seems to be an issue with this. If nix.useSandbox
(formerly known as nix.useChroot
) is set, ssh-config-file
won't be reachable from the build process, and building by will fail with something like Can't open user config file /path/to/ssh-config-file: No such file or directory
. As soon as nix.useSandbox
is disabled, everything work as @Gabriel439 described.
To make this work, I think that fetchgitPrivate
needs to take ssh-config-file
and ssh-auth-sock
as input parameters for overriding the current behavior. I'll try this now and submit a pull-request afterwards if it works.
@k0001 There is one reason that you might want to still preserve the old ability to provide ssh-config-file
via the NIX_PATH
which is that it's the only way that seems to reliably work with Hydra (since Hydra seems to only let you configure the NIX_PATH
when customizing an expression to build)
@Gabriel439 just so that we are on the same page: Are you using NixOps to deploy your Hydra instance? If so, how do you manage the deployment and permissions of the ssh-config-file
file specified through Hydra, as well as the deployment and permissions of the associated IdentityFile
?
@k0001 I don't use nixops
to deploy the Hydra instance. I just use nixos
directly
I may open another issue for this- but I am having a similar problem with fetchcvs
. Basically, ssh refuses to authenticate anoncvs without /var/empty/.ssh/known_hosts
. I wonder if anyone has any work arounds for this? (Currently all of the CVS stuff is fetched through pserver but that can be hit or miss).
This is resolved now (there is builtins.fetchGit
, fetch-git
, and fetchgitPrivate
that all support this).
@matthewbauer: I've opened #41814.
@yegortimoshenko actually it is still not clear to me how one could use ssh-config-file in a sandbox ("sandbox = true" in nix.conf).
Could @k0001, @Gabriel439 or anyone else comment if they have a working solution?
@jokogr You could pass it via NIX_PATH:
nix-build -I ssh-config-file=/path/to/ssh/config
Then you can refer to it in Nix expression as <ssh-config-file>
.
@yegortimoshenko: as @k0001 mentioned, /path/to/ssh/config
is inaccessible in a sandbox, i.e. I get an error like "No such file". Are you using a special path to override this?
You can specify additional paths available in sandbox via extra-sandbox-paths
in /etc/nix/nix.conf
or nix.sandboxPaths
NixOS option.
This is resolved now (there is builtins.fetchGit, fetch-git, and fetchgitPrivate that all support this).
@yegortimoshenko Did you mean that fetchGit
supports using the same ssh-config-file
and ssh-auth-sock
parameters on NIX_PATH
that is supported by fetchgitPrivate
? If so, what's the point of using fetchgitPrivate
then?
For posterity, I had no luck trying to pass 'ssh-config-file' to the Hydra jobset. Instead I moved the config file itself to its standard location for Hydra (/var/lib/hydra/.ssh/config
) and it got caught up fine.
Tip: you can more interactively test the evaluation by executing hydra-eval-jobset proj jobsetname
as the hydra
user. You can directly observe what happens over git/ssh then.
Most helpful comment
Okay, so I think this is basically solved by
fetchgitPrivate
which uses theSSH_AUTH_SOCK
to reuse your SSH agent instead of passing in a specific private key. However, I'm also going to suggest two possible enhancements to the implementation offetchgitPrivate
.First, using a variation on the gist that @zimbatm linked to, I can successfully build the repository by replacing
fetchgit
withfetchgitPrivate
(and fixing thesha256
field):... and supplying the appropriate SSH config file and
SSH_AUTH_SOCK
on the command line (since that is howfetchgitPrivate
is configured to work):So that alone is probably enough to mark this issue closed, but I'd like to also suggest two improvements to
fetchgitPrivate
to reduce the need to supply these parameters on the command line:impureEnvVars
to automatically inherit theSSH_AUTH_SOCK
from the user's environmentnix
argumentThis would involve simplifying
pkgs/build-support/fetchgit/private.nix
to this:... and then you'd just provide the
~/.ssh/config
file innix
:... and now you can run the build command without any command line arguments:
Would people be okay with that proposed change?