This post is essentially a list of changes to the Pi’s default configuration that I would recommend you make before you start using the Pi as a server. These apply regardless of whether you want to use it as a mail server, an Owncloud machine, or a web server running something like WordPress. I’ll run you through the steps, starting with burning Raspbian to an SD card.
Download & Burn Raspbian to an SD card
This step assumes you’re using a Linux computer when burning. The Raspberry Pi foundation website explains how to burn the image if you’re using Windows or MacOS. Visit the raspberry pi downloads page and download the latest raspbian.zip file. Now open a terminal, and type this command to produce a sha1sum of the file you just downloaded (edit the name of the file as necessary for new downloads):
Compare it to the sha1sum on the download page. If it matches, you’re good to go! Unzip the file:
This will produce an image file called 2014-01-07-wheezy-raspbian.img. Insert the blank SD card into your laptop/desktop, but don’t mount it. Check that
/dev/sdb is the name of the SD card using your distribution’s partition manager (GParted for Ubuntu, KDE Partition Manager for KDE). Now use this command to burn the image to the SD card. It will take a while, and you won’t get a progress indicator…just be patient. Make a cup of tea and come back and it should be done! Remember to edit the command so that the file name is correct.
sudo dd bs=4M if=~/Downloads/2014-01-07-wheezy-raspbian.img of=/dev/sdb
When this finishes, your SD card will have the latest version of Raspbian installed.
First Boot & Updates
Next, we connect with Secure Shell (SSH). On Windows, you can use the free app PuTTY for this; Linux and MacOS have the utility built in. Open a terminal and type:
…where 192.168.1.103 is the IP address of the Pi. If you don’t know the IP address you can find out on your router’s admin page (usually http://192.168.1.1 or http://192.168.0.1). This will open a connection so that you can log in as the default user (“pi”). It will prompt you for a password, which is “raspberry”. You should now be logged in, and see a command prompt for pi@raspberrypi. Let’s make sure we’re up to date:
sudo apt-get update sudo apt-get upgrade sudo apt-get dist-upgrade
This could take a while depending on how recently the latest raspbian.img file was put together: the Pi will connect to the Raspbian repository and download the latest versions of all the installed software.
If you’re going to use the Pi as a server, you may want to connect to it via SSH from outside your own Local Area Network (LAN). The problem is, if you allow this for yourself you allow it for everyone else too, and there are loads of scripts that look for SSH login pages and try to brute force their way in. So, what can we do about it?
Adding a new user/password
For starters, let’s change the default username and password – “pi” and “raspberry” is too easy to guess. This command will add a new user called “admin” just as an example, but you can choose another name if you like.
sudo adduser admin
You will be prompted to fill in some information. You can leave most of it blank if you like, the key thing is choosing a decent password. Once this user has been created, you should add them to some useful groups: sudo so that they have superuser access and adm so that they can read log files without using sudo:
sudo usermod -a -G sudo admin sudo usermod -a -G adm admin
So we’ve now added a new user, with a decent password, who can act as administrator once we’ve removed the default user “pi”. We can do better than this, though: there’s still a chance that someone could guess the password – after all, “admin” is an obvious username. If you want to stick with the current username pi and just change the password, just type this command when logged in as pi:
You'll be asked for the current password, and then you can choose and confirm a new password.
PublicKey authentication can be used in addition to, or instead of, password authentication for SSH. It works by creating a pair of keys, one public and one private. The public key is not secret and can be kept on the server (or servers) you would like to log in to; the private key is secret, stays on your laptop/desktop and may be password protected (encrypted). Only someone with a private key that matches the publickey held on the server is allowed to log in. Since the key pairs are so much more complex than normal passwords, the chance of someone guessing the key during a brute force attack is vanishingly small. Therefore, publickey authentication provides a much greater level of protection than normal password logins. The only real drawback is that if you don’t have your private key, or you lose it, then you won’t be able to access the server! We are going to create a SSH private key on the client machine (the laptop/desktop you are logging in from), and then copy the publickey part to the server, so that the server knows to grant entry to anyone who has the matching private key. Let’s get started. Configuration for the secure shell client is stored in a hidden folder in your home directory on the machine you are logging in from. If the directory doesn't exist (use the
-a argument to
ls to show hidden files and folders, e.g.
ls -a ~), you can create it now:
Now, this command (again, run from your laptop/desktop) will generate a key pair for you.
ssh-keygen -t rsa -b 4096
-t option specifies that we want a key of type RSA. The
-b specifies the number of bits in the key. Higher numbers of bits generate a more complicated key that is more difficult to crack, but larger keys are also slightly slower to use. The default value is 2048. You’ll be prompted to set a password for the key. I’d recommend doing this, or anyone who gets hold of it can log in to the server. The
ssh-keygen command creates two new files in the
~/.ssh/id_rsa.pub. The first is the private part of the key, and the second is the public part, which is not a secret. Now we need to copy the publickey you just created from your laptop/desktop to your Raspberry Pi server using this command: If you used the default file location when creating the publickey, you can use:
remote-username is the username you want to log in as on your raspberry pi server (
admin if you just created that user to be the new administrator on the pi), and
192.168.1.103 is the IP address of your server (you can also use the hostname instead of the IP address if it is resolvable from the client). If you saved the key somewhere else (e.g. if you were generating a second key from the client machine), you can use the
-i parameter to tell the command where the publickey is, e.g:
ssh-copy-id -i ~/.ssh/second_RSA_key.pub email@example.com
This will copy the contents of your publickey into a new line in the
~/.ssh/authorized_keys file on the server (in the home directory of the username you specified). Final changes: log in to the Pi again via SSH, this time to the admin account. If publickey authentication is already enabled, you may be prompted for the password needed to unlock your private key (this is not the password for the account on the server). If publickey authentication is not enabled, you will be asked for your username and password as usual:
Now within SSH, edit the configuration file for the SSH daemon:
sudo nano /etc/ssh/sshd_config
find these two lines and uncomment them:
PubkeyAuthentication yes RSAAuthentication yes
Now issue this command, which will restart the SSH server (you’ll be disconnected):
sudo service ssh restart
Connect again. This time, you should be asked for the password to your encrypted publickey. When you’ve logged in again successfully, make one further change to the SSH configuration so that it only allows PublicKey authentication for all users. In
/etc/ssh/sshd_config, update these two settings to disable password authentication: !! Warning !! don’t do this unless you have successfully logged in with your publickey, or you’ll be locked out!
PasswordAuthentication no ChallengeResponseAuthentication no
Now restart SSH again:
sudo service ssh restart
If you try and log in as pi now, you should get the error “Permission denied (publickey).”, because no SSH public keys have been added to pi’s list. You should still be able to log in as admin using the publickey we created earlier. You can now log in to the server as admin and remove the default user “pi” and its home directory:
sudo userdel pi sudo rm -r /home/pi
SSH is now much more secure than it was originally. Ideas from this SSH section were taken from the Ubuntu community documentation page.
Speed things up by booting to a USB Flash Drive
The pi is not a high powered machine, so every little bit of speed you can squeeze out of it is time well speed. High quality SD cards have high write speeds but fairly slow read speeds (think about what they’re usually used for: writing photo data as quickly as possible). In comparison, most USB flash drives have a higher read speed, which can help speed things up. Using a USB flash drive for your root filesystem can also give you more storage space for content. Take a look at this tutorial to learn how to boot your Pi to a USB flash drive.
Run the Raspberry Pi’s configuration utility:
- Expand the filesystem
- Internationalisation options: change the locale and timezone
- Set overclock to modest
- Use the advanced options to set the hostname to something sensible, and then set the memory allocation for the GPU to 0, since the Pi will be running “headless” (no monitor)
- Finish & reboot
Hi, is there a way to work with with filezilla after enabling pubkey authentication? Is pubkey exportable to another computer / OS (win7)? Bye
Nice guide! Worked perfect.
I'll go further with the email server.
One question. What would be a proper size of the SD-card for a private low-traffic email server?
Can you advise how to can create the key files on a Windows PC?
It's Jay over from your mailserver tutorial. Thanks for your help, it worked in the end, but I've put this on the backburner as I've applied for a static IP from my ISP -- I needed that PTR entry as I don't want to end up on a Spamhaus list!
So as to be really secure and all, I've now spent the past day trying to harden SSH access and again it's like there is some sort of skulduggery going on. I'm just not getting the Pi to 'switch' to my newly generated RSA 4096 key. Instead, it sticks stubbornly to some ECDSA 256 key (which I presume gets somehow installed when you enable the SSH server in raspi-config). This happens even on a clean reformat of the SD card, and even after deleting all files and entries for
authorized_keys on my client machine. So here's what I did:
1. Fresh install of Raspbian Jessie on the microSD card.
2. Followed your instructions in this tutorial up to 'PublicKey Authentication'.
3. Once I have tranferred the id_rsa.pub keyfile to the Pi, I log on to my Pi.
4. Since I have
VisualHostKey set to
/etc/ssh/ssh_config, I know even before typing my Pi password that it's not authenticating using my RSA key. And when I do a verbose ssh login using
sudo ssh -v username@local-IP-address it jumps to 'Next authentication method: password', seemingly without giving my id_rsa file a second look.
I'm fairly sure it's me, but where did I go wrong? I followed a few other SSH tutorials, but the result is always the same! Would be great if you could have a look.
sudowhen you start
ssh. Not sure if that will mean the command is looking for root's keys instead of your own. Can you try without sudo? Sam
I tried this, with the same unwanted results. What I have done now is yet again set up Raspbian from scratch, but this time getting rid of the ECDSA key as well as any and all
authorized_keys files, and regenerating an RSA 4096 key with the Pi connected to keyboard/monitor. At first SSH connect (without
sudo) I was asked if I wanted to trust the connection (same as with ECDSA), and this key was then stored on my client (Ubuntu laptop).
I then proceeded to generate a new keypair on my client machine, as per your instructions. I gave the files a password, ran the
ssh-copy-id -i /home/client-username/.ssh/id_rsa.pub pi-username@hostname command, and it did ask for the password for the newly generated key. However, for whatever peculiar reason, the random art still shows that of the key originally created on the Pi. It's like it refuses to update to the new keypair. I can live with that, since I have an arguably more secure key algorithm (which was the objective of the whole enterprise), and switched off password auth altogether. But isn't it weird I'll never be able to change the keypairs?
Thanks again for replying, you're a great man for helping others out of a pickle out on a Saturday! :)
Well, I didn't really have to. I just needed to be sure my laptop client wasn't using the ECSDA key generated from the very first ssh connection to the Pi: by first getting rid of any keys on the Pi altogether, and then having it generate a new RSA key before going headless. If I ssh into the Pi before that and it keeps telling me it connects with ECDSA (and showing me the random art and fingerprint of the ECDSA) although I have installed a new key (with a different algorithm too), isn't the random art a bit pointless?
Yes, sorry. I did set parameter
-v so it displays the random art at each connection.
I'm attempting to set up a new RasPi with the 'OwnCloud', and am trying to prepare my RasPi is becoming a nightmare...
I followed the instructions above and when I get to: ssh-keygen -t rsa -b 4096, it also asks for a file to save it in and suggests in brackets (/root/.ssh/id_rsa). I thought I should type in /home/pi/.ssh/id_rsa or even /home/admin/.ssh/id_rsa but it only seems to generate anything like a key when I use the /root/...option.
Then when I've entered my passcode twice and attempt to copy the pub key using: ssh-copy-id -i /home//.ssh/id_rsa.pub firstname.lastname@example.org (in my case), the only time it seems to work is when I use the path as ssh-copy-id -i /root/.ssh/id_rsa.pub email@example.com
I've also tried ssh-copy-id -i /home/pi/.ssh/id_rsa.pub firstname.lastname@example.org and ssh-copy-id -i /home/admin/.ssh/id_rsa.pub email@example.com but to no avail.
With the root option, I seem to get one key 'allocated' logging in via ssh firstname.lastname@example.org and then it says that it can't verify or identify or access or something like that the user, but still says it needs to add a key to the user, or something like that...
Then I'm in...I think without bein asked the passkey, but when I went to sudo nano /etc/ssh/sshd_config, the two lines of code is already commented out. I restart the ssh service, but don't get logged out. I go out anyway and ssh back in, but no passkey asked only my admin password for admin@raspberry...
Due to all of this I didn't change the PasswordAuthentication to no...
Any ideas? I'm using 'Jessie' again...
I was looged in as 'pi'...(pi@raspberry). I'm not sure if I typed 'sudo' in front when I shouldn't have...
I think sometimes when it wasn't working as expected I may have re-typed with 'sudo'...
Which path + file name should I choose when promted? And which path + file name when copying the pub key? Is the username 'pi' or .admin'?
I'm going to re-image the micro sd card and restart the process again...just to be sure everything is 'clean' again.
After reading the instructions much more in detail this time around, I realised that I used PuTTy from a Windows client machine and that's why things didn't work as expected...
I used my RasPi email server machine to ssh in to my new RasPi server and everything worked as per the tutorial (I did decide to keep my username as 'pi' though...
Thanks again for the support and great tutorial!
I've found a 500GB HDD...now to start the OwnCloud tutorial...