74

I've been looking for a solution on how I can use multiple ssh keys and I figured out, that it will work with a config file in the .ssh directory, but it doesn't work on windows.

My problem is that I'm using a private key to access a git server, so it looks like this: ssh://git@example.com/directory , it works fine when I'm using TortoiseGit, 'cause there is a possibility to choose the private key.

But I want to use the git rep in my IntelliJ IDEA and there is just the option to use the git native shell and it also works, if I put the key, called id_rsa ,into the .ssh folder. Now I want to use multiple ssh keys (so my key will get the name "id_rsa_test", so how do I configure the .ssh/config file under Windows, that it works with a usual git server?

The most examples I found yet are just for the use with github.

mathew11
  • 3,382
  • 3
  • 25
  • 32
  • related [Specify an SSH key for git push for a given domain](https://stackoverflow.com/q/7927750/9193372) – Syscall Feb 03 '23 at 11:22

6 Answers6

69

If you use "Git for Windows"

>cd c:\Program Files\Git\etc\ssh\

add to ssh_config following:

AddKeysToAgent yes
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_rsa_test

ps. you need ssh version >= 7.2 (date of release 2016-02-28)

LennyLip
  • 1,683
  • 19
  • 19
37

You can use multiple ssh keys on Windows 10 and specify the type of access allowed.

Assuming you have created the ssh secure keys already and they were stored in C:\Users\[User]\.ssh

  1. Open the folder C:\Users\[User]\.ssh

  2. Create the file config (no file extension)

  3. Open the file in a text editor like Notepad, and add these configuration details for the first remote host and user. Keep both CMD and BASH paths or only pick one format. Then copy-and-paste below it for the other host/user combinations and amend as required. Save the file.

    Host [git.domain.com]
    User [user]
    Port [number]
    IdentitiesOnly=yes
    PreferredAuthentications publickey
    PasswordAuthentication no
    # CMD
    IdentityFile C:\Users\[User]\.ssh\[name_of_PRIVATE_key_file]
    # BASH
    IdentityFile /c/Users/[User]/.ssh/[name_of_PRIVATE_key_file]
    
  4. Testing

  • Using Bash (Git for Windows)
    $ ssh -T git@[git.domain.com]
    Welcome to GitLab, @[User]!
    
  • Using Commandline (requires activation of Win 10 OpenSSH Client)
    C:\Users\[User]>ssh -T git@[git.domain.com]
    Welcome to GitLab, @[User]!
    
  1. For troubleshooting use ssh -Tv git@[git.domain.com] (or -Tvv or -Tvvv for higher verbosity levels).
Sven Haile
  • 1,100
  • 11
  • 11
  • 5
    This is a much better answer than the currently accepted one. – dthor Apr 21 '22 at 16:45
  • Perfect solution, but I wonder... Instead of having to connect as [ ssh -T user@git.domain.com ] every time, is there a way to give this configuration an alias? I know this is possible on Linux by giving [ Host ] the desired name and [ Hostname ] the actual address. I tried do this here and failed. – Jorge_Freitas Jun 12 '22 at 07:27
  • @Jorge_Freitas 1) Use `-T` only for testing! 2) Most commonly, use either `ssh user@domain.com` or `ssh -F path/.ssh/config domain.com`. Instead of domain.com, one may use the Host or Hostname mentioned in the config file. E.g. `ssh -F path/.ssh/config test1` 3) In the config file, use `Hostname` (hostname or IP address) or `Host` (connection alias referred to in the ssh command, e.g. test1) or both; see https://stackoverflow.com/a/66562287/5703651. – Sven Haile May 03 '23 at 16:27
  • @Jorge_Freitas The value of Host is the alias! If it's not a domain or IP address. So use `Host myname` and add `HostName git.domain.com`. Then use can simply use `ssh myname`. – Nilpo Jul 30 '23 at 01:09
19

These instructions work fine in Linux. In Windows, they are not working for me today.

I found an answer that helps for me, maybe this will help OP. I kissed a lot of frogs trying to solve this. You need to add your new non-standard-named key file with "ssh-add"! Here's instruction for the magic bullet: Generating a new SSH key and adding it to the ssh-agent. Once you know the magic search terms are "add key with ssh-add in windows" you find plenty of other links.

If I were using Windows often, I'd find some way to make this permanent. https://github.com/raeesbhatti/ssh-agent-helper.

The ssh key agent looks for default "id_rsa" and other keys it knows about. The key you create with a non-standard name must be added to the ssh key agent.

First, I start the key agent in the Git BASH shell:

$ eval $(ssh-agent -s)
Agent pid 6276

$ ssh-add ~/.ssh/Paul_Johnson-windowsvm-20180318
Enter passphrase for /c/Users/pauljohn32/.ssh/Paul_Johnson-windowsvm-20180318:
Identity added: /c/Users/pauljohn32/.ssh/Paul_Johnson-windowsvm-20180318 (/c/Users/pauljohn32/.ssh/Paul_Johnson-windowsvm-20180318)

Then I change to the directory where I want to clone the repo

$ cd ~/Documents/GIT/

$ git clone git@git.ku.edu:test/spr2018.git
Cloning into 'spr2018'...
remote: Counting objects: 3, done.
remote: Compressing objects: 100% (2/2), done.
remote: Total 3 (delta 0), reused 0 (delta 0)
Receiving objects: 100% (3/3), done.

I fought with this for a long long time.

Here are other things I tried along the way

At first I was certain it is because of file and folder permissions. On Linux, I have seen .ssh settings rejected if the folder is not set at 700. Windows has 711. In Windows, I cannot find any way to make permissions 700.

After fighting with that, I think it must not be the problem. Here's why. If the key is named "id_rsa" then git works! Git is able to connect to server. However, if I name the key file something else, and fix the config file in a consistent way, no matter what, then git fails to connect. That makes me think permissions are not the problem.

A thing you can do to debug this problem is to watch verbose output from ssh commands using the configured key.

In the git bash shell, run this

$ ssh -T git@name-of-your-server

Note, the user name should be "git" here. If your key is set up and the config file is found, you see this, as I just tested in my Linux system:

$ ssh -T git@git.ku.edu
Welcome to GitLab, Paul E. Johnson!

On the other hand, in Windows I have same trouble you do before applying "ssh-add". It wants git's password, which is always a fail.

$ ssh -T git@gitlab.crmda.ku.edu
git@gitlab.crmda.ku.edu's password:

Again, If i manually copy my key to "id_rsa" and "id_rsa.pub", then this works fine. After running ssh-add, observe the victory in Windows Git BASH:

$ ssh -T git@gitlab.crmda.ku.edu
Welcome to GitLab, Paul E. Johnson!

You would hear the sound of me dancing with joy if you were here.

To figure out what was going wrong, you can I run 'ssh' with "-Tvv"

In Linux, I see this when it succeeds:

debug1: Offering RSA public key: pauljohn@pols124
debug2: we sent a publickey packet, wait for reply
debug1: Server accepts key: pkalg ssh-rsa blen 279
debug2: input_userauth_pk_ok: fp SHA256:bCoIWSXE5fkOID4Kj9Axt2UOVsRZz9JW91RQDUoasVo
debug1: Authentication succeeded (publickey).

In Windows, when this fails, I see it looking for default names:

debug1: Found key in /c/Users/pauljohn32/.ssh/known_hosts:1
debug2: set_newkeys: mode 1
debug1: rekey after 4294967296 blocks
debug1: SSH2_MSG_NEWKEYS sent
debug1: expecting SSH2_MSG_NEWKEYS
debug1: SSH2_MSG_NEWKEYS received
debug2: set_newkeys: mode 0
debug1: rekey after 4294967296 blocks
debug2: key: /c/Users/pauljohn32/.ssh/id_rsa (0x0)
debug2: key: /c/Users/pauljohn32/.ssh/id_dsa (0x0)
debug2: key: /c/Users/pauljohn32/.ssh/id_ecdsa (0x0)
debug2: key: /c/Users/pauljohn32/.ssh/id_ed25519 (0x0)
debug2: service_accept: ssh-userauth
debug1: SSH2_MSG_SERVICE_ACCEPT received
debug1: Authentications that can continue: publickey,gssapi-keyex,gssapi-with-mic,password
debug1: Next authentication method: publickey
debug1: Trying private key: /c/Users/pauljohn32/.ssh/id_rsa
debug1: Trying private key: /c/Users/pauljohn32/.ssh/id_dsa
debug1: Trying private key: /c/Users/pauljohn32/.ssh/id_ecdsa
debug1: Trying private key: /c/Users/pauljohn32/.ssh/id_ed25519
debug2: we did not send a packet, disable method
debug1: Next authentication method: password
git@gitlab.crmda.ku.edu's password:

That was the hint I needed, it says it finds my ~/.ssh/config file but never tries the key I want it to try.

I only use Windows once in a long while and it is frustrating. Maybe the people who use Windows all the time fix this and forget it.

Community
  • 1
  • 1
pauljohn32
  • 2,079
  • 21
  • 28
  • Confirmed that the ssh-add was the key step I needed to make my Cygwin setup work on Windows. Thank you! One small question, what's the difference between the plain "ssh-agent -s" and the eval? – royappa May 19 '19 at 12:50
14

There is an option IdentityFile which you can use in your ~/.ssh/config file and specify key file for each host.

Host host_with_key1.net
  IdentityFile ~/.ssh/id_rsa

Host host_with_key2.net
  IdentityFile ~/.ssh/id_rsa_test

More info: http://linux.die.net/man/5/ssh_config

Also look at http://nerderati.com/2011/03/17/simplify-your-life-with-an-ssh-config-file/

phts
  • 3,889
  • 1
  • 19
  • 31
  • 3
    Thank you, but I actually tried that, I think that windows does not recognize that config located in ~/.ssh/ , is there a possibility to check that, if git found that file? – mathew11 Oct 09 '14 at 18:20
  • 1
    Try to use environment varible, for example `USERPROFILE`: `IdentityFile %USERPROFILE%/.ssh/id_rsa_test` Or relative path: `IdentityFile id_rsa_test` – phts Oct 09 '14 at 21:41
  • Tried both, none of them worked, I also checked if the env variable %userprofile% is set. Does it even work with windows? I mean, that git bash is like a small "unix shell" , maybe there is an problem or git is looking in another folder for the config file. – mathew11 Oct 10 '14 at 09:32
  • Anyway you can use absolute paths – phts Oct 10 '14 at 09:39
  • 4
    From `man` page: _The file name may use the tilde syntax to refer to a user's home directory or one of the following escape characters: '%d' (local user's home directory), '%u' (local user name), '%l' (local host name), '%h' (remote host name) or '%r' (remote user name)._ - try to use these characters – phts Oct 10 '14 at 09:43
  • 1
    I don't know why it doesn't work. actually git recognizes the config file because if I do a deliberate syntax mistake, it won't even "load". but nevertheless, I tried the unix syntax, an absolute path, relative path. With all these characters in your last post, I actually don't know how to use them. – mathew11 Oct 10 '14 at 11:39
  • so maybe the problem relates to something else? e.g. wrong host which does not associate with appropriate key... – phts Oct 11 '14 at 21:47
  • 2
    On Windows, make sure you are writing to `~/.ssh/config` and not `~/.ssh/config.txt`. By default, filename extensions are hidden on Windows, so this may not be obvious – prusswan Dec 12 '18 at 14:38
7

For me worked only adding the config or ssh_config file that was on the dir ~/.ssh/config on my Linux system on the c:\Program Files\Git\etc\ssh\ directory on Windows.

In some git versions we need to edit the C:\Users\<username>\AppData\Local\Programs\Git\etc\ssh\ssh_config file.

After that, I was able to use all the alias and settings that I normally used on my Linux connecting or pushing via SSH on the Git Bash.

valdeci
  • 13,962
  • 6
  • 55
  • 80
2

Alternate solution: Tell git which identity file shall be used for a certain repository. Therefor you have to replace the default ssh command used by git [1], by an alternate one using the -i option of ssh [2].

  1. Open command line in repository
  2. git config --local core.sshCommand "ssh -i ~/.ssh/<private_key_file>"

[1a] https://git-scm.com/docs/git-config#Documentation/git-config.txt-coresshCommand
[1b] https://git-scm.com/docs/git-config#Documentation/git-config.txt---local
[2] https://www.man7.org/linux/man-pages/man1/ssh.1.html

This was inspired by https://gist.github.com/rbialek/1012262#gistcomment-3730916

fe60
  • 170
  • 1
  • 7