Open and Monitor Multiple SSH Terminals at Once

📅 January 21, 2024
“So many remote hosts, so many logins. Can we automate this?”

Suppose we have multiple remote systems that we need to monitor as a group. Usually, we open a terminal for each remote system, SSH with a password, and then interact with the remote systems to perform updates or htop monitoring.

Wouldn’t it be easier if we could run a script that automatically logs into each remote system via SSH for us and display whatever we want to see in each terminal?

This takes a little time to set up, but we can write a script that does this for us to make the terminal windows appear quickly and in specified positions on the Linux desktop!

This is what we are trying to achieve. In this real-life demonstration, there are six terminal windows, and each is connected to a remote system via SSH. By running a script, these terminals automatically display their respective programs running remotely so we can view them on a single local machine.

Custom Terminal Size and Placement

In the screenshot above, a script opens multiple terminals using gnome-terminal with the geometry option to customize the size and placement of each terminal window. This means that each time the script executes, the terminals will open exactly where we want them to open so we do not have to move them around or hunt for them under other windows.

Custom Programs

Each terminal connects to its own system via SSH, and then each terminal runs a specific command of our choice. Above from the upper left in clockwise rotation, the terminals are displaying neofetch, uprecords, screenfetch, and bpytop for three different systems on the bottom. These programs must be installed and exist on the remote systems as needed.

The Script

#!/bin/bash

# System 1 - Kiwi
gnome-terminal --geometry 100x24+100+100 -- bash -c "ssh 192.168.30.88 -t neofetch && exec bash"
gnome-terminal --geometry 100x46+100-100 -- ssh 192.168.30.88 -t bpytop

# System 2 - Watermelon
gnome-terminal --geometry 100x24+1000+100 -- bash -c "ssh 192.168.30.47 -t uprecords && exec bash"
gnome-terminal --geometry 100x46+1000-100 -- ssh 192.168.30.47 -t bpytop

# System 3 - Pineapple
gnome-terminal --geometry 100x24+1900+100 -- bash -c "ssh 192.168.45.77 -t screenfetch && exec bash"
gnome-terminal --geometry 100x46+1900-100 -- ssh 192.168.45.77 -t bpytop

This is only an example to illustrate how it works with a few important points.

Point 1

Like any bash script, statements are executed from top to bottom in order, so it is important that no command blocks the others from running. Each command shown runs, and then execution immediately proceeds to the next.

Point 2

The script opens terminals using gnome-terminal. xterm should also work if you prefer it. The geometry option allows us to set up the size and position of each terminal window, and this will require trial and error to adjust perfectly.

Point 3

There are two types of programs that run in these terminals: one-shot and full-screen. The one-shot programs, like uprecords, neofetch, and screenfetch, run and then close the window. We want to keep these terminals open, so we must use bash trickery to make this happen since we cannot do this with gnome-terminal itself.

gnome-terminal --geometry 100x24+100+100 -- bash -c "ssh 192.168.30.88 -t neofetch && exec bash"
  • gnome-terminal --geometry 100x24+100+100

This sets up the terminal 100×24 characters in size (the default) at a (100, 100) coordinate on the local desktop.

  • -- bash -c "ssh 192.168.30.88 -t neofetch && exec bash"

This tells gnome-terminal to execute the command that follows the double dashes, which is a standard ssh connection to a remote machine using its IP address on a LAN. The -t neofetch option used with ssh means run neofetch and show the results in the terminal.

Usually, the command runs and then the window closes. We would never have enough time to view the output, so we need to force the window open. This is handled with the && exec bash part. exec bash runs bash again within the same terminal, and, thus, it stays open until we close it. The SSH connection will be closed, but not the terminal. This technique is useful for commands that exit after completion.

Point 4

For full-screen programs, such as bpytop, htop, or slurm, that do not close the window until they quit, there is no need to use the bash trick above. Just run these programs normally using the -t option with ssh.

gnome-terminal --geometry 100x46+100-100 -- ssh 192.168.30.88 -t bpytop

This tells gnome-terminal to run bpytop (a fancy terminal-based system monitoring program) on the given remote system.

Point 5

Each terminal window must be closed manually one by one. For this example, we want this to happen because each terminal is its own connection to a remote system. By keeping them separate from each other, they can be monitored individually. I chose to take this approach instead of writing a more elaborate script that closes them all as a group. How this behavior is handled is up to your needs.

Point 6

The script omits a username for each SSH login. If you need to log into different user accounts, then modify ssh to include the username.

Point 7

If you try to rename the title bar of each gnome-terminal, then it will be overwritten with whatever program/path is current.

gnome-terminal --title 'Kiwi' --geometry 100x46+100-100 -- ssh 192.168.3.8 -t bpytop

The modified title above will not use the tile Kiwi. It will read bpytop when bpytop runs.

Auto SSH Login

So far, this works, but we must enter an SSH password for each remote system we want to log into. This is tedious and time-consuming.

As it stands, each terminal window begs for a password before making the SSH connection.

We can fix this by setting up the remote systems to allow SSH logins without requesting a password. The connection will still be secure because we will copy an RSA public key to each remote system that we want to log into. This allows the terminal to securely log into a remote system without prompting for a password.

Create Local RSA Key Pair

On the local machine from which you want to run the multiple-terminal script, run this:

ssh-keygen -t rsa -b 4096

This creates a 4096-bit OpenSSH asymmetric key pair of id_rsa (the private key) and id_rsa.pub (the public key). Use the defaults and skip entering a passphrase. Take note of the path where the key is saved because you will need this later. By default, these files are created in the .ssh directory in your home.

Copy the RSA Public Key to Each Remote Machine

id_rsa.pub is the public key to copy to each remote machine. Copy the same public key to each remote machine. Do not copy the private key id_rsa. Keep that on your local machine.

ssh-copy-id -i ~/.ssh/id_rsa.pub username@192.168.30.88

ssh-copy-id -i ~/.ssh/id_rsa.pub username@192.168.30.47

ssh-copy-id -i ~/.ssh/id_rsa.pub username@192.168.45.77

Replace username with the name of the user you log in as on the remote systems. In each case, you must provide the correct password before the public key is copied to the remote machine, so security is not compromised. You must still authenticate yourself to the remote system in order to set this up. id_dsa.pub must be copied to each remote system. Each key copy process should show a message similar to this if successful (your exact results will be different):

ssh-copy-id is a tool that copies our public RSA key to the remote system so we no longer need to enter a password to log in.

The purpose of doing this is to avoid entering a password when logging in via SSH. Try logging in to a remote system now (check that you are not already logged in).

ssh username@192.168.30.88

You should automatically log into the machine without needing to enter a password. If so, good. But if you are still prompted for a password, then something went wrong or is not configured properly. It could be anything, so I cannot possibly troubleshoot here. At first, this did not work for me, but after some trial and error I discovered that I had generated a DSA pair, not an RSA pair. When I created an RSA key pair and used ssh-copy-id to transfer it to each remote machine, then password-less logins worked. No need to restart the systems or ssh service.

But if you do need to edit some config files, look at /etc/ssh/sshd_config on each remote machine first. Also, make sure openssh-server is installed on the remote systems. (Of course, if openssh-server is missing, then you cannot log in remotely anyway.)

Assuming SSH keys are working, try running the script again.

Voila! All windows automatically appear without needing to enter any passwords in order to connect to the remote systems using SSH. Remote system monitoring appears like magic.

Conclusion

I have found this technique to be incredibly useful, and I find it handy for everything from performing system updates to monitoring multiple systems from scripts. It saves time and typing.

Have fun!

, ,

  1. Leave a comment

Leave a comment