Raspberry Pi boards (or any of the many similar boards) are handy to leave at odd places to talk to the network and collect data, control things, or do whatever other tasks you need a tiny fanless computer to do. Of course, any time you have a computer on a network, you are inviting hackers (and not our kind of hackers) to break in.

We recently looked at how to tunnel ssh using a reverse proxy via Pagekite so you can connect to a Pi even through firewalls and at dynamic IP addresses. How do you stop a bad guy from trying to log in repeatedly until they have access? This can work on any Linux machine, but for this tutorial I’ll use Raspberry Pi as the example device. In all cases, knowing how to set up adequate ssh security is paramount for anything you drop onto a network.


Better than Password Security

Experts tell you to use a good password. However, with ssh, the best method is to disallow passwords completely. To make this work, you need to create a private and public certificate on the machine you want to use to connect. Then you copy the public key over to the Raspberry Pi. Once it is set up, your ssh client will automatically authenticate to the server. That’s great if you always log in using the same machine and you never lose your keys.

You need to create a personal key pair if you haven’t already. You can use the ssh-keygen command to do that on Linux. You can require a passphrase to unlock the key or, if you are sure only you have access to your machine, you can leave it blank.

Once you have the key it is easy to send the public key over to the server with the ssh-copy-id command. For example:

ssh-copy-id me@ssh.hackaday.com

You log in with your password one last time and the command copies your public key to the server. From then on, when you use ssh on that host, you’ll be automatically authenticated. Very handy.

Once you have keys set up, you can disable using regular passwords by editing /etc/ssh/sshd_config. You need the following settings:

ChallengeResponseAuthentication no
PasswordAuthentication no
UsePAM no

That prevents anyone from breaking in by brute force guessing of passwords. It also makes it harder to set up new users or log in from a new computer.

Save the Passwords; Use Two Types

For those reasons, it is not always a good idea to turn off passwords. A better idea is to use two-factor authentication. That requires you to enter a password and also a “one time” verification code. Where do you get that code?

There are several options, but the one I’ll use is from the Google Authenticator application. You can get the application for Apple devices, Blackberries, and-of course-Android devices. You install it in the usual way for your device. The trick is how to make the ssh server on the Pi use it.

Luckily the Raspian repos have a package called libpam-google-authenticator that will do the trick. Installing it with apt-get is only part of the trick, though. You need two things. First, you need to set up your account.

Set Up a Google Authenticator Account

To set up your account, you need to log into your Pi and issue the command google-authenticator. The program will ask you a few questions and then generate a URL that will show you a QR code. It will also provide you a numeric code. You can use either of these to set up your phone. The command will also provide you a few one-time scratch codes you need to save in case you lose your authenticator device. You need to do this for any user ID that can log in via ssh (even ones where you normally use a certificate).

Tell Your Pi to Require Two-Factor Login

The other part of the puzzle requires you to make changes to /etc/pam.d/sshd and /etc/ssh/sshd_config. The first line of /etc/pam.d/sshd should be:

auth required pam_google_authenticator.so

In /etc/ssh/sshd_config you need to make sure passwords are on:

ChallengeResponseAuthentication yes
PasswordAuthentication yes
UsePAM yes

Just make sure you don’t mess anything up. Losing the ssh server could stop you from being able to access the machine. I haven’t messed one up yet, but the advice I hear is to keep an ssh session open while you restart the ssh server (/etc/init.d/sshd restart) so if something goes wrong, you’ll still have a shell prompt open. You might also consider running:

/usr/sbin/sshd -t

This will verify your configuration before you pull the trigger.

By the way, if you already use certificates to log in, this won’t change anything for you. The certificate authentication takes priority over passwords. That does make it tricky to test your setup. You can force ssh not to use your certificate like this:

ssh -o PreferredAuthentications=password -o PubkeyAuthentication=no me@ssh.hackaday.com

Even for accounts where you use certificates, adding the two-factor log in will prevent brute force attacks on your password, so be sure to set up for all accounts you can use over ssh.

Other Protections

There are several other things you can do to help secure your ssh connection:

  • Disallow root logins (edit the PermitRootLogin line in /etc/ssh/sshd_config; you can use sudo from a normal account if you want to become root)
  • Use a non-standard ssh port (edit port in sshd_config)
  • Consider installing fail2ban which will block IP addresses that exhibit suspicious behavior
  • Disallow any users that don’t need ssh access (use AllowUsers or DenyUsers in the sshd_config file)
  • Set PermitEmptyPasswords in sshd_config to ‘no’

Not everyone will agree with disallowing root logins. However, empirically, a lot of attacks will try logging in as root since virtually every Linux system has that account. It is harder for a random attacker to know that my user ID is WetSnoopy.

There are many other techniques ranging from port knocking to locking users to their home directories. You can rate limit connection attempts on the ssh port. Only you can decide how much security is enough. After all, you lock up your cash box better than you lock up your supply closet. However, convenient and free two-factor authentication can add a high level of security to your Raspberry Pi or other Linux-based projects. If you are really concerned, by the way, you can also force two-factor for accessing sudo, as well.

Read more from this series:
Exposing Raspberry Pi to the Internet


  1. If you don’t use a highly stable hardware clock or a time standard… you’re going to have a bad time….. and that bad time is going to give you a bad time… and g-auth won’t work.

  2. Al Williams

    You can increase the time slack or go counter based. Or use ntp

  3. The default is 30 seconds – timesynch within 30 seconds is pretty trivial to implement. That default can be increased to 4 minutes (they ask you that question during the install – it’s not rocket science).

  4. Robert Martin

    its online, ntp is very reliable. I used this kind of solution when I left my pet turtles alone it didn’t fail for 7 weeks. I used an orange pi though.

  5. Lock up your RaspberryPi with Botnet!
    Now with baked in MITM!
    It’s bad enough that the Pi has binary blobs and NDA protected hardware.
    Just use a password protected key.

  6. What do you mean?
    The Google Authenticator PAM module is simply a standalone PAM module that implements the RFC 6238 standard (TOTP). Other than being developed by Google, it does not depend on or communicate with Google systems in any way, nor does it rely on them for authentication.

  7. fail2ban for other services (ftps, nfs, etc) on top of this, would make a fairly rock solid foundation for the security minded beginner

  8. Just throwing this out there for any other Windows Phone users, you can use the Authenticator app from Microsoft which supports google’s 2-factor service.

  9. It is harder for a random attacker to know that my user ID is WetSnoopy.
    You are correct. The funny fact is that “wetsnoopy” is pretty common, it is included in the most basic (and free) passwords dictionaries, rockyou.txt (on line 2774571).

  10. Al Williams

    Keep in mind I said user ID. So you still need a password or certificate. Combine with two factor and WetSnoopy is pretty good.

  11. I set up key pairs for my Linux boxen on basically all my devices that allow me to access the internet, including my phone. My two VPSs also have key pairs for each other, so if I somehow lose a key for one, I can ssh over from the other.
    I guess if I found myself out somewhere without my phone, I wouldn’t be able to access my VPSs, but if I don’t even have my phone on me I won’t know that I needed to log into my VPSs.

  12. s/my VPSs.$/them./

  13. If you typically access the machine from static IP addresses, you can use hosts. allow to really nail down access.

Leave a Comment

Your email address will not be published. Required fields are marked *