SSH forwarding methods

SSH forwarding methods

David WORMS

By David WORMS

Nov 11, 2024

Categories
DevOps & SRE
Tags
Bash
DevOps
Do you like our work......we hire!

Never miss our publications about Open Source, big data and distributed systems, low frequency of one email every two months.

For teaching purposes at Adaltas, we provide isolated container for our students. Students are provided with a common SSH connection and are redirected to a dédicated container running inside one of our servers accessible from the internet. For example, the gollum user connect with SSH to the middle.land.org public server and ends up inside the misty-mountains container.

There are multiple methods to forward the SSH connection from one host to another. But after researching for some instructions, we noticed that there were surprisingly few pages covering this subject.

Four different methods of SSH forwarding are presented to enable secure remote access through an intermediary server: direct SSH chaining, sshd configuration, Bash startup files, and SSH tunneling.

Network scheme

In the article, we will consider a network scheme where the client connects from a local host to a target host in a private network via a remote host exposed to the internet.

Network overview

Below, we use the REMOTE_USER, REMOTE_HOST, TARGET_USER, and TARGET_HOST variables for the remote and the target user and host accordingly. It is also assumed, the SSH identity keys are correctly configured on all the hosts.

REMOTE_USER="<to_be_completed>"
REMOTE_HOST="<to_be_completed>"
TARGET_USER="<to_be_completed>"
TARGET_HOST="<to_be_completed>"

Method 1 - Running SSH over SSH in a single command

The ssh command supports the optional command argument. When provided, the command is executed on the remote host instead of prompting a login shell. To run SSH over SSH, simply run the command like this:

ssh -t $REMOTE_USER@$REMOTE_HOST ssh $TARGET_USER@$TARGET_HOST

When an SSH connection to the remote host is established, it executes the next ssh command. The -t flag forces pseudo-tty allocation. In case you don’t specify it, you will be prompted with the warning Pseudo-terminal will not be allocated because stdin is not a terminal. and your terminal will not be working properly.

This command is equivalent to running ssh commands sequentially.

ssh $REMOTE_USER@$REMOTE_HOST
ssh $TARGET_USER@$TARGET_HOST

You can even make a chain of multiple SSH forwardings. Every ssh command besides the last one must be called with the -t flag:

ssh \
  -t $REMOTE_USER@$REMOTE_HOST ssh \
  -t $TARGET_USER@$TARGET_HOST ssh \
  $NEXT_TARGET_USER@$NEXT_TARGET_HOST

Pros and cons

This is the most straightforward method to redirect the SSH connection. For the end-user, it requires knowledge of the internal network and providing it to the command.

Method 2 - Running SSH over SSH configuring sshd_config

sshd_config is sshd server system-wide configuration file. Usually, it is located in the /etc/ssh/ directory.

The ForceCommand keyword forces execution of a command in the argument. It is executed on the remote host after the SSH authentication. To apply this rule only to a specific user, you can use the Match keyword to introduce a conditional block with the User criteria.

On the remote host, enrich the /etc/ssh/sshd_config configuration or create a new file inside the /etc/ssh/sshd_config.d/ directory. Restart the sshd service to apply the configuration:

# Configuration
cat <<CONF | sudo tee /etc/ssh/sshd_config.d/forwarding.conf
Match User $REMOTE_USER
	ForceCommand ssh $TARGET_USER@$TARGET_HOST
CONF
# Changes application
sudo systemctl restart sshd

Now, to access to the target host from the local one, you can simply run the basic SSH command.

ssh $REMOTE_USER@$REMOTE_HOST

Pros and cons

Using this method allows simplifying the command for the end-user to connect to the target host. However, it requires modifications of the global configuration file, which might be overwhelming when you configure such rules for multiple users and connecting them to different target hosts.

Method 3 - Running SSH over SSH configuring Bash startup files

When Bash is invoked as a login shell, it first reads and executes commands from the Bash startup files. The order of these files execution is described in the documentation manual.

The ~/.bash_login file is one of those Bash startup files. It can be used to proceed with an SSH connection to the target host, after SSH login to the remote host. You can create it and put the ssh command like:

ssh $TARGET_USER@$TARGET_HOST

To access to the target host, like in the previous method, you only need to run on your local host the basic ssh command.

ssh $REMOTE_USER@$REMOTE_HOST

Pros and cons

Comparing to others, this method is easier to use and manage. All the settings are made in the user’s home directories on the remote host. This involves less managing efforts when you provision and de-provision access for multiple users.

It also gives automation capabilities. For any provisioning purpose, you can extend the script in a Bash startup file. For example, you can create a Docker container on the fly and then enter inside it. The example bash script in ~/.bash_login can look like this:

# Export container name
export CONTAINER=$USER-container

if [ ! "$(docker ps -aqf name=$CONTAINER)" ]
then
  # Run container if not exists
  docker run -it --name $CONTAINER IMAGE
else
  # Start container if not running
  docker start -i $CONTAINER
fi

# Exit SSH session on container exit
exit

Here, we are constructing a container name basing on the name of the user exported by $USER. Then, we are checking if a container with the given name already exists. In case of not existing, we are creating, starting, and entering inside it using the -it options to allocate pseudo-TTY and to attach STDIN. Otherwise, we are just starting it by attaching STDIN with the -i option.

Finally, when the end-user connects to the remote host via SSH, he is forwarded to an isolated virtual environment running in a Docker container.

Method 4 - SSH local port forwarding (also known as SSH tunneling)

SSH local port forwarding (also referred to as SSH tunneling) allows you to forward a port on the local host to a port on the remote host, which is then forwarded to a port on the target host.

To create a local port forwarding, pass the -L option to the ssh command:

ssh -L [$LOCAL_HOST:]$LOCAL_PORT:$TARGET_HOST:$TARGET_PORT $REMOTE_USER@$REMOTE_HOST

In addition to TARGET_HOST, REMOTE_USER, REMOTE_HOST introduced above, the options used are as follows:

  • [LOCAL_HOST:]LOCAL_PORT: the local IP address and the port number. When LOCAL_HOST is omitted, the default localhost value is used. Any port number greater than 1024 as LOCAL_PORT can be used. Ports numbers less than 1024 are privileged ports and can be used only by root.
  • TARGET_PORT: the port of the target host, by default is 22.

Additionally, it is useful to add the following options to the ssh command:

  • -N: not to execute a remote command when connecting to REMOTE_HOST which is a login shell.
  • -f: tells the ssh command to run in the background to don’t lock the terminal window.

The complete command will look like this:

ssh -N -f -L \
  [$LOCAL_HOST:]$LOCAL_PORT:$TARGET_HOST:$TARGET_PORT \
  $REMOTE_USER@$REMOTE_HOST

After the SSH local port forwarding is created, you can access the target host running ssh with the -p option with the LOCAL_PORT specified above:

ssh $TARGET_USER@localhost -p $LOCAL_PORT

Pros and cons

This method is way more verbose and difficult to use. The end-user must run non-trivial commands and keep the additional process of SSH tunnel running on his local host.

Conclusion

This article presents 4 different methods to forward SSH connection. Some of them are convenient to use as ad hoc commands, others are suitable for automation.

Share this article

Canada - Morocco - France

We are a team of Open Source enthusiasts doing consulting in Big Data, Cloud, DevOps, Data Engineering, Data Science…

We provide our customers with accurate insights on how to leverage technologies to convert their use cases to projects in production, how to reduce their costs and increase the time to market.

If you enjoy reading our publications and have an interest in what we do, contact us and we will be thrilled to cooperate with you.

Support Ukrain