SSH Configuration#


We will go over 2 cases:

  1. Remote Server

  2. Remote Server with a ProxyJump


Table of Conents#

  • Table of Conents

  • SSH

    • IdentityFile

    • Port Forwarding

    • Background SSH Tunneling

    • Closing Background SSH Tunnels

    • Advanced Users - Bash Script

      • SSH Process Background

      • Closing Ports

  • SSH Config File

  • Remote Server (Cal1)

    • Important Arguments

      • IdentityFile

      • ForwardX11

      • LocalForward

  • Remote Server + ProxyJump

    • ProxyJump

    • Example: Gricad

    • Example: JeanZay

    • Internal SSH Key


SSH#

The simplest thing to do would be to just ssh into the remote server. You just need a username and server.

ssh username@server

This should work with your password. However, there are some essential things missing that we will need in order to use more features. Some include:

  • Permissions - no more passwords + more security

  • Tunneling - to be able to see applications that are hosted on the server

  • Proxy Jumping - to be able to ssh into a remote server on a remote server

The remainder of this section will talk about the extra flags we need to in order to accomplish this.


IdentityFile#

This is important so we don’t have to keep typing import our password all of the time… This can be alleviated with an ssh key. We can generate this with ssh-keygen and then copy it over to the remote server using ssh-copy-id.

Please see the detailed Instructions for how to use ssh-keygen to generate a new SSH key and copy it over to your remote server. Below are some brief instructions for how to do it.

Step 1: Generate the Key

ssh-keygen -t rsa -b 4096 -f /path/to/id_key

Step 2: Forward Key to remote server. You will have to enter your password once - and then never again :).

ssh-copy-id -i /path/to/id_key username@server

Now we should be able to log in with a specified key and we won’t have to enter our password.

ssh username@server -i /path/to/id_key_file

Port Forwarding#

We need to create a tunnel especially if we have applications running on the remote server and we want access to the content. This can be done using the -L flag along with the appropriate ports.

ssh username@server -L 8888:localhost:8888

Note: You may have to change the port number from 8888 to something else.

Check this blog for details about how port forwarding (ssh-tunneling) works.


Background SSH Tunneling#

Often times we don’t want to have the connection open occupying our terminal. So we can put it in the background where we don’t need to worry about it. This can be done with the -f to ensure that it is executed but stays in the background.

# create a tunnel
ssh -fN username@server -L 8888:localhost:8888 

Closing Background SSH Tunnels#

When you’re done, it’s good practice to make sure you close the ssh-tunnel that you opened. Below, I have some steps to do this in a relatively efficient way. It is a bit tedious to type everything out from scratch but later we can automate this so that we don’t have to keep typing in all of the commands. First we need to find all of the background processes that have an ssh.

ps aux | grep ssh | grep "localhost"

We can narrow the search to only those that have a local host attached.

ps aux | grep ssh | grep "8888:localhost:8888"

Then we can kill the process assigned here

# kill that process manually by looking
kill -9 PID
# kill all processes with localhost
ps aux | grep ssh | grep "localhost" | awk '{print $2}' | xargs kill
# kill a specific one
ps aux | grep ssh | grep "8888:localhost:8888" | awk '{print $2}' | xargs kill

These commands are a cumbersome but they get the job done. I would strongly suggest you continue to the next section and try to use some of the scripts in your own workflow. It will make for a much more pleasant experience.


Advanced Users - Bash Script#

We want to automate a few of the things listed above. It’s too much to type all of that every time. In particular, we will automate:

  • Opening up the SSH and Tunneling in the background

  • Closing specific and all background ports

SSH Process Background#

We want to automate the ssh tunnel process in the background.

# syntatic sugar for launching ssh tunnel given a server and a port
function ssh_tunnel_bg(){
    server="$1"
    port="$2"
    echo "server:" $1
    echo "port:" $2
    ssh -fN $server -L "$port":localhost:"$port"
}

Demo Usage:

ssh_tunnel_bg 8888 meom_cal1

Much simpler and we don’t have to remember all of the commands. It is a bit of syntatic sugar but it’s more understandable.

Closing Ports#

Now we want to automate the removal of ports. I would suggest adding these functions to your .profile or .bash_profile so that you can just use these easier to find and kill ssh background processes.

# function to show all background ssh processes
# demo:
# > show_all_bg_ssh
#
function show_all_bg_ssh(){
    ps aux | grep ssh | grep "localhost"
}
# function to show background ssh processes given a localport
# demo:
# > show_bg_ssh 8888
#
function show_bg_ssh(){
    ps aux | grep ssh | grep $1
}

# function to kill background ssh process given a localport number
# demo:
# > kill_bg_ssh 8888
#
function kill_bg_ssh(){
    ps aux | grep ssh | grep $1 | awk '{print $2}' | xargs kill
}

# function to kill all background ssh processes
# demo:
# > kill_all_bg_ssh
#
function kill_all_bg_ssh(){
    ps aux | grep ssh | grep "localhost" | awk '{print $2}' | xargs kill
}

Demo Usage: Kill a Specific Port

# find the background process
show_bg_sh 8888

# kill the background process
kill_bg_sh 8888

Demo Usage: Kill Everything

# find the background process
show_all_bg_sh

# kill the background process
kill_all_bg_sh

SSH Config File#

It ups your game to the next level if you use an ssh config file.

More resources:

We typically store this here:

/home/user/.ssh/config

where it’s visible from anywhere in on your computer.


Remote Server (Cal1)#

In this example, we will showcase how to automate the connection to

We can automate this using using

Host cal1
    HostName ige-meom-cal1.u-ga.fr
	User username
	# Allow for Ids
	ForwardX11 yes
	# SSH Identity File
	IdentityFile ~/.ssh/id_key_file
	# Jupyter Notebooks
	LocalForward 8888 localhost:8888

Host *
  AddKeysToAgent yes
  UseKeychain yes
  IdentityFile ~/.ssh/id_key_file

Demo Usage:

Test the connection to cal1.

ssh cal1

Now it is much easier to ssh into the remote server without having to do all of the extra stuff.


Important Arguments#

There are many important arguments that make our lives a lot easier if they are defined properly.

IdentityFile#

This will point to the identity_file found in your local server. This removes the need to authenticate every time you log in. It’s hard to remember passwords all of the time so this removes that necessity. It’s also more secure due to the encryption.

Note: Never share this .pub with anyone! It should be kept on your personal computer only.

ForwardX11#

This allows us to have some visual bits and pieces. This is important for matlab GUIs and even GUIs for spyder.

LocalForward#

This takes care of all of the port forwarding. You can also forward multiple ports if there is a reason, e.g. 1 for tensor board, 1 for JupyterLab, 1 for some visualization software, etc.


Remote Server + ProxyJump#

In this case, we will look at the configuration for gricad and jeanzay. In this case, we have a head node (not really useful except to enter into the server). And then later we proxy jump to the actual head node for computing.

Host server1
  HostName base_server
	User username

Host server2
  HostName server
  User username
  ProxyJump server1

ProxyJump#

This is the only extra command is the ProxyJump command. This allows


Example: Gricad#

In gricad they have a weird system where they have a entry node which you ssh into. And then you need to ssh into a compute node, e.g. dahu, bigfoot, etc. So this means we need to proxyjump to dahu via entrynode.

Below is an example of the .ssh/config file with these arguments already in place.

Host gricad
	User username
	HostName access-gricad.univ-grenoble-alpes.fr
	IdentityFile ~/.ssh/id_rsa_gricad

# DAHU 
Host dahu_gricad
	User johnsonj
	HostName dahu
	ProxyJump gricad
	IdentityFile ~/.ssh/id_rsa_gricad

Example Usage:

ssh dahu_gricad

This is much simpler than having to do the proxy jumps.

On the gricad docs they have a similar command which uses your <pereseus-login>. I have included it below for a side-by-side comparison with my version.

It’s apparently transparent but I really don’t understand the ProxyCommand they put in place. I think it is much harder to understand compared to my version. I have yet to see any differences in performance from their command and my own.


Example: JeanZay#

In jeanzay the permissions are a bit crazy. It doesn’t work to just ssh directly to jeanzay without some sort of hassle and special permissions with custom ips registered in their system. Instead, it’s much easier to just ssh into the cal1 server. Then we can ssh from there into the jeanzay server. So this means we need to proxyjump to jeanzay via cal1.

Below is an example of the .ssh/config file with these arguments already in place.

Host cal1
  HostName ige-meom-cal1.u-ga.fr
	User username
	IdentityFile ~/.ssh/id_key_file
	LocalForward 8888 localhost:8888

# JEANZAY Head Node
Host jean_zay
    User username
    HostName jean-zay.idris.fr
    ProxyJump cal1
    IdentityFile ~/.ssh/id_key_file
    LocalForward 8880 localhost:8880

Demo Usage:

ssh jean_zay

As you can see, this allows us to log into jeanzay in a much simpler manner.


Internal SSH Key#

I would recommend to generate a ssh-key on the proxy server as well. This will be useful for transferring files and mounting drives for the server. Follow the same instructions as above (ssh-keygen + ssh-copy-id) and generate a .ssh/config file similar to the one below.

Host jean_zay
    User username
    HostName jean-zay.idris.fr
    IdentityFile ~/.ssh/id_jz

Demo Usage:

# ssh into proxy server
ssh meom_cal1
# ssh into the other server
ssh jean_zay

Note: This is the same as ssh jean_zay on the local server via the proxy jump.