microsoft / vscode-remote-release

Visual Studio Code Remote Development: Open any folder in WSL, in a Docker container, or on a remote machine using SSH and take advantage of VS Code's full feature set.
https://aka.ms/vscode-remote
Other
3.6k stars 273 forks source link

WSL2 vscode git don't use ssh-agent, but works in integrated terminal #5956

Open codekoriko opened 2 years ago

codekoriko commented 2 years ago

OS: Windows_NT x64 10.0.18363

Output > git

> git pull --tags origin master
git@github.com: Permission denied (publickey).
fatal: Could not read from remote repository.

Please make sure you have the correct access rights
and the repository exists.

Integrated terminal:

echo $SSH_AUTH_SOCK
# >>> /home/username/.ssh/agent.sock
ssh-add -l
# >>> 4096 SHA256:T/00000000000000000000000000000 my_key (RSA)

Steps to Reproduce:

  1. in integrated terminal launch: git pull --tags origin master. All works
  2. in vscode:WSL click button SC synchronise change. Permission denied (publickey)

The problem appeared when I upgraded to Debian 11, which updated Git from 2.20 to 2.30.

bamurtaugh commented 2 years ago

Does running VS Code as an administrator make a difference? Wondering if it could be related to this.

codekoriko commented 2 years ago

just tried and unfortunately it does not.

socat also setup correctly apparently

socat -V
# >>> socat by Gerhard Rieger and contributors - see www.dest-unreach.org
# >>> socat version 1.7.4.1 on Feb  3 2021 12:58:17
# >>>    running on Linux version #1 SMP Tue Jun 23 12:58:10 UTC 2020, release 4.19.128-microsoft-standard, machine x86_64
# >>> features:
# >>>   #define WITH_STDIO 1
# >>>   #define WITH_FDNUM 1
# >>>   #define WITH_FILE 1
# >>>   #define WITH_CREAT 1
# >>>   #define WITH_GOPEN 1
# >>>   #define WITH_TERMIOS 1
# >>>   #define WITH_PIPE 1
# >>>   #define WITH_UNIX 1
# >>>   #define WITH_ABSTRACT_UNIXSOCKET 1
# >>>   #define WITH_IP4 1
# >>>   #define WITH_IP6 1
# >>>   #define WITH_RAWIP 1
# >>>   #define WITH_GENERICSOCKET 1
# >>>   #define WITH_INTERFACE 1
# >>>   #define WITH_TCP 1
# >>>   #define WITH_UDP 1
# >>>   #define WITH_SCTP 1
# >>>   #define WITH_LISTEN 1
# >>>   #define WITH_SOCKS4 1
# >>>   #define WITH_SOCKS4A 1
# >>>   #define WITH_VSOCK 1
# >>>   #define WITH_PROXY 1
# >>>   #define WITH_SYSTEM 1
# >>>   #define WITH_EXEC 1
# >>>   #undef WITH_READLINE
# >>>   #define WITH_TUN 1
# >>>   #define WITH_PTY 1
# >>>   #define WITH_OPENSSL 1
# >>>   #undef WITH_FIPS
# >>>   #define WITH_LIBWRAP 1
# >>>   #define WITH_SYCLS 1
# >>>   #define WITH_FILAN 1
# >>>   #define WITH_RETRY 1
# >>>   #define WITH_MSGLEVEL 0 /*debug*/
bamurtaugh commented 2 years ago

Does any of the guidance here seem to help? https://github.com/microsoft/WSL/issues/815 https://github.com/microsoft/WSL/issues/3530 https://github.com/microsoft/WSL/issues/3181

codekoriko commented 2 years ago

Nope unrelated issue. As I said everything works fine in the terminal which is not the case in this windows/unix permission conflicting issue you pointed out.

bamurtaugh commented 2 years ago

Any thoughts @aeschli?

aeschli commented 2 years ago

Could be related to the environment the server is started in.

If you set "remote.WSL.debug": true, close all windows and start, then the WSL log shows the environment.

codekoriko commented 2 years ago

ok we are making progress here :+1:
"remote.WSL.debug": true shows reveals:

# No shell environment set or found for current distro.

and indeed none env from my interactive shell scripts get loaded

When I launch vscode from WSL terminal with code . everything works fine:

# Using shell environment from invoking shell: /tmp/vscode-distro-env.g3BUWI

I haven't updated windows but I did apt dist-upgrade upgrading Debian 10 to Debian 11. Distro seems well set:

wslconfig.exe /list
# Windows Subsystem for Linux Distributions:
# Debian (Default)
wsl.exe -l -v
#   NAME                   STATE           VERSION
# * Debian                 Running         2

I tried Run as admininistrator and also rm -rf ~/.vscode-server/ but with no luck

ElHyperion commented 2 years ago

This issue happens even on Linux Manjaro KDE. Running git fetch from the integrated terminal works fine without password prompt (only once for the first time) but pressing the Synchronize Changes button keeps asking for a passphrase all the time.

The only workaround I have so far is a script I wrote which safely starts a ssh-agent and VS Code in the same env (without spamming other agents). If I start Code like this, it somehow "sees" the instance of the ssh-agent and asks for the password only once:

# Starts ssh-agent if it's not started, and then starts VS Code
vscode() {
    ssh-add -l > /dev/null 2>&1
    if [ ! $? -eq 0 ]; then
        echo -n "Cannot connect to an agent"
        agents=`pgrep ssh-agent | wc -l`
        if [ $agents != "0" ]; then
            echo -n " and another agent is already running, killing it"
            killall ssh-agent
        fi
        echo ""
        echo -n "Starting a new agent: "
        eval "$(ssh-agent)"
        ssh-add
    fi
    code
}

Ideally, I would like to start VS Code through a regular shortcut (code command) or not having to enter the password even once, like on Mac OS, but I'm still struggling to achieve this goal, after more than a year...

ttimasdf commented 1 year ago

This happens to me as well, on WSL2, that git integration not picking up my SSH_AUTH_SOCK config in zshrc. In theory VSCode should pick up environment variables defined in bashrc or zshrc.

However, the env changes only apply after I completely closed and reopened VSCode. Reloading window does not work.

trinitronx commented 11 months ago

I can reproduce the issue reported by @ElHyperion. Same behavior when using built-in "Source Control -> Sync Changes" button (no ssh-agent available), versus integrated and/or external terminal (ssh-agent and/or gpg-agent always works). Oddly enough, commit signing always works in any case, which also uses gpg-agent.

One thing to note about Electron / Chromium on Linux platforms is that Chromium overwrites memory used by /proc/PID/cmdline up to /proc/PID/environ which makes debugging the actual process' inherited environment more difficult. (Original Source: Hackernews: "Inherit environment variables from PID 1 by reading /proc/1/environ"). It moves the environment out of the way beforehand, and can still be seen to an Electron app's process.env map datastructure, just not in /proc/PID/environ anymore at the OS-level.

trinitronx commented 11 months ago

@ElHyperion:

It turns out on Manjaro with the SystemD --user-level gcr-ssh-agent.service and/or gpg-agent.service and Yubikey SSH authentication, the issue was the age-old classic: .profile vs. .bashrc / .zshrc.

Viewing the VSCode process' environment using this debug project, it was easy to see that SSH_AUTH_SOCK was unset when Code OSS (code-oss.desktop) was started via rofi launcher. However, when started directly from an interactive terminal the variable was set (due to being export-ed).

So the issue was due to the non-interactive shell environment starting from rofi launcher, which does not source .bashrc and/or .zshrc, but rather only .profile, and ~/.config/profile.d/*.

In Manjaro's default ~/.profile provided by skel:

if [ -n "$(ls "$HOME"/.config/profile.d 2>/dev/null)" ]; then
    for f in "$HOME"/.config/profile.d/*; do
        # shellcheck source=/dev/null
        . "$f"
    done
fi

So the solution here was to place a file to export SSH_AUTH_SOCK under ~/.config/profile.d directory:

~/.config/profile.d/02-gpg-agent.sh:

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gnupg/S.gpg-agent.ssh"

This should work assuming XDG_RUNTIME_DIR is already set for non-interactive shell environments, and that you're using gpg-agent provided by gpg-agent.service & gpg-agent-ssh.socket.

If using gcr-ssh-agent.socket instead, set this as follows:

~/.config/profile.d/02-gcr-ssh-agent.sh:

export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/gcr/ssh"

For WSL users, the same idea applies for interactive vs. non-interactive shells in general. However, with the added complexity of running inside the Cygwin-like WSL environment which lives inside Windows, with it's own environment. Solutions here depend on the user's specific setup, but probably involve running Pageant and exposing access to this running Pageant (PuTTY SSH Agent) instance down into the WSL environment somehow.

References:

ElHyperion commented 11 months ago

@trinitronx

Wow, thanks for such a comprehensive reply. I'll try it once I'm back to Linux again, hopefully in the following few weeks.

NateTheGreatt commented 4 months ago

adding this to my ~/.ssh/config file worked for me:

Host github.com
    IgnoreUnknown UseKeychain
    UseKeychain yes
    AddKeysToAgent yes
    IdentityFile ~/.ssh/github_key