Get SSH Working on a Raspberry Pi 4

Eric North
The Startup
Published in
15 min readDec 1, 2020

--

Secure shell (SSH) is a very handy tool for connecting to your Raspberry Pi, especially if you do not have a monitor, keyboard and mouse at your disposal. Think of SSH as a remote log-in which allows you to work on another system potentially far-removed from the comfort of your easy chair, office chair, standing desk, granite slab or whatever other work area you chose.

Wait, hold on: I might have heard about SSH but what is this ‘Raspberry Pi’, anyway? Dear readers, allow me to present:

Raspberry Pi single-board computer.
Courtesy of Quentin Schulz on UnSplash

Think of the Raspberry Pi as a tiny computer running Raspbian, a flavour of Linux. A tasty flavour, I might add! Because of the Pis’ Linux roots, many of the steps in this article therefore apply to configuring SSH on a much bigger host; Debian boxes to be specific. The instructions should work well with other types of Linux operating systems but your mileage may vary.

There are a few tricky things I encountered when I first attempted to set up secure shell on my RPi. SSH is the gift that keeps on giving! I ran into several difficulties during my intial setup and I suspect other users will encounter similar issues. There are a decent number of rather straightforward tutorials that explain how to SSH into a RPi including this one and that one. Along with these tutorials I found that I had to dig around a couple of discussion posts when I ran into difficulties. I hope that this article will help others in their quest to connect to a Pi via SSH!

Server Setup

First things first: Despite my belief that I’m a top contender for Most Consistent Writer on the Planet, I may not always be. Words like ‘Host’, ‘Raspberry Pi’, ‘RPi’ and ‘Pi’ are used interchangeably throughout this article. Another thing I will point out before getting into the nitty-gritty of SSH is you must have a few bits and pieces beforehand. Like a functional Raspberry Pi that is powered up and connected to your network, preferably with an Ethernet cable. And a static IP assigned by your router to your Pi. And a client machine that is also ideally assigned a static IP and is connected to your local network with, you guessed it, an Ethernet cable. And… a working installation of Raspbian on your Pi. Feel free to subsitute a dash of WiFi in place of your Ethernet cables provided all your devices support it.

You will also want to change any items marked with <..> to suit your particular situation.

Make sure your SuperUser has a strong password before proceeding any further! The default password when logging into a Raspberry Pi for the first time needs to be changed to something stronger before you make additional changes.

Assuming you have all of the above pieces, be sure to perform an initial set-up of SSH once you are logged into Raspbian. You will want to verify SSH enabled first and foremost. Navigate to the ‘raspberry’ icon in the menu (normally at the top-left) and select Preferences, Raspberry Pi Configuration. Enter your SuperUser password when prompted. In the Interfaces tab, select Enable for SSH. Close the menu.

If for some strange reason you do not have SSH installed on your Raspberry Pi you can use the following steps to install it; see this post for details. Within a terminal on your Pi type:

sudo apt install openssh-server

Confirm SSH is running using the following command:

sudo service ssh status

Client Setup

When connecting to your Rasberry Pi for the first time via SSH, run the following command from your client:

ssh -v -o PreferredAuthentications=password -o PubkeyAuthentication=no pi@<pi_IP>

Provided this is the first time on this machine that you have attempted to SSH to your Pi, you should get a prompt asking you whether or not you trust the host, you can say yes to this. Further details are available at this Raspberry Pi forum.

Upon entering your password, you will likely get the dreaded:

Permission denied please try again while logging in with SSH.
Dum dum dummmmm!

Well then.

Here is the part where I get a little fist-shakey at my Pi. But do not dispair, there are some things we can do to get SSH working.

Setup — Digging Further

You will want to have your host machine shut-down and connected to a monitor, keyboard and mouse for these next parts.

With periphirals connected and your host (Pi) restarted, go ahead and log-in. Pull up a terminal session. You can now inspect your host’s logs for any error messages. SSH is rather quiet when it comes to informing users of errors. Any such errors printed to the terminal may appear vague; this is in all likelyhood to prevent malicious users from getting the upper hand and gaining access to your system. No one wants that. Especially me!

Inspect your SSH log file using the following command:

sudo nano /var/log/auth.log

Once you have examined your log file for errors related to SSH, you can also inspect the settings file for the SSH daemon. From the terminal on your host type:

sudo nano /etc/ssh/sshd_config

Be sure you are editing sshd_config, NOT ssh_config; see this post.

Enable PublicKey

This file should contain a number of configuration parameters that you can tweak to get your SSH working. Before proceeding further, I recommend making a backup copy of this file. You know, in the event you make a mistake and have to revert back to a previous good copy. Or, the world explodes. But probably if you have to revert back. Maybe. Once a back-up copy is made and you are back in Nano to edit your sshd_config file , you can un-comment the following line:

# Modified YYYY-MM-DD by <author>.
PubkeyAuthentication yes

Uncomment the PasswordAuthentication line as well:

# Modified YYYY-MM-DD by <author>.
PasswordAuthentication yes

When making changes to your configuration files I recommend inserting a comment directly above the change, along the lines of:

# Modified YYYY-MM-DD by <author>.

AllowUsers and AllowGroups

Another setting to check is that the correct user can access SSH. This step had me scratching my head for quite a while! The default configuration may have an AllowGroups line as follows:

AllowGroups root ssh

For the purpose of this tutorial I recommend that you comment out the AllowGroups line to limit the configuration for the SSH daemon to a single user.

Add an AllowUsers line directly below PasswordAuthentication as follows:

# Modified YYYY-MM-DD by <author>.
PasswordAuthentication yes

# Added YYYY-MM-DD by <author>.
AllowUsers pi

Comment-out AllowGroups if it is present:

# Changed on YYYY-MM-DD by <author>.
# AllowGroups …

Feel free to change the username to whatever name you have set up for your user although be sure that this user is given privileges for SSH. For an initial setup, I find it easier to use the default user pi for troubleshooting. Further details on AllowUsers and AllowGroups as well as their precedence can be found at this helpful link.

You can further specify the host that your user is allowed to connect with. Instead of specifying the user, try specifying <user>@<remotehost> in your list of AllowUsers as suggested by this article:

AllowUsers pi@raspberrypi

Disable PermitEmptyPasswords

Although it is a bad practice, a Linux system administrator can create a user account with no password. That means remote connection requests from that account will have no password to check against. Those connections will be accepted but unauthenticated. The default settings for SSH will likely accept connection requests without passwords. We can change that very easily, and ensure all connections are authenticated by uncommenting the following line:

#PermitEmptyPasswords no

Becomes:

PermitEmptyPasswords no

Once you are satisfied with the changes, go ahead and save the file by hitting cntl-o then cntl-x to exit.

All good, right? Can we start SSH-ing yet?

I think it is prounounced ‘shush-ing’. And the answer is No.

Setup — Almost There

Back in the terminal on your Pi, in order for all of the configuration changes to take effect you first need to restart your SSH daemon on your server:

sudo systemctl restart ssh.service

I am not going to lie, this step also tripped me up a few times!

Now we should be ready to attempt our first connection via SSH. From the terminal on your Pi type:

ssh -v pi@<pi_IP>

Some of you may be asking: ‘Now wait just a darned minute, why would I want to SSH from within my Pi?!?’ Well, if you are like me there is a good chance that your host and client will not be located in the same room. I must be a sucker for punishment. If this describes your situation, it is therefore much more convenient to test whether or not SSH is working by logging in from the host for starters.

If all goes well you should see the following good news in your terminal:

Authentication succeeded while logging in with SSH.
Success!

Provided you get the authentication succeeded message you should be able to log-in to your Pi via SSH from your client machine. Go ahead, give it a try!

When logging in from your client you may still get errors. Inspect your SSH log file using the following command:

sudo nano /var/log/auth.log

Your our log may contain an error such as:

Invalid user <username> from server_IP port <port>

If this is the case, verify you are specifying the correct username in your config file for AllowUsers and try logging in again.

Troubleshooting

If for some reason you are still unable to connect to your Pi via SSH there are a couple of additional troubleshooting steps you can perform, as per this forum post:

  1. Ensure your keyboard layout is correct between both the Raspberry Pi and your client machine (do not use a UK layout on your client when using an American-layout on the host, for example). On my Ubuntu machine I can check my keyboard layout at the top right-hand corner. At the risk of sounding foolish, this has caused me more than a tiny bit of frustration the odd time when I go to log-in to something with a password only to discover my keyboard layout is speaking a different language!
  2. From your client machine, run: dpkg-reconfigure openssh-server; see here for further details on this configuration step.
  3. Verify that you have provided your Raspberry Pi with a static IP address in your router.
  4. Ensure you are logging into SSH with the correct username; you can verify the username once you are logged into your Pi. See the point I made just a few moments ago about troubleshooting using pi as the default user.
Option to change language settings in Ubuntu.
Look at all those puffy clouds!

Hardening Your Pi with a PublicKey

Assuming all goes well and you are able to access your Pi via SSH you can set up a public-private key in order to improve the security. There is a good post that explains how to do it here and a more generic set of instructions can be found at this link. In this section I am going to expand the concept just a wee bit by including a nifty way to manage your keys should you ever feel the need to have multiple server-client SSH configurations. As nerdy as it sounds, this is the kind of stuff that keeps me up at night from time-to-time. Hopefully you will find it helpful!

Important: These next steps will remove and re-install SSH keys on both your client and server. Please please please: check with your System Administrator first, particularly if your server and/or client’s SSH keys are configured for several other machines!

Delete Older SSH Keys

We will start by deleting any stale keys from the Pi, see this video tutorial for details.

Navigate to the hidden folder on your Pi containing the SSH keys:

cd .ssh

Next, edit the authorized_keys file:

sudo nano authorized_keys

Remove the entries from this file, they will likely be rather long so be patient when removing them.

Hit cntl-o then cntl-x to exit. Delete the authorized_keys file rather than messing with individual keys, provided that your System Admin says it is okay to do so. Bring them a nice coffee or tea if this is your second or third visit!

Next, go to your client and remove the keys, see this post to remove the hidden SSH folder on the client:

rm -rf /home/<client_user>/.ssh

Your SSH keys should now both be cleared from the server and client.

Generate New SSH Key on the Client

In this step we are going to generate a custom-named file to store a key on our client, see this post for details. During this set-up we are going to split id_rsa keys into multiple files for better configuration control when dealing with multiple servers; this is handy particularly if you use SSH PublicKey authentication at-home as well as public services such as Git. In a Terminal on your client, type:

ssh-keygen

You may get the following message:

Generating public/private rsa key pair.
Enter file in which to save the key (/home/<client_user>/.ssh/id_rsa):
/home/<client_user>/.ssh/id_rsa already exists.
Overwrite (y/n)?

You will get this message if you have already configured a public-private key for a separate server. To avoid this message I recommend setting up separate keys per this post.

At the prompt type:

/home/<client_user>/.ssh/id_rsa_<server_user>

If you do not specify the full path the new key will be put where the system chooses, likely in the user’s home folder. Be sure to specify the complete path.

During the creation of your keys you may be prompted to set up a passphrase. I recommend using a passphrase if you are going to be using SSH to manage another machine remotely via the Terminal. The passphrase is an added layer of security. If you plan on using SSH as part of another service such as rsync you may want to not set a passphrase if your other scripts run in the background. I will leave this up to you and your Information Security folks to hash out. Bu-dum — bum.

Copy the new key to the server:

ssh-copy-id -i ~/.ssh/id_rsa_<server_user> <server_user>@<server_IP>

Configure the new SSH Key on the Client

Next we are going to create a config file to enable SSH to point to the appropriate keys, see this post for details:

touch ~/.ssh/config
cd home/<client_user>/.ssh/
nano config

Once in the text editor, add the following:

Initial SSH configuration

Hit cntl-o to save, cntl-x to exit.

Note: If you plan on connecting to additional hosts, put their lines below the first configuration in the file as follows:

SSH configuration with additional server

Login to Raspberry Pi using SSH Public Key

With (1) your new SSH key generated, (2) issued to the Pi and (3) set-up in a configuration file on the client, you should now be ready to log-in to your Pi using the PublicKey to confirm it is working. You will want to ensure the PasswordAuthentication line is changed from yes to no, otherwise you may still be able to login to your server using a password. Once logged in via SSH to your Pi, edit its config file for the SSH daemon using sudo nano /etc/ssh/sshd_config to change the option for password-based logins:

# Modified YYYY-MM-DD by <author>.
#PasswordAuthentication yes
PasswordAuthentication no

As usual, hit cntl-o to save, cntl-x to exit. Remember to restart ssh service after editing the daemon config:

sudo systemctl restart ssh.service

You can confirm that the change has taken effect by logging out of SSH then attempting to log back in on the client machine. One of two things should happen: you are logged in thanks to your public key, or, the system asks you to enter your passphrase (assuming you created one when you created your public-private key-pair). If you get prompted to provide your passphrase you can hit enter a couple of times to see if SSH then asks for a password. If it does not then you have confirmed that the public key is the approved method of authentication.

PublicKey Troubleshooting

Life is not perfect and neither is setting up SSH the first time. When things go sideways during your initial set-up, there are a few things you can try. See my above caveat about speaking with your System Administrator before proceeding further with the deletion of any keys from your client or server. If your System Admin happens to also be you then the conversation should be pretty quick! In no particular order:

  • Delete authorized_keys on the server, they are located in the /.ssh folder.
  • If you are using Ubuntu, delete your OpenSSH keys from the Ubuntu Passwords and Keys app on your client. I beleive this program goes by the name of Seahorse when invoked from the command line.
  • Delete the /.ssh folder on your client for both your user as well as root accounts, elevate to root using sudo su, then rm -rf /root/.ssh Be very careful with this command as it will delete other things on your system willy-nilly if not used correctly!
  • Turn your client off and back on again to purge any cached keys stored in environment variables. Yes. I just told you to turn it off and back on again.
  • Change the hostname on your client temporarily to help troubleshoot stale keys. Inspecting authorized_keys with a text editor to ensure all keys with the old hostname were removed.
  • Use the following command to ensure stale keys are no longer present: ssh-add -l
  • If you see any keys as well as your old hostname after running the above command, it is a good indication that there are stale keys somewhere on your system, go back and repeat the above steps to purge them.
  • Re-generate keys for the server and client, use nil passphrase by hitting enter when prompted.
  • Use ssh-add -l to confirm the newly-generated keys as well as ensure that both the username and hostname are correct.
  • If all else fails go and grab a nice beverage then try again tomorrow.

Special Bonus: Interactive SSH

SSH should ship with x-tools to allow you to open graphical windows with the X option.

Open a new SSH session as follows:

ssh -X pi@<pi_IP>

You should now be able to type in the names of programs on your server and hit enter. If all goes well the program should open as a new window on your client. Be patient particularly if you are connecting via WiFi!

Summary

Here are the abbreviated steps for this article, for those that want to cut right to the chase.

Server

Verify SSH is enabled on your Raspberry Pi by navigating to the ‘raspberry’ icon in the menu and select Preferences, Raspberry Pi Configuration. In the Interfaces tab, select Enable for SSH. Close the menu.

Install openssh-server via:

sudo apt install openssh-server

Confirm SSH is running:

sudo service ssh status

Edit the SSH daemon configuration:

sudo nano /etc/ssh/sshd_config

Un-comment PubkeyAuthentication:

# Modified YYYY-MM-DD by <author>.
PubkeyAuthentication yes

Uncomment PasswordAuthentication:

# Modified YYYY-MM-DD by <author>.
PasswordAuthentication yes

Add an AllowUsers line directly below PasswordAuthentication as follows:

# Modified YYYY-MM-DD by <author>.
AllowUsers pi

Comment-out AllowGroups if it is present:

# Changed on YYYY-MM-DD by <author>.
# AllowGroups …

Save by hitting cntl-o then cntl-x to exit then restart your SSH daemon:

sudo systemctl restart ssh.service

Attempt an initial SSH connection from the terminal on your Pi:

ssh -v pi@<pi_IP>

You should now be logged into an SSH session on your Pi. Log-out and then proceed with setting up PublicKey access.

Go and check with your System Administrator to confirm if they are okay with you deleting the SSH keys before proceeding with these next steps!

Navigate to the hidden folder on your Pi containing the SSH keys:

cd .ssh

Edit the authorized_keys file:

sudo nano authorized_keys

Remove the entries from the file then hit cntl-o to save and cntl-x to exit. Alternatively, delete the entire file via:

rm /home/<client_user>/.ssh/authorized_keys

Client

Remove old keys on the client:

rm -rf /home/<client_user>/.ssh

Generate a new set of SSH keys:

ssh-keygen

During key generation, specify the path and rename the new key file along the lines of:

/home/<client_user>/.ssh/id_rsa_<server_user>

Specify a passphrase as applicable.

Copy the new key to the server:

ssh-copy-id -i ~/.ssh/id_rsa_<server_user> <server_user>@<server_IP>

Ceate and edit a config file to enable SSH to point to the newly-created key:

touch ~/.ssh/config
cd home/<client_user>/.ssh/
nano config

Once in the text editor, add the following:

SSH configuration

Hit cntl-o to save, cntl-x to exit.

Connect to Server

With (1) your new SSH key generated, (2) issued to the Pi and (3) set-up in a configuration file on the client, you should now be ready to log-in to your Pi using the PublicKey to confirm it is working.

Login to your Pi from the client:

ssh -v pi@<pi_IP>

You should be asked for your passphrase assuming you set one up.

Edit the config file:

sudo nano /etc/ssh/sshd_config

Change the PasswordAuthentication line is changed from yes to no, otherwise you may still be able to login to your server using a password:

# Modified YYYY-MM-DD by <author>.
#PasswordAuthentication yes
PasswordAuthentication no

Hit cntl-o to save, cntl-x to exit then restart your SSH daemon:

sudo systemctl restart ssh.service

Logout and login again from the client to confirm PublicKey still works.

Postscript

I strongly recommend you take additional steps to harden your RaspberryPi following this tutorial, particularly when it comes to SSH. There are several posts that go into further detail in this regard such as this one. And also this. This one too.

There are many more things you can do to improve the connectivity between your Raspberry Pi and another computer, for instance please check out this excellent Medium article on connecting an RPi to a Mac with an Ethernet cable. You may need to adjust your DNS settings once you perform this connection, more on this in another post!

Another useful tip is to map your server’s hostname to its IP address. This step is useful when you wish to connect with your new machine via SSH. Think of it like a shortcut for your server’s IP! More info on this in another post.

What steps have you taken to set up SSH on your Raspberry Pi?

--

--

Eric North
The Startup

Engineer with a small dash of quirkiness, always on the lookout for new things to learn. Avid sailor and adventurer. Publisher of good(?) ideas.