Skip to content

Instantly share code, notes, and snippets.

@WillianTomaz
Last active April 29, 2024 15:26
Show Gist options
  • Star 38 You must be signed in to star a gist
  • Fork 7 You must be signed in to fork a gist
  • Save WillianTomaz/a972f544cc201d3fbc8cd1f6aeccef51 to your computer and use it in GitHub Desktop.
Save WillianTomaz/a972f544cc201d3fbc8cd1f6aeccef51 to your computer and use it in GitHub Desktop.
Instructions for using 1Password SSH Agent with WSL2 (on Windows 11)

Saturday, April 22, 2023

How to Use 1Password SSH Agent with WSL2 (on Windows 11)

  • Note:

    • Always look for the official documentation, this tutorial may not suit you as there are new updates to the installation process.
    • References are at the end of the document.
  • Was used:

    • Windows 11 (x64)
    • WSL 2 (Ubuntu 22.04.2 LTS)
    • 1Password (for Windows 8.10.5)



Install WSL2 (on Windows 11)

  • Windows 11 makes it easy to install WSL, basically you need to run these commands:

    In your PowerShell(admin) or CMD(admin):

    1. Run the command to install WSL2, and restart the computer.
      # The command will install WSL alongside the Ubuntu distribution.
      wsl –install
      # Or, to install WSL with a specific distro, run the command:
      wsl –install -d <distro-name>
    2. Other Useful Commands:
      # Checking the image version
      wsl --list --verbose
      
      # Selecting Distro as Main
      wsl --setdefault <distro-name>
      
      # If you need to remove a distro
      wsl --unregister <distro-name>
      
      # If necessary, kill the WSL process
      wsl --shutdown  



1. Enable 1Password SSH Agent

2. Download npiperelay

  • This tool (npiperelay) is used for communication between WSL and the 1Password SSH agent. It uses WSL to communicate with Windows Named Pipes.
    1. Download npiperelay from the GitHub repository
    2. Unzip it, and paste the npiperelay.exe file in any folder that's configured in your system's PATH.
      • If you don't know how to modify your system's PATH... Example Here
        # 1. Create a folder at an address like this
        C:\Users\my-user\folder-npiperelay
        # 2. Create PATH Environment Variable on Windows
        # 3. Run npiperelay.exe

3. Connect WSL with 1Password's SSH agent

In your WSL distribution:

  • "We need to install socat which is a utility to transfer data between channels, this tool will use npiperelay to then communicate with the named pipes"
    sudo apt install socat
  • Create a new file named .agent-bridge.sh in your home directory
    touch $HOME/.agent-bridge.sh && chmod +x $HOME/.agent-bridge.sh
    1. (IMPORTANT) Create the folder on your root for the agent.sock (How mentioned by @rfay and @Lochnair in the comments) or if you prefer, add the content on .agent-bridge.sh at the top of the step bellow
      mkdir -p ~/.1password
    2. Paste content into File: .agent-bridge.sh
      # Code extracted from https://stuartleeks.com/posts/wsl-ssh-key-forward-to-windows/ 
      
      # (IMPORTANT) Create the folder on your root for the `agent.sock` (How mentioned by @rfay and @Lochnair in the comments)
      # mkdir -p ~/.1password
      
      # Configure ssh forwarding
      export SSH_AUTH_SOCK=$HOME/.1password/agent.sock
      # need `ps -ww` to get non-truncated command for matching
      # use square brackets to generate a regex match for the process we want but that doesn't match the grep command running it!
      ALREADY_RUNNING=$(ps -auxww | grep -q "[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent"; echo $?)
      if [[ $ALREADY_RUNNING != "0" ]]; then
          if [[ -S $SSH_AUTH_SOCK ]]; then
              # not expecting the socket to exist as the forwarding command isn't running (http://www.tldp.org/LDP/abs/html/fto.html)
              echo "removing previous socket..."
              rm $SSH_AUTH_SOCK
          fi
          echo "Starting SSH-Agent relay..."
          # setsid to force new session to keep running
          # set socat to listen on $SSH_AUTH_SOCK and forward to npiperelay which then forwards to openssh-ssh-agent on windows
          (setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork &) >/dev/null 2>&1
      fi
    3. Add the following line at the end of the file .bashrc
      source $HOME/.agent-bridge.sh

4. Finally last step

  • Reset your Windows Terminal and you should be able to see your keys imported into 1Password when listing the keys added to the agent.
  • Try this command on your WSL2 and if it returns your keys, congratulations you finished the setup!
    ssh-add -l



References

@WillianTomaz
Copy link
Author

Thanks a lot guys!
I added folder creation as commented! 😄 👍

@DR-DinoMight
Copy link

Thanks for this I've been pulling my hair out trying to figure out how to do this.

One question, is there any reason this wouldn't work in a zsh shell? I've tried adding it but I just can't get it to work is throws no errors or anything just nothing.

as soon as I change my default shell back to bash it works?

@WillianTomaz
Copy link
Author

as soon as I change my default shell back to bash it works?

Thanks, @DR-DinoMight
I use it with the default terminal (bash) and it works perfectly!
About ZSH, sorry but I don't have good experiences with it 😆

@jerriclynsjohn
Copy link

Any idea about how to make this work for zsh?

@jerriclynsjohn
Copy link

I tried this in bash and I'm getting this error error fetching identities: communication with agent failed. Any advice on how to fix this?

@TowardsDeath
Copy link

TowardsDeath commented Aug 14, 2023

I tried this in bash and I'm getting this error error fetching identities: communication with agent failed. Any advice on how to fix this?

I had this problem as well with 1Password, as of today. It turned out to be a problem with running .exe files, such as npiperelay.exe. (I tried to run VS Code, which failed with an error "Exec format error".) The problem and solution are described here: microsoft/WSL#8843

Running this command fixed the issue:

sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf'

@janniksinz
Copy link

Same issue: error fetching identities: communication with agent failed. I also found this solution sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf' and ran it in WSL2 but even after restarting WSL it does nothing.
I had it working twice before but after some time and restarts it always comes back to this error.

@jerriclynsjohn
Copy link

jerriclynsjohn commented Aug 18, 2023

I tried this in bash and I'm getting this error error fetching identities: communication with agent failed. Any advice on how to fix this?

I had this problem as well with 1Password, as of today. It turned out to be a problem with running .exe files, such as npiperelay.exe. (I tried to run VS Code, which failed with an error "Exec format error".) The problem and solution are described here: microsoft/WSL#8843

Running this command fixed the issue:

sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf'

This also resulted in the same error error fetching identities: communication with agent failed

@DeamonMV
Copy link

DeamonMV commented Sep 11, 2023

Same issue: error fetching identities: communication with agent failed. I also found this solution sudo sh -c 'echo :WSLInterop:M::MZ::/init:PF > /usr/lib/binfmt.d/WSLInterop.conf' and ran it in WSL2 but even after restarting WSL it does nothing. I had it working twice before but after some time and restarts it always comes back to this error.

Try this microsoft/WSL#3326 (comment)

# cat /etc/wsl.conf
[automount]
enabled = true
options = "metadata,umask=0077,fmask=0077"

I have same issue.
This should help if when you are trying to run, from the you WSL distro, npiperelay.exe command and Get error Permmision Denied
But command should work fine

@WillianTomaz Please consider to add this to the manual. Thank you

@DeamonMV
Copy link

DeamonMV commented Sep 12, 2023

That was a not good idea, do not do in this way

Better to keep you /etc/wsl.conf as is, for example like this

[automount]
enabled = true
options = "metadata,umask=022,fmask=111"
mountFsTab = true

Run npiperelay.exe you will get error Permission denied and the path to the npiperelay.exe

And just run sudo chmod +x /mnt/c/your/path/to/npiperelay.exe to fix it.

This should help

@kraduk
Copy link

kraduk commented Sep 12, 2023

Thanks for this I've been pulling my hair out trying to figure out how to do this.

One question, is there any reason this wouldn't work in a zsh shell? I've tried adding it but I just can't get it to work is throws no errors or anything just nothing.

as soon as I change my default shell back to bash it works?

It probably needs a #!/bin/bash on the 1st line of the script, and then executed vs sourced in. You could also do bash $HOME/.agent-bridge.sh in your bashrc

@rfay
Copy link

rfay commented Sep 19, 2023

Apparently 1Password is about to release explicit support. Slack has a good conversation, https://1password-devs.slack.com/archives/C032QPCFK0B/p1695093498713749

Besides this approach and the (coming) 1Password explicit support, there's also a reference to a useful article, https://justinbarclay.ca/posts/1password-across-the-void/

@gustavobigardi
Copy link

It worked perfectly here!! Thank you so much bro!

@AnturGyffrous
Copy link

This worked for me on ZSH, but of course I had to add the source $HOME/.agent-bridge.sh line to .zshrc not .bashrc

@michal-grzelak
Copy link

michal-grzelak commented Oct 21, 2023

I second what @rfay posted above. If you're using WSL then you don't need any npiperelay. interop is turned on by default in WSL, so you can simply put:

alias ssh="/mnt/c/Windows/System32/OpenSSH//ssh.exe" # or just ssh.exe
alias ssh-add="/mnt/c/Windows/System32/OpenSSH//ssh-add.exe" # or just ssh-add.exe

into your .zshrc/.bashrc.

If you don't want to use windows ssh in WSL and wanted just to use for git, then no problem, just put:

[core]
  sshProgram = "/mnt/c/Windows/System32/OpenSSH//ssh.exe" # or just ssh.exe

in you .gitconfig.

This is just a shortcut from the article.

@FlyinPancake
Copy link

FlyinPancake commented Oct 29, 2023

If you use fish, you can add this to a file located in .config/fish/conf.d/

#!/bin/fish
# Configure ssh forwarding
set -x SSH_AUTH_SOCK $HOME/.1password/agent.sock

# Check if npiperelay.exe is already running
set ALREADY_RUNNING (ps -auxww | grep -q "[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent"; echo $status)
if test $ALREADY_RUNNING != 0
    if test -S $SSH_AUTH_SOCK
        # Not expecting the socket to exist as the forwarding command isn't running
        echo "Removing previous socket..."
        rm $SSH_AUTH_SOCK
    end

    echo "Starting SSH-Agent relay..."
    # Use setsid to force a new session to keep running
    # Set socat to listen on $SSH_AUTH_SOCK and forward to npiperelay, which then forwards to openssh-ssh-agent on Windows

    setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork >/dev/null 2>&1 &
end

@FlyinPancake
Copy link

@cyshallchan
Copy link

It seems that this method is no longer effective now? At least in my case, I can't use it. Is there anyone kind enough to help me?

ps -ef | grep -i agent:

root        5236       1  0 20:15 ?        00:00:00 /usr/bin/socat UNIX-LISTEN:/root/.ssh/agent.sock,fork EXEC:/mnt/c/Users/Cyshall/AppData/Local/Microsoft/WinGet/Links/npiperelay.exe -ei -s //./pipe/openssh-ssh-agent,nofork

Running ssh-add -l gives me an error:

error fetching identities: communication with agent failed

System info:

Windows 11 Pro 22H2 22621.2428

1password info:

1Password for Windows 8.10.7 (81007041)

@FlyinPancake
Copy link

Check the value of the SSH_AUTH_SOCK variable, and try restarting the PC

@cyshallchan
Copy link

Check the value of the SSH_AUTH_SOCK variable, and try restarting the PC

I have tried everything, but it didn't work. Then I attempted to start directly from the terminal and checked the output, but I couldn't understand it. The detailed steps are as follows:

The first window executes the following command in wsl2:

/usr/bin/socat UNIX-LISTEN:/root/.ssh/agent.sock,fork EXEC:"/mnt/c/Users/xxxx/AppData/Local/Microsoft/WinGet/Links/npiperelay.exe -ei -s //./pipe/openssh-ssh-agent"

The second window in wsl2 reports an error executing ssh-add -l:

error fetching identities: communication with agent failed

Returning to the first window at this point will output the following:

/mnt/c/Users/xxxx/AppData/Local/Microsoft/WinGet/Links/npiperelay.exe: 1: MZ    @   : not found
/mnt/c/Users/xxxx/AppData/Local/Microsoft/WinGet/Links/npiperelay.exe: 3: Syntax error: word unexpected (expecting ")")
2023/10/31 19:01:56 socat[2906] E waitpid(): child 2907 exited with status 2

@smooshy
Copy link

smooshy commented Nov 2, 2023

Thanks for this! This worked for me on Win 11 with Ubuntu 22.04.3.

@cyshallchan
Copy link

I second what @rfay posted above. If you're using WSL then you don't need any npiperelay. interop is turned on by default in WSL, so you can simply put:

alias ssh="/mnt/c/Windows/System32/OpenSSH//ssh.exe" # or just ssh.exe
alias ssh-add="/mnt/c/Windows/System32/OpenSSH//ssh-add.exe" # or just ssh-add.exe

into your .zshrc/.bashrc.

If you don't want to use windows ssh in WSL and wanted just to use for git, then no problem, just put:

[core]
  sshProgram = "/mnt/c/Windows/System32/OpenSSH//ssh.exe" # or just ssh.exe

in you .gitconfig.

This is just a shortcut from the article.

I just noticed this method, I tried it out and it worked fine. Thank you very much!

@rfay
Copy link

rfay commented Nov 20, 2023

The official instructions at https://developer.1password.com/docs/ssh/integrations/wsl/ are now working in general, it may be best to just adopt them now. Pretty simple.

@julienallexandre
Copy link

@rfay
Copy link

rfay commented Nov 23, 2023

It's working perfectly for me.

@Dragory
Copy link

Dragory commented Nov 30, 2023

The official instructions are really just a different workaround, and for some use cases a worse solution. For example, it requires you to manage your SSH config on the Windows side and doesn't set SSH_AUTH_SOCK at all, which some use cases might need.

@Icehunter
Copy link

I also don't use .exe files in windows as much as possible and don't appendPath. The only issue I have is the constant:

ssh-add -L
Error connecting to agent: No such file or directory

I have to delete the older and remake it a few times and kill wsl to get it working after a reboot.

@mkhoatd
Copy link

mkhoatd commented Mar 8, 2024

I also don't use .exe files in windows as much as possible and don't appendPath. The only issue I have is the constant:

ssh-add -L
Error connecting to agent: No such file or directory

I have to delete the older and remake it a few times and kill wsl to get it working after a reboot.

Maybe try this

export SSH_AUTH_SOCK=$HOME/.ssh/agent.sock

# Function to start the SSH-Agent relay
start_ssh_agent_relay() {
    if [[ -S $SSH_AUTH_SOCK ]]; then
        echo "Removing previous socket..."
        rm $SSH_AUTH_SOCK
    fi
    echo "Starting SSH-Agent relay..."
    (setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork &) >/dev/null 2>&1
}

# Function to check if the SSH-Agent relay is running
check_ssh_agent_relay() {
    if [[ $(ssh-add -l 2>&1) == "Error connecting to agent: No such file or directory" ]]; then
        return 1  # Return non-zero exit code if the relay is not running
    else
        return 0  # Return zero exit code if the relay is running
    fi
}

# Function to stop the SSH-Agent relay
stop_ssh_agent_relay() {
    npiperelay_pid=$(ps -auxww | grep -q "[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent" | awk '{print $2}')
    if [[ -n $npiperelay_pid ]]; then
        echo "Killing npiperelay..."
        kill $npiperelay_pid
    fi
    if [[ -S $SSH_AUTH_SOCK ]]; then
        echo "Removing previous socket..."
        rm $SSH_AUTH_SOCK
    fi
}

# Check if the SSH-Agent relay is already running
if ! ps -auxww | grep -q "[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent"; then
    start_ssh_agent_relay
fi

# Check if the SSH-Agent relay is running and retry if it fails
retry_count=0
max_retries=3
while ! check_ssh_agent_relay; do
    if ((retry_count >= max_retries)); then
        echo "Failed to start SSH-Agent relay after $max_retries attempts."
        exit 1
    fi
    echo "SSH-Agent relay failed to start. Retrying..."
    stop_ssh_agent_relay
    start_ssh_agent_relay
    ((retry_count++))
done

echo "SSH-Agent relay started successfully."

@SJ50
Copy link

SJ50 commented Mar 16, 2024

for those who are facing error fetching identities: communication with agent failed or any ssh-add -l related errors.
try below script

#!/bin/bash

export SSH_AUTH_SOCK=$HOME/.ssh/ssh-agent.sock

# need `ps -ww` to get non-truncated command for matching
# use square brackets to generate a regex match for the process we want but that doesn't match the grep command running it!
SSH_AGENT_WORKING=$(ssh-add -l >/dev/null 2>&1; echo $?)
if [[ $SSH_AGENT_WORKING != "0" ]]; then
    # echo "ssh agent not working, killing npiperelay.exe"
    kill $(ps -auxww | grep "[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent" | awk '{print $2}') >/dev/null 2>&1
fi	

ALREADY_RUNNING=$(ps -auxww | grep -q "[n]piperelay.exe -ei -s //./pipe/openssh-ssh-agent"; echo $?)
if [[ $ALREADY_RUNNING != "0" ]]; then	
    
    if [[ -S $SSH_AUTH_SOCK ]]; then
        # not expecting the socket to exist as the forwarding command isn't running (http://www.tldp.org/LDP/abs/html/fto.html)
        # echo "removing previous socket..."
        rm $SSH_AUTH_SOCK >/dev/null 2>&1
    fi
    # echo "Starting SSH-Agent relay..."
    # setsid to force new session to keep running
    # set socat to listen on $SSH_AUTH_SOCK and forward to npiperelay which then forwards to openssh-ssh-agent on windows
    (setsid socat UNIX-LISTEN:$SSH_AUTH_SOCK,fork EXEC:"npiperelay.exe -ei -s //./pipe/openssh-ssh-agent",nofork &) >/dev/null 2>&1
fi

When WSL shutdown it keep socat process stored and when we start WSL again it reuses same process, this leads to error error fetching identities: communication with agent failed. I have added check if ssh-agent process is running properly, if not then kill and restart socat process

@rodrigo-a-moreno
Copy link

Excellent Post!!!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment