27

I'm trying to move from using Powershell to Bash on Windows (Windows Subsystem for Linux or WSL). For the purpose of using GIT, I've set up my SSH keys in C:/Users/User/.ssh. I then logged into Bash, and created a symlink ln -s /mnt/c/Users/User/.ssh/ ~/.ssh/ in order to (in theory) use the same ssh keys from both shells.

When running git, however, I always get an error: Bad owner or permissions on /home/user/.ssh/config. What am I doing wrong?

6 Answers 6

6

What am I doing wrong?

SSH requires sane permissions on the private keys and you are not able to achieve that while symlinking to different filesystem (windows). The manual page for ssh explains that quite clearly:

~/.ssh/id_rsa

Contains the private key for authentication. These files contain sensitive data and should be readable by the user but not accessible by others (read/write/execute). ssh will simply ignore a private key file if it is accessible by others.

You can most probably copy the private keys and set appropriate permissions, if you want to "share the keys".

5
  • thank you. And there is no way I could share the same user between the two systems? Commented Feb 28, 2017 at 3:01
  • copying the keys doesn't work. they still have their old ownership & permissions. Using chmod and chown silently fails. Commented May 12, 2017 at 14:40
  • This answer should not be the accepted one because there are multiple other answers showing you clearly that it CAN be done - I have tried two of them, and they work. Commented Apr 4 at 9:51
  • @jurchiks this answers the part of the question I am familiar with and explain concepts to understand the problem. This answer does not say it can NOT be done. The other answers just drop some configuration files and commands, which make it working without explanation. I know people these days are for simple answers that they can just copy&paste though ... Commented Apr 4 at 10:32
  • @Jakuje "you are not able to achieve that while symlinking to different filesystem". Your words, not mine. Commented Apr 4 at 13:46
24

To build on @ChadT's helpful answer, here's what worked for me.

Open your distro, and create or modify the /etc/wsl.conf file to include the automount options below:

$ cat /etc/wsl.conf
[automount]
options = "metadata,umask=022,fmask=111"

These options ensure that files in the mounted system are given proper user and group ownership, and that they have sensible default permissions (as opposed to everything getting 777).

Close the distro, wait about 8 seconds for the background subsystem to stop running, and reopen the distro.

Navigate to your mounted C: drive at /mnt/c/Users/<user>, and set the proper permissions on the .ssh directory and key files, as required by SSH:

$ cd /mnt/c/Users/<user>
$ chmod 700 .ssh
$ chmod 600 .ssh/id_rsa
$ chmod 644 .ssh/id_rsa.pub

Finally, navigate to your distro's home drive, backup or remove any existing .ssh directory, and create a symlink back to your C: drive's .ssh directory:

$ cd ~
$ mv .ssh .ssh_orig
$ ln -s /mnt/c/Users/<user>/.ssh/ .ssh

You should now be able to fully share your Windows SSH config, hosts, and keys with your WSL distro, while maintaining them in a single place.

2
  • 1
    Great solution, this one works flawlessly Commented Jun 6, 2024 at 10:16
  • Yes, agree, this is cool. Use dos2unix ~/.ssh/config if the ^M (CRLF) that you get when tab-completing hosts are annoying Commented Nov 6 at 3:10
18

Here's a solution which mounts the .ssh directory directly and doesn't require changing /etc/wsl.conf to enable the metadata option (which can be a bit heavyweight, in my opinion).

By default, most/all Linux distros read and process the fstab file on startup, to automatically mount filesystems. WSL 2 does so as well. And since Windows drives and folders can be mounted directly in WSL using DrvFs, we can combine them to automatically sync the .ssh directory between OSes.

Open your Linux distro and edit the /etc/fstab file as root (e.g. with sudo nano /etc/fstab). Add the following line at the end:

C:\Users\<your Windows username>\.ssh\ /home/<your Linux username>/.ssh drvfs rw,noatime,uid=1000,gid=1000,case=off,umask=0077,fmask=0177 0 0

where you've replaced <your Windows username> and <your Linux username> appropriately. The other mount flags will ensure the permissions on the .ssh directory are correct. Then restart your WSL distro and voilà, all your SSH keys and config will be automagically available in Linux. Any changes will be synchronized.

5
  • This really works on my Win10 19042! Commented May 12, 2022 at 17:43
  • This is great (tested and works on Windows 10 19044.2130 Commented Nov 8, 2022 at 12:06
  • Also, If for some reason this doesn't work for you, make sure you're using WSL2. Commented Dec 5, 2022 at 9:03
  • Apparently restarting the WSL distro didn't work for me, opening WSL after the shutdown showed "Processing fstab with mount -a failed". I happened to find elsewhere that running sudo mount -a allows to test the file, so I did, and it showed "mount: (hint) your fstab has been modified, but systemd still uses the old version; use 'systemctl daemon-reload' to reload." So I did the reload and ran sudo mount -a again, and this time, it worked, the .ssh directory is in WSL and it works. Commented Apr 3 at 19:41
  • If your Windows username contains spaces, you can use \040 which will be converted to a space Commented May 3 at 20:30
10

Based on solution from Gabriel Majeri, perform the following script in your WSL distro:

# Create .ssh directory in home directory with proper permission
mkdir -m 700 ~/.ssh

# Get Windows user name
WINUSER=`cmd.exe /c 'echo %USERNAME%' | tr -d '\r'`

# Add a permanent mount entry for Windows user .ssh directory
cat << EOF | sudo tee -a /etc/fstab
C:\Users\\$WINUSER\.ssh\ /home/$USER/.ssh drvfs rw,noatime,uid=`id -u`,gid=`id -g`,case=off,umask=0077,fmask=0177 0 0
EOF

# Mount the .ssh
sudo mount /home/$USER/.ssh
3
  • You mean... the guy who answered above you? lol Commented Aug 27, 2024 at 20:10
  • I appreciate this clean script as an extension of the other answer. Worked well for me. Commented Feb 4 at 12:02
  • hey, I think all my keys went away, is there any way I can revert this operation, now I can't find my keys in windows nor in ubuntu Commented Jun 23 at 22:31
7

You need to mount your windows filesystem using the DrvFS file system with the metadata option which allows Linux permissions to coexist with Windows files by storing them in file metadata.

sudo umount /mnt/c sudo mount -t drvfs C: /mnt/c -o metadata

This will allow you to use your SSH Keys across both Operating Systems.

Further reading: https://blogs.msdn.microsoft.com/commandline/2018/01/12/chmod-chown-wsl-improvements/

And yet more reading on how to configure WSL to apply this setting everytime it starts: https://blogs.msdn.microsoft.com/commandline/2018/02/07/automatically-configuring-wsl/

5
  • Hi Chad, this is interesting. I no longer have a dual boot system so I'm unable to test if it works for me and therefore can't mark it as the right answer. But I can upvote. Commented Jun 28, 2018 at 11:30
  • @bluppfisk fwiw I am using this method to share ssh keys across Windows/Linux and it is working great! Commented Jun 29, 2018 at 0:10
  • just to be clear, you are still simply copying the files not sharing them, right? As Jakuje notes, the permissions of symlinks seem incompatible with ssh restrictions and I have just encountered the expected "unprotected file" warnings... If you're able to somehow keep only one key in either WSL or Windows and then create a shortcut/symlink that works with SSH, please do let me know! Commented Jun 20, 2021 at 2:57
  • @FonsMA - No this isn't copying, it's mounting the files with additional metadata to that the permission info is carried through. Commented Jun 21, 2021 at 0:59
  • yes, my C drive has Linux metadata and I can set whatever permissions I want. But I still need to keep an exact copy of my_key.rsa both under /mnt/c/Users/fons/.ssh/ and /home/fons/.ssh/ for stuff I run out of WSL (like my Rstudio Server ssh tunnelling) and stuff that runs on Windows (like Visual Studio Code). Am I missing something? Commented Jun 21, 2021 at 1:32
0

You can copy your Windows .ssh folder into WSL. Mount the C:/ drive to WSL, then put the following in your ~/.bashrc

# Copy .ssh folder from G:\ to WSL and set correct access.
# The access is important, because extra access on config file
# will prevent it from working.
rm -rf ~/.ssh_new
cp -r /mnt/g/.ssh ~/.ssh_new \
  && chmod 400 ~/.ssh_new/*.ppk \
  && chmod 600 ~/.ssh_new/config \
  && chmod 644 ~/.ssh_new/known_hosts \
  && chmod 644 ~/.ssh_new/*.pub \
  && chmod 700 ~/.ssh_new/ \
  && HOME=$(pwd) \
  && wsl.exe -u root /bin/sh -c "rm -rf $HOME/.ssh" \
  && mv ~/.ssh_new ~/.ssh

This assumes that your public keys end in .pub and your private keys end in .ppk. You can modify the command according to your needs.

Update (and probably a better solution)

Running the above from your .bashrc will work when opening an instance of WSL, but it will fail when opening a WSL-connected terminal via Visual Studio Code. I think VSCode has a protection that prevents privilege escalation via wsl.exe -u root.

An alternative is to use a script and run it manually when you need to update the .ssh folder.

#!/bin/bash

USER_HOME=$(getent passwd $SUDO_USER | cut -d: -f6)

# Copy .ssh folder from G:\ to WSL and set correct access.
# The access is important, because extra access on config file
# will prevent it from working.
cd $USER_HOME
rm -rf ./.ssh_new
cp -r /mnt/g/.ssh ./.ssh_new \
  && chown -R $SUDO_USER:$SUDO_USER ./.ssh_new \
  && chmod 400 ./.ssh_new/*.ppk \
  && chmod 600 ./.ssh_new/config \
  && chmod 644 ./.ssh_new/known_hosts \
  && chmod 644 ./.ssh_new/*.pub \
  && chmod 755 ./.ssh_new/ \
  && rm -rf ./.ssh \
  && mv ./.ssh_new ./.ssh
3
  • Allowing root to SSH into any system is a huge security vulnerability. Commented Jan 29, 2024 at 22:54
  • @Ramhound If you're root, you already have access to create such a script and call it yourself... It's not a vulnerability, since root has access to view the .ssh directory of any user. Also, the script doesn't copy the keys into /root unless you call the script as root; it copies it into the calling user's home directory. The entire question here is about sharing SSH keys between Windows and WSL. That obviously will give the WSL root user access to the keys, whether you mount your .ssh folder or copy the keys. Commented Jan 30, 2024 at 15:55
  • The default user within WSL absolutely shouldn’t be the root user. Commented Jan 30, 2024 at 16:27

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.