Skip to content

SSH🔗

Preamble🔗

This section provides a basic understanding of SSH and how it can be used to securely connect to remote servers.

It aims to be a general guide, not specific to HP4Health or any other cluster, but the concepts can be applied to any server you have access to.

Introduction🔗

SSH (Secure Shell) is a cryptographic network protocol that allows secure remote login and command execution over an insecure network. It provides a secure way to access and manage remote systems, making it an essential tool for software developers and system administrators.

With SSH, you can securely connect to a remote server or device and perform various tasks, such as executing commands, transferring files, and tunneling network connections. It uses encryption to protect the confidentiality and integrity of data transmitted between the client and the server.

One of the key advantages of SSH is its ability to authenticate users and hosts using public-key cryptography. This means that you can establish a secure connection without relying on passwords, making SSH more resistant to brute-force attacks and unauthorized access.

In addition to remote access, SSH also supports port forwarding, allowing you to securely access services running on remote machines through encrypted tunnels. This feature is particularly useful when working with distributed systems or accessing resources behind firewalls.

Overall, SSH is a powerful and widely-used protocol for secure remote administration and file transfer. Understanding how to use SSH effectively can greatly enhance your productivity and security when working with remote systems.

SSH: Password-based Authentication🔗

Password-based authentication is the most common method of authentication for SSH. When you connect to a remote server using SSH, you are prompted to enter your username and password to authenticate yourself. The server then verifies your credentials and grants access if they are correct.

sequenceDiagram
    participant Client
    participant Server

    Client->>Server: Connection Request
    Server-->>Client: Response
    Client->>Server: Sends Username
    Server-->>Client: Requests Password
    Client->>Server: Sends Password
    Server-->>Server: Checks Password
    Server-->>Client: Secure Connection Established
  1. Client sends connection request: The SSH client initiates a connection to the SSH server.
  2. Server responds: The SSH server responds to the client's connection request.
  3. Client sends username: The client sends the username to the server.
  4. Server requests password: The server prompts the client for a password.
  5. Client sends password: The client sends the password to the server.
  6. Server checks password: The server verifies the password against its stored credentials.
  7. Secure connection established: If the password is correct, a secure, encrypted connection is established between the client and the server.
An analogy to understand the process of password-based authentication is the following:

Imagine two friends, Alice and Bob, who want to start a secure conversation. Alice sends a letter to Bob asking to start a conversation.

However, Bob can't tell if this is really Alice, so he first responds with a letter saying he agrees to start a conversation but initiates a verification process to ensure Alice's identity.

Alice is required to send her codename that uniquely identifies her (username). Bob then requests a secret code (password) to verify Alice's identity. Alice sends the secret code to Bob, who checks it against his records. If the secret code is correct, a secure conversation starts between Alice and Bob.

```mermaid
sequenceDiagram
    participant Alice as Client (Alice)
    participant Bob as Server (Bob)

    Alice->>Bob: Sends a letter asking to start a conversation
    Bob-->>Alice: Responds with a letter saying he agrees
    Alice->>Bob: Sends her name (username)
    Bob-->>Alice: Requests the secret code (password)
    Alice->>Bob: Sends the secret code (password)
    Bob-->>Bob: Checks the secret code against his records
    Bob-->>Alice: Secure conversation starts
```

Try it yourself: use CLI to connect to a remote server🔗

The ssh cli tool is the most common way to connect to a remote server using SSH.

Connect to a remote server:

ssh username@hostname
  • username: The username you use to log in to the remote server.
  • hostname: The hostname or IP address of the remote server.

Connect to a remote server on a specific port:

ssh -p port username@hostname
  • port: The port number on which the SSH server is running (default is 22).

However, password-based authentication has some limitations. Passwords can be vulnerable to brute-force attacks, eavesdropping, and password-guessing attempts. To address these security concerns, SSH also supports public-key authentication, which is more secure and convenient than password-based authentication.

SSH: Public-key Authentication🔗

SSH operates on the client-server model, where the client initiates a connection to the server and authenticates itself using a cryptographic key pair. The server then verifies the client's identity and grants access if the authentication is successful.

sequenceDiagram
    participant Client
    participant Server

    Client->>Server: Connection Request
    Server-->>Client: Response
    Client->>Server: Sends Public Key
    Server-->>Server: Checks if Public Key is in `authorized_keys` file
    Server-->>Client: Sends Session ID Encrypted with Public Key
    Client-->>Client: Decrypts Session ID
    Client->>Server: Sends Decrypted Session ID
    Server-->>Client: Secure Connection Established
  1. Client sends connection request: The SSH client initiates a connection to the SSH server.
  2. Server responds: The SSH server responds to the client's connection request.
  3. Client sends public key: The client sends its public key to the server for authentication.
  4. Server checks public key: The server checks the public key against its authorized keys to verify the client's identity.
  5. Server sends session ID encrypted with public key: If the public key is valid, the server generates a session ID and encrypts it using the client's public key. This ensures that only the client with the corresponding private key can decrypt it.
  6. Client decrypts session ID: The client receives the encrypted session ID and uses its private key to decrypt it.
  7. Client sends decrypted session ID: The client sends the decrypted session ID back to the server as proof of its identity.
  8. Secure connection established: Upon successful verification of the session ID, a secure, encrypted connection is established between the client and the server, allowing for secure communication.
Extending the analogy to understand the process of public-key authentication:

Bob and Alice realize a few security concerns with their current method of communication:

1. **Eavesdropping:** Someone could intercept the secret code (password) while it is being sent from Alice to Bob.
2. **Password-guessing:** Someone could guess the secret code (password) by trying different combinations.
3. **Client Identity verification:** Bob can't be sure that the letter from Alice is really from her.
4. **Server Identity verification:** Alice can't be sure that the letter from Bob is really from him.

To address these concerns, Alice and Bob decide to use a more secure method of communication.

Alice sends Bob a padlock (public key) with an open lock :lock:.

Bob checks the padlock to ensure it matches his records before sending a package :package: with a secret message (session ID) and uses Alice's padlock to lock it. Alice receives the package and uses her key (private key) to unlock it and read the secret message. Alice then sends a confirmation letter to Bob saying she received and read the message. They can now start a secure conversation.

Alice unlocks the box with her key (private key) and reads the secret message. Alice sends a confirmation letter to Bob saying she received and read the message. They can now start a secure conversation.

```mermaid
sequenceDiagram
    participant Alice as Client (Alice)
    participant Bob as Server (Bob)

    Alice->>Bob: Sends a letter asking to start a conversation
    Bob-->>Alice: Responds with a letter saying he agrees
    Alice->>Bob: Sends a padlock (public key) with an open lock
    Bob-->>Bob: Checks the padlock to ensure it matches his records
    Bob-->>Alice: Sends a box with a secret message (session ID) locked with Alice's padlock
    Alice-->>Alice: Unlocks the box with her key (private key) and reads the secret message
    Alice->>Bob: Sends a confirmation letter saying she received and read the message
    Bob-->>Alice: They start a secure conversation
```
But how does the public-key relate to the private-key?

The public key is shared with the server, while the private key is kept secret on the client-side. The public key is used to encrypt data that can only be decrypted by the corresponding private key. This ensures that only the client with the private key can authenticate itself to the server.

The public and private keys are related using asymmetric cryptography, where the public key is derived from the private key but cannot be used to derive the private key. This one-way relationship allows the public key to be shared openly while keeping the private key secure.

Try it yourself: Generate an SSH key pair and connect to a remote server🔗

Generate an SSH key pair:

Start by generating an SSH key pair on your local machine. This creates a public key and a private key that can be used for public-key authentication. The private key is stored in what is commonly referred to as the identity file stored locally (usually in ~/.ssh/id_rsa), while the public key is shared with one or many servers.

ssh-keygen -t rsa -b 4096 -C "your_email@example.com"
  • -t rsa: Specifies the type of key to generate (RSA). Other options include dsa, ecdsa, and ed25519.
  • -b 4096: Specifies the number of bits in the key (4096 bits is recommended for RSA keys).
  • -C "your_email@example.com": Specifies the email address to associate with the key.
  • The command will prompt you to choose a location to save the key pair and set a passphrase to protect the private key.
  • By default, the keys are saved in ~/.ssh/id_rsa (private key) and ~/.ssh/id_rsa.pub (public key).
  • The public key (id_rsa.pub) can be shared with the server for authentication.
  • The private key (id_rsa) should be kept secure and not shared with others.

Copy the public key to the remote server:

ssh-copy-id username@hostname
  • This command copies the public key to the ~/.ssh/authorized_keys file on the remote server.
  • You will be prompted to enter the password for the remote server to complete the process.
  • Once the public key is added to the authorized_keys file, you can authenticate to the server using the private key without entering a password.

Connect to the remote server using public-key authentication:

ssh -i ~/.ssh/id_rsa username@hostname
  • -i ~/.ssh/id_rsa: Specifies the path to the private key file for authentication.

A convenient way to connect to a remote server🔗

Using the cli tool is the most common way to connect to a remote server using SSH. However, you might find yourself getting tired of typing the same command over and over again, forgetting the port number, the username, the path to the private key, etc.

Luckily, you can use the SSH configuration file to customize your SSH client behavior and settings, making it easier to manage and connect to multiple servers.

Best of all, you can set it up to make connecting to a server with public-key authentication, ports, usernames, even proxy jumps as easy as typing ssh myserver.

SSH Configuration File🔗

The SSH configuration file (~/.ssh/config) allows you to customize your SSH client behavior and settings.

This file can be used to define connection parameters, aliases, and shortcuts for remote hosts, making it easier to manage and connect to multiple servers.

  • bonus: you can set up a ProxyJump to connect to a server through a jump host.

Here are the most common configuration options you can set in the SSH configuration file:

Minimal Configuration🔗

If you commonly use the following commmand line to connect to a server:

cli command
ssh john@johns.really.cool.server.com

the following configuration will allow you to connect to the server by simply typing ssh myserver:

equivalent configuration in the SSH configuration file
Host myserver
    HostName johns.really.cool.server.com
    User john           # this will be created by the server administrator
  1. Host: Defines the remote host or alias for the connection.

  2. You can actually call this whatever you want

  3. This is the name you will use to connect to the server

  4. HostName: Specifies the hostname or IP address of the remote server.

  5. This is the actual address of the server

  6. This will be common for all users of the server, also can be an IP address

  7. User: Specifies the username to use when connecting to the remote server.

  8. This is the username that the server administrator has created for you

Advanced Configuration🔗

Port🔗

Connect to a server on a specific port
Host myserver
    HostName johns.really.cool.server.com
    User john
    Port 2222
    IdentityFile ~/.ssh/id_rsa
    ProxyJump jumpserver
Why do some servers require specifying the port?
  • The hostname johns.really.cool.server.com is an alias for the server's IP address, which can be accessed by anyone who knows it, making it susceptible to attacks.
  • Changing the default SSH port (22) to a non-standard port (e.g., 2222) can provide a minor layer of security by reducing the likelihood of automated attacks targeting the default port. This approach is known as "security through obscurity."
  • It is crucial to understand that using a non-standard port is not a comprehensive security measure. Skilled attackers can still discover the port through network scanning tools.
  • Using a non-standard port can help reduce the noise from automated bots and less sophisticated attackers who target the default port.
  • The server administrator must communicate the correct port number to authorized users, adding an additional step for access control.

IdentityFile🔗

Specify the path on the local machine to the private key file for authentication.
Host myserver
    HostName johns.really.cool.server.com
    User john
    Port 2222
    IdentityFile ~/.ssh/id_rsa

Port Forwarding🔗

ProxyJump: Specifies a jump host to connect to the remote server through a proxy.

  • This is useful when the remote server is not directly accessible from your local machine, but you can connect to it through an intermediate server (jump host).
  • This option allows you to establish a connection to the jump host first and then connect to the remote server from there.
Connect to a server through a jump host
Host hpclogin
    HostName someHPCserver.loginnode.com
    User john
    IdentityFile ~/.ssh/id_rsa

Host hpcnode
    HostName someHPCserver.node-14.com # or whatever the node is called
    ProxyJump hpclogin
    User john
    IdentityFile ~/.ssh/id_rsa

Then you can connect to the node using:

ssh hpcnode
What are common examples of using ProxyJump?
  1. Connecting to a server behind a firewall: If the remote server is behind a firewall and only accessible through a jump host, you can use ProxyJump to establish a connection through the jump host.

  2. Connecting to a server in a private network: If the remote server is in a private network and not directly accessible from the internet, you can use ProxyJump to connect to the server through a gateway server that has access to the private network.

Jupyter Lab on Compute Node through port forwarding🔗

The idea here is that since you cant access the compute node directly, you can use the jump server to forward the port to the compute node.

Port forwarding to access Jupyter Lab on a compute node
Host mycompute
    HostName compute-node-14
    User john
    IdentityFile ~/.ssh/id_rsa
    ProxyJump jumpserver
    LocalForward 8888 localhost:8888

Then you can connect to the compute node and forward the port to your local machine using:

ssh mycompute

If the command works, then you can open a browser and go to localhost:8888 to access the Jupyter Lab running on the compute node.