Open ckcr4lyf opened 2 years ago
FYI: I currently have bypassed this by setting by env var
GIT_SSH_COMMAND="ssh -o ControlMaster=no"
as hinted by the source here -> https://github.com/golang/go/blob/master/src/cmd/go/internal/get/get.go#L156
I think it should at least be added to the docs (or just changelog) to make it easier
This change introduces in Go 1.17 seems like a nerf to security, since for SSH repos, it seems to force you to have an SSH key which is cached by ssh-agent.
The go
command intentionally disables password prompts because it fetches repositories in parallel — there isn't really a controlled way for you to see which repo is asking for your credential. (That is admittedly more of a concern when PasswordAuthentication
is enabled in your ssh
client configuration, but we still don't want to train users to get in the habit of entering passwords without a clear destination.)
The long-term solution for Yubikey authentication in particular might be to use the ssh ControlMaster
setting. You could establish the ssh
session prior to running the go
command, and then use that connection to fetch any needed repos, and finally tear it down again. Unfortunately, we also currently disable ControlMaster
for #13453 — but that may be feasible to fix a different way.
there isn't really a controlled way for you to see which repo is asking for your credential.
That's a great point. Since all the private repos I'm using are based on the same auth, the thought had never crossed my mind, but I can see where this change came from.
I think using the environment variable is a decent workaround for now, since it allows for using Yubikey SSH auth w/ Go 1.17
I did a bit more reading, and here's my suggestion (based on https://ldpreload.com/blog/ssh-control):
insteadOf
rule in ~/.gitconfig
as described in https://github.com/golang/go/issues/26134#issuecomment-403885803.
gitlab.com
is not a hard-coded hosting provider, that might not be necessary.)ControlPath ~/.ssh/control-%C
to your .ssh/config
file.ssh -M -N -f git@gitlab.com
. That should prompt you for Yubikey authentication to GitLab, then return you the shell prompt (leaving the SSH connection open in the background).go
command(s) you need to download the needed module contents.ssh -O exit git@gitlab.com
to terminate the open SSH connection.If you don't want to adjust your global .ssh/config
, you could instead do:
go
command:
export GIT_SSH_COMMAND='ssh -o ControlPath=~/.ssh/control-%C -o BatchMode=yes`
ssh -o ControlPath=~/.ssh/control-%C -M -N -f git@gitlab.com
to prompt for authentication.go
command(s) you need to download the needed module contents.ssh -o ControlPath=~/.ssh/control-%C -O exit git@gitlab.com
to terminate the open SSH connection.If you don't want to leave a connection open in the background indefinitely if you forget step (5), you could omit the -f
flag to the ssh
command and instead set the ControlPersist
option to a reasonably short timeout.
Or:
ssh -M -N git@gitlab.com
.go
command(s) you need to download the needed module contents.ssh
command from step (4), press ⌃C
to terminate the open session.@ckcr4lyf, please give the above a try and let me know if it works. (If so, perhaps I can add some more formal documentation on this configuration.)
@bcmills , thanks so much for the response. I can confirm it works perfectly!
I tested it with the latter option of a "temporary setup", and was able to fetch multiple private repos (for the same SSH auth) with no issues (including prompts). I tried the "permanent" solution w/ SSH config, and that also works great!
I believe this is a viable solution, since it allows for secure SSH-auth (e.g. via Yubikey + pin) explicitly, which can further be terminated once the go operations are complete.
Cheers, and thanks for the help (not sure if I should close the issue or not)
Thanks for confirming! I'll leave this issue open for documentation — we certainly do want to support private repos that require two-factor authentication, and this setup and workflow is not trivial to figure out.
FYI: I currently have bypassed this by setting by env var
GIT_SSH_COMMAND="ssh -o ControlMaster=no"
as hinted by the source here -> https://github.com/golang/go/blob/master/src/cmd/go/internal/get/get.go#L156
I think it should at least be added to the docs (or just changelog) to make it easier
here is a permalink to that line so it doesn't get lost when that file gets updated
@matloob, @samthanawalla: this issue should be a pretty straightforward writeup of the options discussed in https://github.com/golang/go/issues/49515#issuecomment-969247066.
From the changelog of Go 1.17, I see:
I use private repos with SSH and have correctly set up my
.netrc
and all. I use a yubikey with PIN for SSH authentication.Go 1.16 behavior
I try and get a lib / run
go mod vendor
, the git client will prompt me for my yubikey PIN in order to authenticate with the remote server, once I enter it correctly, it all works well. (EDIT: Probably the SSH client which git calls, but either way, it worked fine)Note: There are multiple prompts, I enter my pin for each one.
Go 1.17 behavior
I try and run go mod vendor or something, and it will fail with this:
I am 99% sure this is due to the change in Go 1.17 to disable "password prompts", since if I revert to Go 1.16 all works as expected.
I am able to use my Yubikey w/ PIN prompt for Git and other SSH stuff just fine. The changelog suggests using an ssh-agent for password-protected keys, but in my case, the key resides on my Yubikey, and I need to enter the pin in order to perform cryptographic operations with it. Since the key is not accessible, I cannot cache it within SSH agent. (Additionally, I do not want to cache my yubikey pin).
This change introduces in Go 1.17 seems like a nerf to security, since for SSH repos, it seems to force you to have an SSH key which is cached by ssh-agent.
If there is no way to disable this with a flag on my end or something, I think it should be reverted for Go 1.18, as @bcmills suggested it is being "given a try" in Go 1.17 - https://github.com/golang/go/issues/44904#issuecomment-830978943