With Bash on Ubuntu on Windows, you can use a Windows Subsystem for Linux on Windows 10. With that, you can run many Linux commands, for example, ssh
. This post shows you how to create an SSH key, which should be used on both, the Linux subsystem and Windows.
Update from May 14, 2018: After updating to the Insider Build 17063, you need to run the following commands on the Windows Subsystem for Linux to make the solution work again, as Entity Black points out in his comment under this post:
sudo umount /mnt/c
sudo mount -t drvfs C: /mnt/c -o metadata
Update from May 29, 2018: It seems that the steps with unmounting are only temporary, as pointed out in the comments. To fix this, you need to modify or create a config file and add a little bit of content to it. There are three slightly different ways proposed in the comments – one by Andrew, one by Entity Black, and one by Vince.
Update from July 10, 2018: Darren mentioned in his comment, that using SSH alias with the described solution will fail, and how to solve that.
Goal
I wanted to create an SSH key, which I can use with the Linux subsystem and standard Windows programs. In the best scenario, the key is stored only once on the hard disk. You can read a tutorial about installing the subsystem on howtogeek.com.
Solution
The default path for SSH keys on Windows is C:/Users/Florian/.ssh
which matches the path /mnt/c/Users/Florian/.ssh
on the Linux subsystem. Default SSH path on the subsystem is ~/.ssh
.
Previous to this post update, I had a not optimal solution where the keys needed to exist twice. But in the comments there were several folks with better solutions – one of them Andrey Chirkov, who posted a one-line solution that you run on the Windows Subsystem for Linux (the ~/.ssh
folder must not exist before running it):
Code language: Bash (bash)ln -s /mnt/c/Users/Florian/.ssh ~/.ssh
That creates a link from ~/.ssh
to /mnt/c/Users/Florian/.ssh
. With that, we only need to store our SSH keys in the Windows path and can use them from the Linux shell, too.
After trying it, I noticed that this line was also part of the Stack Overflow response I linked in the previous version of the post. I have no idea why I did not get it working back then…
The original version of this post was published on March 8, 2017.
Thanks!
I also found I could copy existing Windows keys and then fix up the permissions with:
The whole article couldn't save me, till I give these 2 (permission) commands shown by you.
God bless!!
Thank you for your help ! Your article helped me to figure out how the whole ssh system worked.
Just one thing : the private and public keys were created in the root/.ssh directory in my case, and not in the user directory. But I use the Linux subsystem for Windows, so that can be an explanation.
Have you tried hard-linking the files rather than using a symbolic link? I think the permissions would be preserved in that case.
Thanks for your comment. Did not try that, but will do that!
This works for me and I have just one key 😉
```
ssh-keygen -t ecdsa -C "" -f /mnt/c/Users//.ssh/
touch ~/.ssh/config
vi ~/.ssh/config
```
**paste:**
```
Host *
IdentityFile /mnt/c/Users//.ssh/id_ecdsa
```
**save config**
```
chmod 600 ~/.ssh/config
chown $USER ~/.ssh/config
touch /mnt/c/Users//.ssh/known_hosts
ln -s /mnt/c/Users//.ssh/known_hosts ~/.ssh/known_hosts
```
Cool, thanks! Will give that a try.
My working solution in just one command and one key pair:
ln -s /mnt/c/Users/myusername/.ssh ~/.ssh
That is the best solution so far 🙂
Cool, thanks for sharing it – finally tested it and works great! Will update the post accordingly.
Hi, I've got the sim link set up ok. Trying to ssh gives me a permission error. "0777 for .... are to open"
I cant seem to chmod the files. When run (sudo or user) the permissions don't change - and no error is given.
Did you ever get an answer for this? This was my issue as well
Did you resolve it somehow? Stuck into this too.
Guys have you tried multiple ssh keys ?
I have 2 keys,
home_rsa
work_rsa
but even if I modify the config file, they do not get picked up, I always have to rename it to id_rsa for git clone to work.
Anyone else noticed this problem?
Hi Miha,
I haven’t tried multiple keys, but maybe this might help you (also check out the comments, there seem to be modifications to the Gist that might be necessary)? https://gist.github.com/jexchan/2351996
Florian
Hi Florian,
thanks for the link, that solved the issue. Indeed the default SSH Agent does not work so well with multiple keys.
Best,
Miha
Hi Miha,
great to hear that your problem is solved!
Cheers,
Florian
Important update,
based on latest update "Insider Build 17063" there has been significant change in permissions. In very short, you need to:
sudo umount /mnt/c
sudo mount -t drvfs C: /mnt/c -o metadata
Relevant links:
https://github.com/Microsoft/WSL/issues/3181
https://blogs.msdn.microsoft.com/commandline/2018/01/12/chmod-chown-wsl-improvements/
https://blogs.windows.com/windowsexperience/2017/12/19/announcing-windows-10-insider-preview-build-17063-pc/#cbUAtBrErr1A3JJA.97
Thanks for the hint! I will insert an update box at the beginning of the article.
Does unmounting and mounting solves the issue for you? For me it doesn't set the metadata flag. Any ideas?
I found the solution.
Since I wasn't able to mount c: with metadata flag I had to change /etc/wsl.conf and include the following:
[automount]
options = "metadata"
Thank you for this solution, you save my day! 😉
It worked once after unmounting and remounting drive C. When I exit and re-enter the shell, I'm once again unable to use git.
This isn't a workable solution for me. I need to do some reading to find out what the change was (something with the drvfs mount type?) and how to make it permanent.
Hey Vince,
yeah I should mention it here. The permanent solution requires to edit /etc/wsl.conf file in your wsl. It is described in my answer here on stackexchange (see EDIT part):
https://softwareengineering.stackexchange.com/a/370900/122285
Okay, it was easier than I thought.
The solution that worked for me was to add a very simple /etc/wsl.conf:
[automount]
enabled = true
options = "metadata"
I found part of the answer at Stack Exchange's Super User site:
https://superuser.com/a/1295442/280338
... but that answer resulted in fixed directory permissions and ignored file permissions for me.
I read the referenced MS page:
https://docs.microsoft.com/en-us/windows/wsl/wsl-config#set-wsl-launch-settings
... but using that code resulted in not mounting the host drives at all. Using just the enabled and options parts from the page resulted in fixed directory and file permissions, which kinda works, but I'd rather set the permissions myself.
Then I remembered that the temporary solution from here only sets the "metadata" option. So, that's what I did, and it works like a charm... Just like I have a real operating system with a real filesystem.
@Andrew, Entitiy Black and Vince: thanks for your additional comments! I will add an additional update box to the beginning of the post pointing to the comments section with your tips 🙂
Best,
Florian
Hi,
It may be worth noting that if using the ssh configuration file, you may need to do this a slightly different way.
Due to strict permissions requirements of the .ssh/config, it requires it be only read/write on that file. Thus it cannot exist on the windows file system. A way around this is to simply use symlinks to each individual key file and known hosts, and let config reside on the linux side.
Thus, using
ln -s /mnt/c/Users/YourName/.ssh/id_rsa.pub ~/.ssh/id_rsa.pub
ln -s /mnt/c/Users/YourName/.ssh/id_rsa ~/.ssh/id_rsa
ln -s /mnt/c/Users/YourName/.ssh/known_hosts ~/.ssh/known_hosts
And then leaving the .ssh/config file as-is, not symlinked on the linux side, with permissions 600, allows for usage of the .ssh config file. Thus, you can have quick alias names in there such as:
Host myAlias
HostName somewhere.com
User exampleUser
And can easily connect with:
ssh myAlias
If you symlink the entire .ssh folder, and have a config file in there, windows takes over the ACL and you can no longer specify a 600 permission. Thus, trying to connect via the alias will result in a failure due to incorrect permissions. This is what wound up working for me anyhow. Hopefully it helps someone else out setting this up!
Hi Darren,
thanks a lot for your comment! Personally, I did not use alias yet, but it is good to know 🙂 I will add a link to the update box at the beginning pointing to your comment.
Best,
Florian
Darren,
Your comments about "strict permissions requirements" of .ssh helped me investigate my password-less ssh login issues with the Windows Subsystem for Linux (WSL). Also, your comments about the permissions and which side controlling the file permissions was helpful. But my solution was a bit different and, in particular, the use of the ln command was different.
My approach was to allow the WSL to control the file permissions of /home/comperem/.ssh and everything in there (known_hosts, id_rsa, and id_rsa.pub)
Previously I had changed the WSL bash HOME environment variable to /mnt/c/Users/comperem by editing the WSL system-wide bash.bashrc file in /etc/bash.bashrc with this:
export HOME=/mnt/c/Users/comperem
Then, in WSL's bash, after running 'ssh-keygen -t rsa' and hitting return to all defaults with no passphrase, the WSL files appeared in their expected location with proper permissions:
ls -l /home/comperem/.ssh/
total 4
-rw------- 1 comperem comperem 1679 Jul 21 11:46 id_rsa
-rw-r--r-- 1 comperem comperem 397 Jul 21 11:46 id_rsa.pub
-rw-r--r-- 1 comperem comperem 444 Jul 21 11:46 known_hosts
Notice the permissions properly implemented with WSL's bash: -rw-r--r--
This is where my solution differs. The ln command is similar to the cp and mv commands:
ln -s src dest (or ln -s TARGET LINK_NAME which is the same conceptually)
Creating a symbolic link to .ssh in the Windows home folder to the WSL .ssh with:
ln -s /home/comperem/.ssh /mnt/c/Users/comperem/.ssh
results in the proper permissions for the entire contents of the .ssh folder on the WSL side:
comperem@matrix:~/.ssh$ pwd
/mnt/c/Users/comperem/.ssh
comperem@matrix:~/.ssh$ ls -l
total 4
-rw------- 1 comperem comperem 1679 Jul 21 11:46 id_rsa
-rw-r--r-- 1 comperem comperem 397 Jul 21 11:46 id_rsa.pub
-rw-r--r-- 1 comperem comperem 444 Jul 21 11:46 known_hosts
comperem@matrix:~/.ssh$
Then remote login with ssh is passwordless via the public keys as expected.
My solution is a bit different but your post helped.
Hi Marc,
I received two almost identical comments from you (I think the second had one more line of code) – I replaced the comment text of the first one (that was marked as reply to Darren) with the text of the second one, so it is correctly listed as a reply here and includes your modification 🙂
Best,
Florian
yes, perfect. thanks.
This solution works like a champ.
sshd -ddd complained bad owner or modes for /mnt/c/Users/user initially, so I did chmod 755 /mnt/c/Users/user. Again, sshd compalined about the permission stuff for /mnt/c.
I turned off strict modes to get a simple workaround. Though it's not a good way to do it, this and the metadata thing together can get public key auth work on the current wsl.
Maybe keeping two copies of .ssh is in fact the best painless solution. This is what I feel after a whole struggling.
BTW, this post and all the replies above are really useful! Thank you guys!
Great to hear that, thanks for your comments! 🙂
Thank you for this article and the comments.
Reading here and there, the solution I came with is:
sudo umount /mnt/c
sudo mount -t drvfs C: /mnt/c -o metadata
To make the change permanent, edit /etc/wsl.conf:
[automount]
options = "metadata,uid=,gid="
To use the config file in ssh, I simply restrict the permissions on this file to read-only on Windows.
Best article on the internet for this topic. Finally got Subsystem linux and ssh and windows working in harmony! Hallelujah!
Thank you a million