Skip to content

feat: Add SSH agent forwarding support to coder agent #1548

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 11 commits into from
May 25, 2022

Conversation

mafredri
Copy link
Member

@mafredri mafredri commented May 18, 2022

This PR adds support for SSH agent forwarding.

This simple change can support SSH agent forwarding but requires extra steps:

As Kyle pointed out, this works fine with the coder gitssh command so the extra steps are not necessary, we only need to make sure the ssh ForwardAgent setting is enabled:

coder config-ssh
ssh -o ForwardAgent=yes coder.mydev
# Inside workspace:
git clone git@github.com:private/repo.git

Checklist

  • Add basic forward agent support
  • Add support for using the forwarded agent to GIT_SSH_COMMAND (i.e. coder gitssh)?
  • Add forward agent support to coder ssh too

Fixes #1549.

@mafredri mafredri self-assigned this May 18, 2022
@mafredri
Copy link
Member Author

Wanted this to be DRAFT PR, can't seem to convert it after the fact.

@kylecarbs
Copy link
Member

I'm surprised it doesn't just work with gitssh. Since we're setting the SSH_AUTH_SOCK, I assumed it'd get passed through to the ssh command gitssh executes.

@mafredri
Copy link
Member Author

I'm surprised it doesn't just work with gitssh. Since we're setting the SSH_AUTH_SOCK, I assumed it'd get passed through to the ssh command gitssh executes.

Oh you're absolutely right, silly me, I did not look closely at what the actual error output was.

run ssh command: exec: "ssh": executable file not found in $PATH

So yeah, with ssh installed it works perfectly! 😄

@kylecarbs
Copy link
Member

Ahh, nice! Forwarding with coder ssh should just be forwarding SSH_AUTH_SOCK if any is set:

https://pkg.go.dev/golang.org/x/crypto/ssh/agent#ForwardToRemote

@mafredri mafredri force-pushed the mafredri/ssh-agent-forwarding branch from c0a7d75 to 3df1a08 Compare May 24, 2022 10:10
@mafredri mafredri requested review from kylecarbs and a team May 24, 2022 16:45
@mafredri
Copy link
Member Author

I believe this is now ready for review. SSH agent forwarding has now been implemented for both coder ssh and ssh.

For coder:

coder ssh --forward-agent <workspace>

For SSH:

coder config-ssh -o ForwardAgent=yes
# or
ssh -o ForwardAgent=yes coder.<workspace>

Thanks @kylecarbs for the pointers, this was surprisingly easy to setup.

@kylecarbs
Copy link
Member

@mafredri that'd be a good example for the usage of config-ssh!

cli/ssh.go Outdated
_ = cmd.Flags().MarkHidden("shuffle")
cliflag.BoolVarP(cmd.Flags(), &forwardAgent, "forward-agent", "", "CODER_SSH_FORWARD_AGENT", false, "Specifies whether to forward the SSH agent specified in $SSH_AUTH_SOCK")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The shorthand flag for this should be -A to match openssh

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A most excellent suggestion, thanks!

cli/ssh_test.go Outdated
for {
fd, err := l.Accept()
if err != nil {
t.Logf("accept error: %v", err)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ignore closed errors

@mafredri
Copy link
Member Author

@kylecarbs great suggestion! Added.

Comment on lines +265 to 267
t.Cleanup(func() {
<-doneC
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

note: I wasn't sure of this so I had to remind myself -- reading from a closed channel will immediately return the zero value of the channel type, and not block.

https://go.dev/play/p/PIS5JU1Lbgz

So this is fine, this won't cause t.Cleanup to hang or anything.

// And we're done.
pty.WriteLine("exit")
<-cmdDone
})
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

praise: This is such a cool test.

//nolint:paralleltest // Disabled due to use of t.Setenv.
t.Run("ForwardAgent", func(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Test not supported on windows")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

remark, non-blocking: recent versions of Windows do include SSH (source) but it's probably a ghastly can of worms to open! So agreed, let's leave this non-Windows for now. 😅

Co-authored-by: Cian Johnston <cian@coder.com>
@mafredri mafredri merged commit 527f1f3 into main May 25, 2022
@mafredri mafredri deleted the mafredri/ssh-agent-forwarding branch May 25, 2022 18:28
kylecarbs pushed a commit that referenced this pull request Jun 10, 2022
* feat: Add SSH agent forwarding support to coder agent

* feat: Add forward agent flag to `coder ssh`

* refactor: Share setup between SSH tests, sync goroutines

* feat: Add test for `coder ssh --forward-agent`

* fix: Fix test flakes and implement Deans suggestion for helpers

* fix: Add example to config-ssh

* fix: Allow forwarding agent via -A

Co-authored-by: Cian Johnston <cian@coder.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Feat: Add support for SSH agent forwarding
4 participants