How to use SSH properly and what is SSH Agent Forwarding
Levi Velázquez

Levi Velázquez @levivm

About: Director of Engineering at MO Technologies. Best way to learn is teaching :) Dev.to community moderator.

Joined:
Aug 10, 2018

How to use SSH properly and what is SSH Agent Forwarding

Publish Date: Aug 23 '18
121 22

The SSH (Secure Shell) is widely used to provide secure access to remote systems, we have few ways to do it. Basically, everybody who uses it knows about the routine password access. But, there are some issues with this approach, mainly, it allows brute-force password guessing.

SSH provides better authentication process. We are going to recap basic ways to do SSH and view more advanced options in order to be able to use our ssh keys in the external server without putting them directly over there.

First method is using private/public keys between local machine and the remote one.

Using SSH Public Key access

As we know, if we try to connect to a server using basic SSH. It will prompt interactive shell asking us the password. In order to avoid for the server prompting to enter a password each time that we want to connect. We create a pair of public and private keys.

  1. Start key generation program
$ ssh-keygen -o -a 100 -t ed25519
Enter fullscreen mode Exit fullscreen mode
  1. Enter the path to the file that will hold the key.
$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key(/home/johndoe/.ssh/id_rsa): 
Enter fullscreen mode Exit fullscreen mode

You should enter the path to the file that will hold the key, by default is id_rsa on your .ssh directory.

This will create two files, a private key, and a public one. The public key will have .pub appended to its name.

  1. Enter a passphrase for using your key.

This is passphrase is used to encrypt your key. It will be requested for further connections. You can leave it blank but is strongly discouraged.

Enter passphrase(empty for no passphrase):  <Type the passphrase>
Enter fullscreen mode Exit fullscreen mode
  1. Re-enter your passphrase
Enter same passphrase again: <Type the passphrase>
Your identification has been saved in /home/johndoe/.ssh/id_rsa.
Your public key has been saved in /home/johndoe/.ssh/id_rsa.pub.
The key fingerprint is:
0e:fb:3d:57:71:73:bf:58:b8:eb:f3:a3:aa:df:e0:d1 johndoe@myLocalHost
Enter fullscreen mode Exit fullscreen mode
  1. Verify the results

You should have both keys in your selected directory. If everything went well, we are ready to use ours keys.

  1. Copy the public key on the remote host.

We need to add our public key id_rsa on our remote host, the path is $HOME/.ssh/authorized_keys

  1. Connecting through SSH using our keys
ssh -i ~/.ssh/id_rsa user@our_host_ip
Enter fullscreen mode Exit fullscreen mode

SSH Agent

We already know how to use keys in order to connect through Secure Shell, but, there is an issue, it requires unlocking private key with a secret passphrase upon each connection.

To avoid this, we need to use ssh-agent, a program that runs in background and stores your keys in memory.

  1. Enable ssh-agent
# start the ssh-agent in the background
$ eval "$(ssh-agent -s)"
Agent pid 69599
Enter fullscreen mode Exit fullscreen mode
  1. Add the SSH key to the ssh-agent
$ ssh-add ~/.ssh/id_rsa
Enter fullscreen mode Exit fullscreen mode

If you named your key differently, you need to replace id_rsa with your key name.

Now you can connect to the host, it will ask for passphrase just once. Your next connection would be passphrase free.

ssh -i ~/.ssh/id_rsa user@our_host_ip
Enter fullscreen mode Exit fullscreen mode

By default ssh use id_rsa key, so we can avoid -i ~/.ssh/id_rsa so, we can use

ssh user@our_host_ip
Enter fullscreen mode Exit fullscreen mode

SSH agent forwarding

The previous approach looks like the perfect solution, but what happens if we want to connect to any service that requires our ssh authentication.

Let's say, we need to pull a repo in the remote host using our github keys. We need to repeat previous process but on the host machine. It would be risky if anyone grants access to our host because he could retrieve our private keys and has access to private configured services.

To avoid the previous scenario, we are going to use our final resource: SSH agent forwarding.

SSH agent forwarding can be used to make deploying to a server simple. It allows you to use your local SSH keys instead of leaving keys (without passphrases!) sitting on your server.

Let's configure and test SSH forwarding using github as remote service to pull our code into the host.

Setting up SSH agent forwarding

Remember that we need to already have our key associated with any github repo.

So, let's configure:

  1. Create or open up the file at ~/.ssh/config
  2. Enter the following text, replacing myhost.com with our server domain name or IP
Host myhost.com
  ForwardAgent yes
Enter fullscreen mode Exit fullscreen mode

There is a shortcut to archive this, if we don't want to create a config file, we have another option, using -A flag with the ssh command.

ssh -A user@myhost.com 
Enter fullscreen mode Exit fullscreen mode

-A option enables forwarding of the authentication agent connection.

It means that, it forwards your SSH auth schema to the remote host. So you can use SSH over there as if you were on your local machine.

Testing SSH agent forwarding

In order to test if our agent forwarding is working, let's ssh into our remote host and test it out.

$ ssh app@myhost.com
app@debian:~$ ssh -T git@github.com
Hi levivm! You've successfully authenticated, but GitHub does not provide shell access.
Enter fullscreen mode Exit fullscreen mode

It works. Now we can pull/push against any github repo that we have access to it.

If there something wrong, please, let me know.

Note: you don't forward the key itself, you forward the agent, so basically, you can add many keys as you want. In case your github repo use different keys.

You can check here how to do it
https://superuser.com/questions/1140830/ssh-agent-forwarding-using-different-usernames-and-different-keys

If you like my content or it was helpful, you can motivate me to write more content by buying me a coffee

Comments 22 total

  • Slavius
    SlaviusAug 24, 2018

    Just a note:

    default ssh-keygen does not generate secure enough keys. At least on Ubuntu 18.04 it generates RSA based, 2048 bit key, which is considered weak already.
    While generating 4096 RSA bit key is possible (and may be still required to ssh into systems using old versions of ssh) it is beneficial to switch to shorter but computationaly more expensive elliptic curves like ed25519.

    To further increase security against brute-forcing in case your key was stolen, you should specify to save the key in new format (the old one is really weak) by using -o and additionally to specify to use many KDF function rounds to secure the key using -a 100 or more.

    The final command then should be:

    /usr/bin/ssh-keygen -o -a 100 -t ed25519
    
    Enter fullscreen mode Exit fullscreen mode
    • Levi Velázquez
      Levi VelázquezAug 24, 2018

      Oh, nice to know it, thx a lot, going to update it.

  • Susensio
    SusensioAug 24, 2018

    It says private key has a .pub extension appended, but its the other way around, pub is for public

  • Digital Chris
    Digital ChrisAug 24, 2018

    "The private key will have .pub appended to its name"

    What do I even say to this.

  • Saliya Ekanayake
    Saliya EkanayakeAug 24, 2018

    How to handle the case where your git uses a different key than the one you use to login to the remote host?

    • Levi Velázquez
      Levi VelázquezAug 24, 2018

      You can add keys to SSH Agent Forwarding, so you can use 1 key for sshintg into the remote host and the other one for pulling from github.

      Note: you don't forward the key itself, you forward the agent, so basically, you can add many keys as you want.

      You can check here how to do it
      superuser.com/questions/1140830/ss...

  • Tyler Christian
    Tyler ChristianAug 24, 2018

    This doesn't address dangling agents. Each time you 'eval $(ssh-agent -s)' you are creating a new process. This will leave stranded processes that aren't cleaned up and don't die with timeouts. There is a method to reuse a PID rather than recreating each time.

    • Stephen Woodbridge
      Stephen WoodbridgeJan 22, 2020

      I have this problem also. It would nice to know the correct way to handle this in .bash_login, .profile, .bashrc, .bash_logout files so if an agent already exists, it is reused, or on logout the agent is removed. I often have ssh sessions broken by connection failures so the session is not logged out.

      • Sebastien Levy
        Sebastien LevyAug 20, 2021

        Hey, if it can help, I've a repo containing a tiny script that handle that.
        The way it works is pretty simple: it exposes an alias named ssh-auth that ask to authenticate the first time it is used and then re use an existing agent if invoked in a different terminal. Just, ensure to look at both .bashrc_ssh-auth.sh as well as .bashrc files : github.com/MetaBarj0/configs/tree/....
        Let me know if it helps.

  • Yves Lorenzo
    Yves LorenzoAug 25, 2018

    Is it possible to re-use the same key-pair files with other local machines to access the server?

  • tdpoker
    tdpokerAug 25, 2018

    How to make it as if we access a website, we use the website provided vpn?

  • Luca
    LucaJan 15, 2019

    when I test the agent forwarding with the ssh command to github as in
    $ ssh -T git@github.com
    I get:
    git@github.com: Permission denied (publickey)

    I guess it's not working then...
    any hint on debugging where I might have gone astray? Thanks Levi; useful.

    • Levi Velázquez
      Levi VelázquezMar 15, 2019

      Sorry, I didn't see your comment, you already solved it ?

  • Oleg Gromov
    Oleg GromovMar 1, 2019

    Adding the key to ssh-agent is what I've been missing.
    Thank you Levi!

  • Matthias Hogerheijde
    Matthias HogerheijdeJun 18, 2019

    I would propose mentioning ssh-copy-id over manually editing ~/.ssh/authorized_keys.

    ssh-copy-id takes the same -i argument, so if you use a non-standard location for your key, lets say ~/foo/bar/id_rsa and ~/foo/bar/id_rsa.pub, then

    $ ssh-copy-id -i ~/foo/bar/id_rsa user@remote-machine
    

    will open ssh, ask for password, copy the ~/foo/bar/id_rsa.pub file into ~/.ssh/authorized_keys on the remote.

    Otherwise

    $ ssh-copy-id user@remote-machine
    

    will copy whatever keys it finds to the remote (might be multiple!)

  • CaptDragon
    CaptDragonNov 4, 2019

    You forgot to add the "-A" in your "Testing SSH agent forwarding" example.
    This works great with my Yubikey, thanks!

  • packeteer
    packeteerFeb 25, 2020

    I believe SSH agent forwarding is considered harmful, and it is better to use ProxyCommand instead

Add comment