I access all of my Raspberry Pis remotely using SSH. While reading about a server operator’s experience of being hacked, I decided to explore ways to make my Pis more secure.
Every Pi starts out with SSH access bound to port 22, which is the standard for SSH communications. The problem is, hackers know this and so it’s the first place they look when they’re attempting to access a machine. I want to change that.
Don’t forget, most attacks are scripted: they run through ranges of IP addresses and port numbers just to see what might be accessible. No, they won’t be targeting you specifically, but yes, you might be targeted among a wider haul.
Accessing a Pi with SSH also centres on using your password for authentication. Even with a long password, that’s not as secure as the use of an encrypted key available only on the two or three machines that are communicating, so I want to switch to that too.
Of course, adding all these options will make the
ssh command more complex, so I thought I’d try and simplify this by using SSH’s configuration file to simplify what I enter to establish a connection to the Pi.
Here’s the procedure I researched and used. I use a Mac as a main machine, but the following steps should also work on a Linux box. I haven’t tried any of this on a Windows computer, however.
- Fire up your Raspberry Pi and SSH in in the usual way
- Make sure you’re in your home directory (enter:
- Create a ‘.ssh’ directory:
- Set the new directory’s permissions:
chmod 700 .ssh
- Switch to the new directory:
- You need to generate your RSA access key pair: one private, one public.
ssh-keygen -t rsa
You’ll be asked for a filename — just hit enter to keep the one that’s suggested. You’ll also be asked to enter a passphrase — just hit enter again, and once more when you’re asked to confirm your choice, so that no passphrase is applied.
- You now have two keys,
id_rsa, which will be used for access authorisation. The first of these will be used on this side of the authorisation transaction. Enter:
cat id_rsa.pub >> authorized_keys
- The second key file needs to be sent to each client machine from which you’ll be SSH-ing into your Pi.
If you’ve already used SSH to access a Pi from your main machine, you will have a ‘.ssh’ directory in your home folder already. To check, open a second Terminal window or tab on your main computer and enter
ls -la. You’ll see
.sshlisted. If not, create one using steps 3-5 above.
At this point, I turned Remote Login on on my Mac (Apple’s System Preferences front end for SSH). On the Pi I entered:
scp id_rsa <username>@<hostname>.local:~/.ssh/pi_rsa
You’ll need to replace <username> and <hostname> with those from your own machine. You’ll be asked for your client password, and then the file will copy over. You can transfer the file using a shared drive or a USB stick, but it’s worth getting to grips with SCP.
- You’re now going to set up an entry for your Pi in your main computer’s ‘.ssh’ directory’s config file. Enter:
cd ~/.sshand then:
- Enter the following. Note the single-space inset for all lines after the ‘Host…’ line:
Host <A_NICKNAME> Hostname <YOUR_PI_HOSTNAME>.local User <YOUR_PI_USERNAME> Port 22000 IdentityFile ~/.ssh/pi_rsa StrictHostKeyChecking yes
So you can see how it works, here’s my entry as an example:
Host pz Hostname pizero.local User zarJaz4 Port 22000 IdentityFile ~/.ssh/pi_rsa StrictHostKeyChecking yesWhy add this entry? With all this in place, all I need key in to access my pi is
ssh pz. Without it I would have to enter
ssh -p 22000 -i ~/.ssh/pi_rsa zarJaz4@pizero.localevery time.
- Back on the Pi, we need to set the new SSH port and, while we’re at it, block root login. So enter
sudo nano /etc/ssh/sshd_configMake sure you do this on your Pi, not your main machine!
- Look through the open file for the ‘Port 22’ line and change it to ‘Port 22000’
- Look through the file file for ‘PermitRootLogin without-password’ and add a # at the start
- Save the file with Ctrl-X then Y. Now restart your Pi:
sudo shutdown -r now
- To test it all works when the Pi is back up after a couple of minutes, on your main machine enter
sshfollowed by the nickname you chose in your config file.
- You’ll connect and be asked for your password, then you’ll be logged in. You don’t want to authenticate by password in future, re-edit
/etc/ssh/sshd_configand look for the line ‘#PasswordAuthentication yes’ and change it to ‘PasswordAuthentication no’. Note the removal of the initial #
- Finally restart your Pi. Now when you log in, you won’t be asked for your password — you’ll go straight in, your authorisation having been granted by your key.
Only someone else with that key can now connect. You’ve set this up on your main machine, and you’ll need to copy the same
id_rsa key to any other computer from which you want to access your Pi.
Of course, this might seem overkill if you’re only accessing your Pi locally on the same network, and you’re behind a router’s firewall, but you may eventually choose to expose your Pi to the Internet so you can, for example, SSH in from work or some other location. This procedure allows you to do so securely by (a) obscuring the port on which you connect (and you can make this more obscure by picking a less obvious port number above 10,000, eg. 18713) and (b) allowing access only to clients with the correct RSA-encrypted certificate.
Setting up two factor authentication on a Pi is easy and provides an additional level of security for any computers exposed to the internet. There’s a good account of how to do this here: https://www.sbprojects.net/projects/raspberrypi/ga.php
It seems to me that you have the RSA keys backwards? I’ve always put the private key on the server, and shared the public key (*.pub).
Unless you really have to, you should leave strict host key checking turned on. It helps prevent MITM attacks.
Very good suggestion from someone who knows. Example updated accordingly. Thanks, Roger.