Put your ssh experience in Windows on Steroids

ssh In this blogpost I want to show you how you can make your life easier to work with Linux VM’s and Git by configuring SSH on your Windows Machine in a secure but convenient way. Let me first elaborate a little further why you would want to apply the tips and tricks from this blog post.

Git has become the de-facto standard of vcs over the past few years. You are probably using it for all your software development projects, and maybe even for your web blog, when you are blogging in markdown using a static site generator.

You also might be using Nodejs, python or other programming languages which are easier to run on Linux. Probably you have been using a Virtualbox VM or you are deploying your solutions in the cloud. The last thing you want is entering your password each time you connect to the VM via PuTTY. Or when you are trying to send some file to the VM using for example WinSCP.

Furthermore I usually use vagrant for my VM’s. Using the setup below will improve my experience.

This blogpost will help you putting the settings in place so you only have to enter your ssh-key’s password only once. No matter what tool you are using following settings will apply to all of them when they use an ssh key to authenticate.

Prerequisites:

  • Git (Git-extensions)
  • PuTTY
  • Puttygen (comes with Git-extensions)

Generate a SSH key

In order to generate an ssh key you can simply use ssh-keygen.exe which can be found in your Git installation directory in the bin folder. It is mandatory you name the keys exactly as in this blog post, since open_ssh will look for them using those names.

Open your Git Bash and execute following commands to generate your open-ssh key. Make sure you put a strong password on the key when prompted. This makes sure no one can use your key when you accidentally loose it somewhere.

1
2
3
4
5
6
7
8
9
ssh-keygen -t rsa -b 4096 -C "your@email.domain"
Generating public/private rsa key pair.
Enter file in which to save the key (/c/Users/Marco/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in ~/.ssh/id_rsa.
Your public key has been saved in ~/.ssh/id_rsa.pub.
The key fingerprint is:
30:a5:c1:7a:bb:00:bf:7c:24:b7:4d:f1:d6:3d:e5:7e your@email.domain

We have just generated a key pair using 4096 bit encryption. PuTTY does not natively support the generated private key. Next step is to create a private PuTTY ssh key. This can be done using puttygen.exe which can be found in your Git-extensions installation directory or your putty installation directory. Open puttygen.exe by double clicking the executable and import your open-ssh key using the conversion menu as shown in following screenshot.
Puttygen convert Open-SSH
Then save the private key as id_rsa.ppk in the same folder as your open-ssh public and private key. Again don’t forget to put a password on the key (ideally the same as on your open-ssh key for your own convenience).

Now we have the ssh keys in place to be able to setup ssh connections either via Bash (id_rsa) or via PuTTY (id_rsa.ppk). The only problem is we have to enter the password each time in bash and we have to manually load the PuTTY key in pageant.exe.

Pageant

The Pageant program that was installed as part of the PuTTY package, can store your keys and give them to mRemote, WinSCP and PuTTY as required. You can open pageant.exe and load your id_rsa.ppk key manually and provide the password. From now on PuTTY, WinSCP and any program that serves as a fronted for them (like mRemote) will first consult with the Pageant program if there is a key to use for the connection.

You might want to load this key automatically at startup. This can easily be done by using one of the following methods:

  1. Assuming you’ve allowed Pageant to take over the ppk suffix, you should be able to simply add the key files to the Windows “startup” folder.
  2. Create a shortcut to the program that passes the key-files as parameters. For example, the “Target” command for 1 key would look like:
    Pageant
    "%PROGRAMFILES(x86)%\PuTTY\pageant.exe" "%USERPROFILE%\.ssh\id_rsa.ppk"

SSH Agent forwarding

This configuration is optional, but doing it will allow you once you’ve SSH ed into a machine to continue and SSH from it, to the next machine, with the same key. This way you don’t have to put your SSH key on those servers.

Your private key should always stay as close as possible to you!

PuTTY

  • Open PuTTY.
  • Under “Connection” -> “SSH” -> “Auth”.
  • Check the “Allow agent forwarding”.
    Putty forward agent 1
  • Go to the “General Options” by clicking on “Preferences” -> “Preferences”.
    Putty forward agent 2
  • Go back to “Session”
  • Select the “Default Settings” entry.
  • Click on “Save”.

WinSCP

  • In a WinSCP new connection tab, Enable the Advance options checkbox.
  • Go to the “SSH” -> “Authentication”.
  • Check the “Allow agent forwarding” checkbox.
    WinSCP forward agent 1
  • Go to the “General Options” by clicking on “Preferences” -> “Preferences”.
    WinSCP forward agent 2
  • Enable Putty to be invoked with the forwarding option by going into “Integration” -> “Application” and appending the “-A” CLI option.
    WinSCP forward agent 3

Now we can leverage the full power of SSH using PuTTY. However for bash we still have to provide the password for our key each time we open a new bash.

Bash profile

We can solve this by starting an ssh-agent to cache the key.

It can be easily configured by adding following .profile file to your %USERPROFILE% on the same level where you can find your .shh folder.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
declare -x SSH_ENV="$HOME/.ssh/environment"
# start the ssh-agent
function start_agent {
echo "Initializing new SSH agent..."
# spawn ssh-agent
ssh-agent | sed 's/^echo/#echo/' > "${SSH_ENV}"
echo succeeded
chmod 600 "${SSH_ENV}"
. "${SSH_ENV}" > /dev/null
ssh-add
}
# test for identities
function test_identities {
# test whether standard identities have been added to the agent already
ssh-add -l | grep "The agent has no identities" > /dev/null
if [ $? -eq 0 ]; then
ssh-add
# $SSH_AUTH_SOCK broken so we start a new proper agent
if [ $? -eq 2 ];then
start_agent
fi
fi
}
# check for running ssh-agent with proper $SSH_AGENT_PID
if [ -n "$SSH_AGENT_PID" ]; then
ps -f -u "${USERNAME}" | grep "$SSH_AGENT_PID" | grep ssh-agent > /dev/null
if [ $? -eq 0 ]; then
test_identities
fi
else
if [ -f "$SSH_ENV" ]; then
. "$SSH_ENV" > /dev/null
fi
ps -f -u "${USERNAME}" | grep "$SSH_AGENT_PID" | grep ssh-agent > /dev/null
if [ $? -eq 0 ]; then
test_identities
else
start_agent
fi
fi

Now your key will be cached once you have entered the password in bash one time. Each time you close bash and (re)open a new one your key will automatically be loaded.

Your folder structure will look something like this:

1
2
3
4
5
c:\Users\Marco\.profile
c:\Users\Marco\.ssh
c:\Users\Marco\.ssh\id_rsa
c:\Users\Marco\.ssh\id_rsa.ppk
c:\Users\Marco\.ssh\id_rsa.pub

Bonus

Put the contents of your id_rsa.pub key on a Linux server in the following folder: ~/.ssh/authorized_keys

From now on you will automatically login to the server without providing a password.
localhost -ssh -l marco -P 22

On connection your server will show something like following message:

1
2
3
4
5
Using username "marco".
Authenticating with public key "your@email.domain" from agent
Last login: Sat Sep 12 14:48:21 2015 from 192.168.1.33
CoreOS stable (766.3.0)
marco@dockertest ~ $

I hope you will benefit from your SSH on steroids.

No more entering passwords when pushing or pulling Git.
No more putting your private ssh keys on a server or vm.
No more logging in to a vm using a password.
No more passwords when using WinSCP.
Don’t forget to lock your computer, since your key is cached now!

Share