Best way to use multiple SSH private keys on one client [closed] - ssh

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about a specific programming problem, a software algorithm, or software tools primarily used by programmers. If you believe the question would be on-topic on another Stack Exchange site, you can leave a comment to explain where the question may be able to be answered.
Closed 2 years ago.
Improve this question
I want to use multiple private keys to connect to different servers or different portions of the same server (my uses are system administration of server, administration of Git, and normal Git usage within the same server). I tried simply stacking the keys in the id_rsa files to no avail.
Apparently a straightforward way to do this is to use the command
ssh -i <key location> login#server.example.com
That is quite cumbersome.
Any suggestions as to how to go about doing this a bit easier?

From my .ssh/config:
Host myshortname realname.example.com
HostName realname.example.com
IdentityFile ~/.ssh/realname_rsa # private key for realname
User remoteusername
Host myother realname2.example.org
HostName realname2.example.org
IdentityFile ~/.ssh/realname2_rsa # different private key for realname2
User remoteusername
Then you can use the following to connect:
ssh myshortname
ssh myother
And so on.

You can instruct ssh to try multiple keys in succession when connecting. Here's how:
$ cat ~/.ssh/config
IdentityFile ~/.ssh/id_rsa
IdentityFile ~/.ssh/id_rsa_old
IdentityFile ~/.ssh/id_ed25519
# ... and so on
$ ssh server.example.com -v
....
debug1: Next authentication method: publickey
debug1: Trying private key: /home/example/.ssh/id_rsa
debug1: read PEM private key done: type RSA
debug1: Authentications that can continue: publickey
debug1: Trying private key: /home/example/.ssh/id_rsa_old
debug1: read PEM private key done: type RSA
....
[server ~]$
This way you don't have to specify what key works with which server. It'll just use the first working key.
Also you would only enter a passphrase if a given server is willing to accept the key. As seen above ssh didn't try to ask for a password for .ssh/id_rsa even if it had one.
Surely it doesn't outbeat a per-server configuration as in other answers, but at least you won't have to add a configuration for all and every server you connect to!

The answer from Randal Schwartz almost helped me all the way.
I have a different username on the server, so I had to add the User keyword to my file:
Host friendly-name
HostName long.and.cumbersome.server.name
IdentityFile ~/.ssh/private_ssh_file
User username-on-remote-machine
Now you can connect using the friendly-name:
ssh friendly-name
More keywords can be found on the OpenSSH man page. NOTE: Some of the keywords listed might already be present in your /etc/ssh/ssh_config file.

The previous answers have properly explained the way to create a configuration file to manage multiple ssh keys. I think, the important thing that also needs to be explained is the replacement of a host name with an alias name while cloning the repository.
Suppose, your company's GitHub account's username is abc1234.
And suppose your personal GitHub account's username is jack1234
And, suppose you have created two RSA keys, namely id_rsa_company and id_rsa_personal. So, your configuration file will look like below:
# Company account
Host company
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_company
# Personal account
Host personal
HostName github.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_personal
Now, when you are cloning the repository (named demo) from the company's GitHub account, the repository URL will be something like:
Repo URL: git#github.com:abc1234/demo.git
Now, while doing git clone, you should modify the above repository URL as:
git#company:abc1234/demo.git
Notice how github.com is now replaced with the alias "company" as we have defined in the configuration file.
Similary, you have to modify the clone URL of the repository in the personal account depending upon the alias provided in the configuration file.

ssh-add ~/.ssh/xxx_id_rsa
Make sure you test it before adding with:
ssh -i ~/.ssh/xxx_id_rsa username#example.com
If you have any problems with errors sometimes changing the security of the file helps:
chmod 0600 ~/.ssh/xxx_id_rsa

Generate an SSH key:
$ ssh-keygen -t rsa -C <email1#example.com>
Generate another SSH key:
$ ssh-keygen -t rsa -f ~/.ssh/accountB -C <email2#example.com>
Now, two public keys (id_rsa.pub, accountB.pub) should be exists in the ~/.ssh/ directory.
$ ls -l ~/.ssh # see the files of '~/.ssh/' directory
Create configuration file ~/.ssh/config with the following contents:
$ nano ~/.ssh/config
Host bitbucket.org
User git
Hostname bitbucket.org
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa
Host bitbucket-accountB
User git
Hostname bitbucket.org
PreferredAuthentications publickey
IdentitiesOnly yes
IdentityFile ~/.ssh/accountB
Clone from default account.
$ git clone git#bitbucket.org:username/project.git
Clone from the accountB account.
$ git clone git#bitbucket-accountB:username/project.git
Note: Because of the User git directive, you can omit the git# portion of the repo URL, shortening your clone command like so:
$ git clone bitbucket-accountB:username/project.git
This is the only purpose of that directive. If you don't need it (e.g. you always copy-paste the git clone command from the website), you can leave it out of the config.
See More Here

I would agree with Tuomas about using ssh-agent. I also wanted to add a second private key for work and this tutorial worked like a charm for me.
Steps are as below:
$ ssh-agent bash
$ ssh-add /path.to/private/key e.g ssh-add ~/.ssh/id_rsa
Verify by $ ssh-add -l
Test it with $ssh -v <host url> e.g ssh -v git#assembla.com

Now, with the recent version of Git, we can specify sshCommand in the repository-specific Git configuration file:
[core]
repositoryformatversion = 0
filemode = true
bare = false
logallrefupdates = true
sshCommand = ssh -i ~/.ssh/id_rsa_user
[remote "origin"]
url = git#bitbucket.org:user/repo.git
fetch = +refs/heads/*:refs/remotes/origin/*

For me on MacOs, the only working solution was to simply add this in file ~/.ssh/config:
Host *
IdentityFile ~/.ssh/your_ssh_key
IdentityFile ~/.ssh/your_ssh_key2
IdentityFile ~/.ssh/your_ssh_key3
AddKeysToAgent yes
your_ssh_key is without any extension. Don't use .pub.

I had run into this issue a while back, when I had two Bitbucket accounts and wanted to had to store separate SSH keys for both. This is what worked for me.
I created two separate ssh configurations as follows.
Host personal.bitbucket.org
HostName bitbucket.org
User git
IdentityFile /Users/username/.ssh/personal
Host work.bitbucket.org
HostName bitbucket.org
User git
IdentityFile /Users/username/.ssh/work
Now when I had to clone a repository from my work account - the command was as follows.
git clone git#bitbucket.org:teamname/project.git
I had to modify this command to:
git clone git#**work**.bitbucket.org:teamname/project.git
Similarly the clone command from my personal account had to be modified to
git clone git#personal.bitbucket.org:name/personalproject.git
Refer this link for more information.

Use ssh-agent for your keys.

Here is the solution that I used inspired from the answer of sajib-khan. The default configuration is not set; it's my personal account on GitLab and the other specified is my company account. Here is what I did:
Generate the SSH key
ssh-keygen -t rsa -f ~/.ssh/company -C "name.surname#company.com"
Edit the SSH configuration
nano ~/.ssh/config
Host company.gitlab.com
HostName gitlab.com
PreferredAuthentications publickey
IdentityFile ~/.ssh/company
Delete the cached SSH key(s)
ssh-add -D
Test it!
ssh -T git#company.gitlab.com
Welcome to GitLab, #hugo.sohm!
ssh -T git#gitlab.com
Welcome to GitLab, #HugoSohm!
Use it!
Company account
git clone git#company.gitlab.com:group/project.git
Personal/default account
git clone git#gitlab.com:username/project.git
Here is the source that I used.

For those who are working with aws I would highly recommend working with EC2 Instance Connect.
Amazon EC2 Instance Connect provides a simple and secure way to connect to your instances using Secure Shell (SSH).
With EC2 Instance Connect, you use AWS Identity and Access Management (IAM) policies and principles to control SSH access to your instances, removing the need to share and manage SSH keys.
After installing the relevant packages (pip install ec2instanceconnectcli or cloning the repo directly) you can connect very easy to multiple EC2 instances by just changing the instance id:
What is happening behind the scenes?
When you connect to an instance using EC2 Instance Connect, the Instance Connect API pushes a one-time-use SSH public key to the instance metadata where it remains for 60 seconds. An IAM policy attached to your IAM user authorizes your IAM user to push the public key to the instance metadata.
The SSH daemon uses AuthorizedKeysCommand and AuthorizedKeysCommandUser, which are configured when Instance Connect is installed, to look up the public key from the instance metadata for authentication, and connects you to the instance.
(*) Amazon Linux 2 2.0.20190618 or later and Ubuntu 20.04 or later comes preconfigured with EC2 Instance Connect.
For other supported Linux distributions, you must set up Instance Connect for every instance that will support using Instance Connect. This is a one-time requirement for each instance.
Links:
Set up EC2 Instance Connect
Connect using EC2 Instance Connect
Securing your bastion hosts with Amazon EC2 Instance Connect

You can create a configuration file named config in your ~/.ssh folder. It can contain:
Host aws
HostName *yourip*
User *youruser*
IdentityFile *idFile*
This will allow you to connect to machines like this
ssh aws

As mentioned on a Atlassian blog page,
generate a config file within the .ssh folder, including the following text:
#user1 account
Host bitbucket.org-user1
HostName bitbucket.org
User git
IdentityFile ~/.ssh/user1
IdentitiesOnly yes
#user2 account
Host bitbucket.org-user2
HostName bitbucket.org
User git
IdentityFile ~/.ssh/user2
IdentitiesOnly yes
Then you can simply checkout with the suffix domain and within the projects you can configure the author names, etc. locally.

Multiple key pairs on GitHub
1.0 SSH configuration file
1.1 Create ~/.ssh/config
1.2 chmod 600 ~/.ssh/config (must)
1.3 Input the following into the file:
Host pizza
HostName github.com
PreferredAuthentications publickey # optional
IdentityFile ~/.ssh/privatekey1
Case A: Fresh new Git clone
Use this command to Git clone:
$ git clone git#pizza:yourgitusername/pizzahut_repo.git
Note: If you want to change the host name “pizza” of .ssh/config in the future, go into the Git cloned folder, edit .git/config file URL line (see case B)
Case B: Already have Git clone folder
2.1 Go to the cloned folder, and then go into the .git folder
2.2 Edit configuration file
2.3 Update the URL from *old to new:
(Old) URL = git#github.com:yourgitusername/pizzahut_repo.git
(New) URL = git#pizza:yourgitusername/pizzahut_repo.git

IMPORTANT: You must start ssh-agent
You must start ssh-agent (if it is not running already) before using ssh-add as follows:
eval `ssh-agent -s` # start the agent
ssh-add id_rsa_2 # Where id_rsa_2 is your new private key file
Note that the eval command starts the agent on Git Bash on Windows. Other environments may use a variant to start the SSH agent.

On Ubuntu 18.04 (Bionic Beaver) there is nothing to do.
After having created an second SSH key successfully the system will try to find a matching SSH key for each connection.
Just to be clear you can create a new key with these commands:
# Generate key make sure you give it a new name (id_rsa_server2)
ssh-keygen
# Make sure ssh agent is running
eval `ssh-agent`
# Add the new key
ssh-add ~/.ssh/id_rsa_server2
# Get the public key to add it to a remote system for authentication
cat ~/.ssh/id_rsa_server2.pub

I love the approach to set the following in file ~/.ssh/config:
# Configuration for GitHub to support multiple GitHub keys
Host github.com
HostName github.com
User git
# UseKeychain adds each keys passphrase to the keychain so you
# don't have to enter the passphrase each time.
UseKeychain yes
# AddKeysToAgent would add the key to the agent whenever it is
# used, which might lead to debugging confusion since then
# sometimes the one repository works and sometimes the
# other depending on which key is used first.
# AddKeysToAgent yes
# I only use my private id file so all private
# repositories don't need the environment variable
# `GIT_SSH_COMMAND="ssh -i ~/.ssh/id_rsa"` to be set.
IdentityFile ~/.ssh/id_rsa
Then in your repository you can create a .env file which contains the ssh command to be used:
GIT_SSH_COMMAND="ssh -i ~/.ssh/your_ssh_key"
If you then use e.g. dotenv the environment environment variable is exported automatically and whoop whoop, you can specify the key you want per project/directory. The passphrase is asked for only once since it is added to the keychain.
This solution works perfectly with Git and is designed to work on a Mac (due to UseKeychain).

On CentOS 6.5 running OpenSSH_5.3p1 and OpenSSL 1.0.1e-fips, I solved the problem by renaming my key files so that none of them had the default name.
My .ssh directory contains id_rsa_foo and id_rsa_bar, but no id_rsa, etc.

You can try this sshmulti npm package for maintaining multiple SSH keys.

Related

Access to jumpbox as normal user and change to root user in ansible

Here is my situation. I want to access a server through a jumpbox/bastion host.
so, I will login as normal user in jumpbox and then change user to root after that login to remote server using root. I dont have direct access to root in jumpbox.
$ ssh user#jumpbox
$ user#jumpbox:~# su - root
Enter Password:
$ root#jumpbox:~/ ssh root#remoteserver
Enter Password:
$ root#remoteserver:~/
Above is the manual workflow. I want to achieve this in ansible.
I have seen something like this.
ansible_ssh_common_args: '-o ProxyCommand="ssh -W %h:%p -q user#jumpbox"'
This doesnot work when we need to switch to root and login to remote server.
There are a few things to unpack here:
General Design / Issue:
This isn't an Ansible issue, it's an ssh issue/proxy misconfiguration.
A bastion host/ssh proxy isn't meant to be logged into and have commands ran directly on it interactively (like su - root, enter password, then ssh...). That's not really a bastion, that's just a server you're logging into and running commands on. It's not an actual ssh proxy/bastion/jump role. At that point you might as well just run Ansible on the host.
That's why things like ProxyJump and ProxyCommand aren't working. They are designed to work with ssh proxies that are configured as ssh proxies (bastions).
Running Ansible Tasks as Root:
Ansible can run with sudo during task execution (it's called "become" in Ansible lingo), so you should never need to SSH as the literal root user with Ansible (shouldn't ssh as root ever really).
Answering the question:
There are a lot of workarounds for this, but the straightforward answer here is to configure the jump host as a proper bastion and your issue will go away. An example...
As the bastion "user", create an ssh key pair, or use an existing one.
On the bastion, edit the users ~/.ssh/config file to access the target server with the private key and desired user.
EXAMPLE user#bastion's ~/.ssh/config (I cringe seeing root here)...
Host remote-server
User root
IdentityFile ~/.ssh/my-private-key
Add the public key created in step 1 to the target servers ~/.ssh/authorized_keys file for the user you're logging in as.
After that type of config, your jump host is working as a regular ssh proxy. You can then use ProxyCommand or ProxyJump as you had tried to originally without issue.

github deploy key not working for my cyberpanel user

I have a site on CyberPanel, user "thows3051" and want to use git to manage my site. But when I try ssh -T git#github.com I get git#github.com: Permission denied (publickey)..
If I ssh into the server on that user ssh thows3051#mysite.com, into the .ssh directory, there is a thows3051.pub file which I copied the contents into the repo on github under "deploy keys".
EDIT
Was able to explicitly use the correct key with ssh -i ~/.ssh/thows3051 -T git#github.com which shows You've successfully authenticated....
So my question is why isn't the user using the right ssh key?
Thanks in advance
Was able to fix it. I'm not sure what key was being used, if any?
But if you create a file in ~/.ssh/config, you can put the following inside:
IdentityFile ~/.ssh/thows3051
And it will use that key.
Note that you can set specific keys for certain hosts, for example:
Host github.com
IdentityFile ~/.ssh/github.key

Can Ansible be configured to try multiple SSH keys?

I understand that when running an SSH command with public key authentication, the client will try all the SSH keys it knows about until the host accepts one (https://security.stackexchange.com/questions/182804/how-does-ssh-know-which-public-key-to-use-from-authorized-keys).
When running an Ansible command on a host using SSH there does not seem to be this capability: Ansible requires an SSH private key file to be specified explicitly in ansible.cfg:
private_key_file = /user/.ssh/id_rsa_mykey
In my use case, Ansible is running inside a docker container on Lando. All SSH keys are imported from the user's ssh config directory to a known path in the container. However, I don't necessarily know the name of the one that's needed by Ansible because this is something individual users configure.
Is there a way to make SSH commands issued by Ansible try multiple keys like SSH is designed to do?
Ansible requires an SSH private key file to be specified explicitly in ansible.cfg:
Ansible does not require that you provide a private key file in your ansible.cfg. Since ansible is just calling out to ssh, the preferred place to configure connection credentials is in your ~/.ssh/config file. There, you can configure multiple host-specific keys:
Host host1
IdentityFile ~/.ssh/key-for-host1
Host host2
IdentityFile ~/.ssh/key-for-host2
Or you can configure it to try multiple keys in sequence:
Host *.example.com
IdentityFile ~/.ssh/maybe-this-one
IdentityFile ~/.ssh/okay-how-about-this-instead
And of course ssh will use any keys present in your ssh agent.

GitHub multiple accounts: Can authenticate SSH with both accounts, but cannot clone repositories of one

I'm on my work computer, which is already [successfully] configured to connect to our GitHub account and authenticate our commits using SSH and GPG keys, respectively. Before I began changing things, my original ~/.ssh/config file was this:
Host *
AddKeysToAgent yes
UseKeychain yes
IdentityFile ~/.ssh/id_rsa
To add my personal account, I generated a new SSH key (~/.ssh/id_rsa_personal), added the .pub part to my personal GitHub account, and modified my ~/.ssh/config file to the following:
# Default
Host *
AddKeysToAgent yes
UseKeychain yes
# Personal
Host github.com-PERSONAL
HostName github.com
User git
PreferredAuthentications publickey
IdentityFile ~/.ssh/id_rsa_personal
# Work
Host github.com
HostName github.com
IdentityFile ~/.ssh/id_rsa
After this change, I am still able to interact with my work account without a problem – nothing has changed. However, when I attempt to interact with my personal account using
git clone git#github-PERSONAL:nikblanchet/myrepository.git
, I am getting an error message:
Cloning into 'myrepository'...
ssh: Could not resolve hostname github-personal: nodename nor servname provided, or not known
fatal: Could not read from remote repository.
Please make sure you have the correct access rights
and the repository exists.
To narrow down the issue, I decided to try a simple SSH authentication
ssh -T git#github.com-PERSONAL
, and, surprisingly, it worked!
Hi nikblanchet! You've successfully authenticated, but GitHub does not provide shell access.
(Running ssh -T git#github.com authenticated with my work account, as expected.)
So now I'm lost. Why can ssh -T resolve the hostname while git clone cannot? What did I miss?
You URL should be:
github.com-PERSONAL:nikblanchet/myrepository.git
You tried first
git#github-PERSONAL:nikblanchet/myrepository.git
That is why it was not able to resolve github-PERSONAL, which is not in your config file.
github.com-PERSONAL is.
Note: no need to add the git# part: your config file does specify the User git already.

Breaking agent forwarding in Ansible on Vagrant

Using Ansible to provision Vagrant box, Ansible fails when cloning Git repo: Host key verification failed. fatal: Could not read from remote repository.. Oddly I can clone from Git with no issues when I SSH into the box and run git clone <GIT_URL>. Have set sudo: no in Ansible task but still fails. ssh-agent is running correctly on both host and box.
Host key verification failed.
is not related to the agent forwarding. As noted in the comments, it is related to the known_hosts file.
Before the first connection to the server (github.com), you need to manually verify it's host key, or use similar process as noted in comments, using keyscan:
ssh-keyscan -H github.com >> ~/.ssh/known_hosts
The other (not recommended) possibility is to turn off the host key verification in the ~/.ssh/config:
Host git
StrictHostKeyChecking no
UserKnownHostsFile /dev/null
in the home directory of the user running the git clone.