SSH Tips: Key-Based Authentication, Remote Commands without Interactive Login, and SSHFS

SSH is an important and commonly-used tool for remote shell access to Linux and Unix systems. This post will cover some tips for effectively using SSH and the closely-related SSHFS to run commands and access files on a remote host.

We’ll work with a pair of client and server computers running a Red Hat or Debian-based Linux distribution, then configure key-based authentication between the two. We’ll then use SSH to login to the server from the client (without using a password!), look at how we can run commands on our server without interactively logging in, then use SSHFS to remotely mount the server’s filesystem to our client computer. Most of the commands described will need to be run with superuser privileges, either by prefacing them with sudo or using the su command to switch to a superuser account.

Key-Based Authentication

First, we’ll want to ensure the SSH daemon is running on our server with the systemctl status sshd command. If the sshd service is not running or enabled, we may need to start it on a one-off basis (systemctl start sshd), enable it (systemctl enable sshd if we want the service to start persistently in the future when the server is rebooted), and/or install it (if it’s missing entirely – yum install openssh-server for Red Hat-based distros or apt install openssh-server for Debian-based distros should do the trick in this case).

Once we know the sshd service is running on the server, we can head back to our client to configure key-based authentication. This enables us to store a private encryption key on the client side, upload a corresponding public key to the server, then use these two keys to authenticate and communicate via SSH with the server.

The ssh-keygen command generates the private and public keys (using a random “seed” value), then prompts us to secure the key pair with a passphrase. This is not necessary, but can be used to provide an additional layer of protection.

user@CLIENTPC:~$ ssh-keygen
Generating public/private rsa key pair.
Enter file in which to save the key (/home/user/.ssh/id_rsa):
Enter passphrase (empty for no passphrase):
Enter same passphrase again:
Your identification has been saved in /home/user/.ssh/id_rsa.
Your public key has been saved in /home/user/.ssh/id_rsa.pub.
The key fingerprint is: (fingerprint here)
The key’s randomart image is:
(randomart image here)

Next, we use the ssh-copy-id command to upload the public key to the server. The key is stored in the ~/.ssh/authorized_keys directory for the target user account on the server.

user@CLIENTPC:~$ ssh-copy-id user@SERVERPC
/usr/bin/ssh-copy-id: INFO: Source of key(s) to be installed: “/home/user/.ssh/id_rsa.pub”
/usr/bin/ssh-copy-id: INFO: attempting to log in with the new key(s), to filter out any that are already installed
/usr/bin/ssh-copy-id: INFO: 1 key(s) remain to be installed — if you are prompted now it is to install the new keys
user@SERVERPC’s password:

Number of key(s) added: 1

Now try logging into the machine, with: “ssh ‘user@SERVERPC'”
and check to make sure that only the key(s) you wanted were added.

Once this is complete, we can edit the /etc/ssh/sshd_config configuration file on the server to enable authentication using a key pair without the use of a password. This carries the advantage of preventing unauthorized individuals from logging into your account by guessing your credentials, as well as saving you the hassle of remembering an extra password.

The lines to change in the configuration files are as follows –

ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

Once these changes are saved, restart the sshd service using the systemctl restart sshd command to apply your changes. Future logins via SSH from your client machine to the corresponding account on the server will no longer require a password to be entered, as the client is authenticated and communications are encrypted using the private/public key pair.

It is important to note that this change affects all users, and key-based authentication will be required once these changes are made. If you lose your private key, you’re unable to log in via SSH until the config file on the server is edited to re-enable password authentication.

Remote Commands without Interactive Login

While SSH enables interactive login to a host machine, this isn’t always necessary or preferable. We may only need to quickly run a single command on a server, in which case we can pass it as part of our SSH connection string –

user@CLIENTPC:~ $ ssh user@SERVERPC echo “Hello World!”
Hello World!

Note that the output of the command is streamed to the console of the client machine specifically. For this reason, if I had passed ssh user@SERVERPC echo “Hello World!” > myfile, the “Hello World!” output would have been saved to a file called myfile on the client PC, not to the server.

At face value, this doesn’t seem to be much more than a marginal time-saver. However, this also enables us to script commands to be executed on a remote machine (or machines) in sequence. For example, I could write a script to query for free disk space on a series of servers and save the output to a single text file on my client machine.

SSHFS

One of my favorite SSH-related tools is SSHFS, which enables us to mount a remote server’s file system locally through SSH without the need for any additional file-sharing services such as NFS or Samba.

As this tool is separate from SSH, it usually isn’t installed by default on most distros. This can be resolved with yum install fuse-sshfs on Red Hat-based systems or apt install sshfs on Debian systems.

Once SSHFS is installed on the client, we should first create a mount point (ex. mkdir /mnt/mymountdir).

We then mount the remote target to our client PC. In its simplest form using the client and server examples mentioned above, the command would be as follows –

sshfs root@SERVERPC:/ /mnt/mymountdir/

This particular example enables us to mount an entire remote system to our client. However, we could also tailor our command to mount a more narrow portion of our filesystem such as a user’s home directory, if needed.

Once we’re done, we can unmount the filesystem with umount /mnt/mymountdir/ , as we would for any other mounted filesystem.

Though we’ll be prompted for a password in the example provided above, key-based authentication can be configured for SSHFS as well. Using this sort of authentication would also allow us to use SSHFS with the /etc/fstab file to automatically mount a filesystem at boot time, allowing for persistent file sharing over a local network or the Internet on any system supporting the SSH protocol.