Configure SSH, overclocking, firmware, WiFi, Bluetooth, VNC, and two-factor auth for a headless Rasperry Pi 4B with Raspberry Pi OS
This stoy will be very similar to my last two about the Raspberry Pi, but in this case, we are going to use the new Raspberry Pi OS (previously Raspian) which is based on Debian Stretch (10) and a Raspberry Pi 4B with 4GB of RAM which I recently obtained.
There were enough differences with setting this one up in relation to the previous setups that I wrote about that it merited it’s own story. Some elements will be repeated, which I will do for the sake of those new to Raspberry Pi, but most will be new and hopefully will help newbies be more comfortable in using it.
So, to start off, you’ll need your Raspberry Pi 4B. I strongly suggest you get at least the 4GB option (we’ll be using VNC, so that needs more RAM). If you can get the new 8GB version, even better, but the 4GB should really be the minimum, and I haven’t see the 8 GB on Amazon yet. After using this for about two weeks, I can honestly say you should not go lower if you are going to do anything graphical on it.
You will also need a micro SD card. Again, after trying different cards, I can 100% now say it is much better to get the 32GB SanDisk Extreme Pro. I was really surprised at what a difference it made with writing speeds. Just splurge, you will thank yourself later.
As for powering it up, as long as your cellphone charger is USB-C and can shoot out at least 15 Watts, you should be fine, if you don’t want to overclock, but I would highly suggest that you use only 18 Watts or higher if you are going to follow the whole tutorial here. I was using my Samsung Note 10+ charger (25 Watts) and cable with it and it worked perfectly. I can’t vouch for other chargers, but this worked like a charm.
Now that we have those three crucial elements, let’s get the image for Raspberry Pi OS here. We are going to download the version with the desktop. This version is still 32-bit, but they are already starting to work on the 64-bit version, which should come out around October hopefully. It’s still feels fast as it is, so you won’t feel like you’ve missed anything for it not being 64-bit.
It’s already a ZIP file, so we don’t need to fight the format to flash it. For flashing (setting up the image on the micro SD card) we can use either the Chrome Recovery Utility or Balena Etcher. I like Chrome Recovery more just because it’s more universal and can be used on Chromebooks to do the process.
After you have that installed, fire it up and click on the blue button “Get started”, then in the upper right-hand corner, click on the cog, and then, “Use local image”. Here, you’ll select the zip file downloaded previously. Then, select your SD card from the drop-down list. Afterwords, click on “Continue”. It will then tell you that the SD card will be completely erased and formatted. Then, click on “Create now” to get that set up.
At the end of the process, which will take about 15 minutes, it will tell you that you can eject the Storage Device. Do NOT take it out or eject it yet! Just close the Chrome Recovery Utility and head on over to your file manager.
Here, in the boot folder, we are going to change one file, and add two others. First, you need to add a file called ssh . You are not going to put anything inside it, and you don’t add a .txt at the end. You just create it and add it to the folder, so that when the Raspberry Pi starts up, it will let us ssh into it.
Then, you’ll create another file, called wpa_supplicant.conf . In this file you will add the following:
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev update_config=1
Here, for network name you put your WiFi network name. Then for networkpassword, put your password for your WiFi. In both cases, leave the quotation marks. This you then save and close.
Finally, we need to find and modify a file called config.txt . We need to add these three lines at the end:
You could put them in other specific places in the file, but it’s not necessary. Just throw them at the end, save, and close.
Make sure you have a heat sink and fan for the Raspberry Pi to overclock, or it will overheat and/or break!
For this, you can use the following MazerPi case, (strictly a suggestion).
To create and edit all these, I use Caret (a universal Markdown text editor that works on any laptop).
Once that is done, insert the micro SD card into the Raspberry Pi and plug in the power source to have it start up. You’ll need to wait about a minute for it to get up and running. After that, If you have an Android or iOS phone handy, just install WiFi Man, which, under the tab “Discover”, will allow you to find the IP address of the Raspberry Pi. Make sure you are on the same WiFi Network that you put in the wpa_supplicant.conf file. In many cases, it won’t have a name, just “generic” so you’ll have to know what other devices are connected to the network to figure out which one it is.
If you have access to a terminal, you can use nmap:
sudo apt-get install net-tools nmap -y
Then, just use
ip route | grep default to find the your Gateway IP, and then run
nmap -sP 188.8.131.52/24 (changing the 0.1 to the numbers that come out from ip route). You may have to change all four numbers, but what stays the same is the /24 at the end.
In the extreme case that you never see the IP address come up, you might be forced to either connect by ethernet to set things up, or briefly connect to a TV or montor with an HDMI cable to see the IP address there, but most of the time, this is enough.
Now that we have the IP address, let’s ssh into the pi (by typing
ssh pi@IP_ADDRESS) to start configuring. The first thing we need to do is update the password by typing
passwd. It will ask you to type in raspberry and then change it to something else. Then we need to update everything.
sudo apt-get update && sudo apt-get full-upgrade
After that is done, let’s update the firmware if you haven’t already and reboot:
sudo apt install rpi-eeprom -y
sudo rpi-eeprom-update -a
Now, let’s ssh back in and fix the WiFi. The WiFi is very “fragil” I’ve found on the Raspberry Pi. If you do something wrong, the network manager basically breaks. After playing around for hours, I found the best way to control it was using wicd-curses which works very well in the terminal. For this to work, we’ll install it and get rid of the previous network manager. To install, type the following:
sudo apt-get install wicd-curses
After that is installed you just type
sudo wicd-curses to start it and then, using arrows and upper case letters, we’ll set up the connection.
Using your down arrow key, highlight the network that you are already connected to (it should be in green), then click on the right arrow key for configuration. Click on the down arrow key until you get to the key, and type in the password for the network, then go up (with the up arrow key) until you get to “automatically connect” and click on the space bar to select it (an x should present itself).
Then, type Shift S to save and Shift Q to quit wicd-curses. Now, we have to get rid of the previous network manager by typing the following and rebooting.
sudo systemctl disable dhcpcd
This will also disconnect us from the SSH session, but once it’s rebooted, it should have connected to the WiFi we configured previously and then allow us to ssh into the Raspberry Pi again. From then on, you just use sudo wicd-curses to configure your wifi.
Just make sure that you add your cellphone hotspot as an option to automatically connect to so that, when you leave your house, you can connect to that first and then use wicd-curses to conect to another WiFi Network. Do not add any other WiFi network to wicd until you have rebooted after having added only the WiFi you were previously connected to, otherwise it may disconnect from everything given that the other WiFi network manager will be in conflict.
It is also very important to make sure that you add the password and select “Automatically connect to this network” to the network you were already connected to before rebooting, as we mentioned above (in green), otherwise, wicd won’t have that info, because it was only saved in the previous network manager that we will disable, so don’t forget…
Now that we are done with configuring the WiFi, let’s configure Bluetooth.
First, let’s just add the following packages (some of which are already installed, but just in case…)
sudo apt-get install bluetooth bluez pi-bluetooth python-dev libbluetooth-dev python3-pip -y && sudo pip3 install pybluez adafruit-ampy
After that is done, we’ll jump into the following file with Vim (If you don’t know how to use Vim, please see my story about it here):
sudo vim /etc/systemd/system/dbus-org.bluez.service
Then we need to modify a line so that it ends in -C and add another line right below it so that they look like this below. After that, save and close (with :x) and then
ExecStartPost=/usr/bin/sdptool add SP
Once we ssh in again we’ll type the command
sudo service bluetooth start and then
sudo bluetoothctl to enter into the shell to run each of the following commands:
After that, just type
bluetoothctl scan on and then, when you find the MAC address of a Bluetooth device, just type the following commands to connect and trust (changing the MAC address to your device’s), and you’re done.
bluetoothctl pair 40:HR:32:46:GH:00
bluetoothctl trust 40:HR:32:46:GH:00
For our final configuration, we want to set up VNC so we can open the GUI of our Raspberry Pi from anywhere, (in this case, on an iPad Pro) in the right resolution.
First we need to make sure we have realvnc installed (it should already be there, but just in case):
sudo apt-get install realvnc-vnc-server
Then we’ll type
sudo raspi-config, and with down arrow, navigate to Interfacing Options > ENTER > VNC > ENTER and select Yes > ENTER > OK > ENTER. To get out, just press the tab key twice to go down to <Finish>.
You can actually do a lot of stuff in the raspi-config area, so take a look around to see what options there are.
After that, we need to configure the vncserver. For this, we’ll have to jump into the following file:
sudo vim /root/.vnc/config.d/vncserver-x11 and then Replace
Authentication=VncAuth and save the file. If there is nothing there, just add
Authentication=VncAuth at the end and close.
Then, in the command line, run
sudo vncpasswd -service so that you can set a password that you’ll need to connect with. To finish, we’ll type
service vncserver restart . It will spit out errors. You can ignore all of it and just type
clear to clear the screen.
Once that is done, then we’ll edit this file:
sudo vim /boot/config.txt and change the following:
First, comment out the following line (careful, there is another line with the same name commented out, you need to comment out the one that is still active):
Then, uncomment and change the following two lines (if you are on an 11 inch iPad Pro):
To finish off, we have to do one strang thing I found for this to finally work, which is to go back to
sudo raspi-config then with the down arrow go to Advanced options > ENTER > Resolution > ENTER and then choose the following resolution:
I have yet to understand why this is necessary, but it’s the only way I have found that let’s me use the vncserver. After that, you will need to reboot with
sudo reboot. When you ssh back in, type
vncserver to start running the server (and then
vncserver -kill :1 to stop it).
Once you have the vnc server running, we can use any VNC app we have in the App Store. I use Jump Desktop because it has good Magic Mouse and Trackpad support.
Click on the + icon, put in your Raspberry Pi IP address (the one below is just an example, so change it to your own) and select vnc, leaving the port at 5900, then Save, then connect and put in your password for your vncserver.
You should have something like this below when you finally enter:
It should be in the exact same resolution as your 11 inch iPad Pro so as not to have to pan around. It will then ask you to change the time zone after you click on Next, and continue to ask you questions until it is satisfied that everything was set up correctly.
We can also add two-factor authentication to our Raspberry Pi to make it more secure. We’ll start by editing the following:
sudo vim /etc/ssh/sshd_config
Then, we’ll change the following from ‘no’ to ‘yes’
Then, we’ll type
sudo systemctl restart ssh and then install google-authenticator:
sudo apt-get install libpam-google-authenticator
Then, just run it with
google-authenticator without the sudo.
After that, it will start asking you four questions, and either at the beginning (or after the first or second question) print out the QR code that you can try and scan with your autheticator app (I use Authy for now). I say “try and scan” because it didn’t come out correctly for me and it didn’t scan, but right under the QR code is says “Your new secret key is: KEY” and with that key you can type it into the authenticator app and it works fine to register it. As well, it would be a good idea to jot down the emergency scratch codes for backup. The four questions are the following:
Do you want me to update your "/home/pi/.google_authenticator" file? (y/n) yDo you want to disallow multiple uses of the same authentication token? This restricts you to one login about every 30s, but it increases your chances to notice or even prevent man-in—the-middle attacks. (y/n) y... this will permit for a time skew of up to 4 minutes between client and server. Do you want to do so? (y/n) n... you can enable rate-limiting for the authentication module. By default, this limits attackers to no more than 3 login attemps every 30s. Do you want to enable rate-limiting?s (y/n) y
For these questions, we will answer ‘y’ for all of them, except the third, which will be ’n’.
Finally we will edit the following:
sudo vim /etc/pam.d/sshd and we will make sure that we have the following at the beginning, adding the extra lines:
# Standard Un*x authentication.
auth required pam_google_authenticator.so# Disallow non-root logins when /etc/nologin exists.
account required pam_nologin.so
To finish off, we’ll type
sudo systemctl restart ssh .
Be very careful to follow the instructions for two-factor authentication, otherwise you’ll be locked out of your Pi. You may want to have two ssh sessions open at the same time just to make sure it worked.
Keep in mind that there is a bug in the Blink Shell right now, and if you try and use this for saved Hosts it will give an error: Did not find remote IP address. Until they fix it, you’ll need to mosh the IP manually. As well, using mosh sometimes makes Blink crash. Just keep that in mind before using it.
Even though two-factor auth is good, using ssh with a certificate is better. If you are only going to ssh into the raspberry pi with one or two devices, the best would be to get rid of passwords all together and just use a certificate. This is quite straightforward in the Blink Shell. You just type the following (substituting IP for your pi IP address):
ssh-copy-id id_rsa pi@IP
It will ask you to type ‘yes’ and then put your password in one last time, and from then on, it won’t ask for the password anymore.
Now, if you are using ssh from another Linux terminal, then you would first create the ssh keys with
ssh-keygen -t rsa , hitting enter three times until it finishes. Then you would just run
ssh-copy-id pi@IP .
Now, if you want to make sure that passwords are no longer used at all (presupposing that you already added the devices you want that are going to ssh into the pi), then we can open the following file:
sudo vim /etc/ssh/sshd_config
and uncomment / change the following three to ‘no’:
After doing this, just type
sudo systemctl restart ssh and then the only way to enter the Raspberry Pi will be with the ssh certificate.
Now, this works fine for ssh, but you will hit an error if you try and mosh into the Raspberry Pi with only the certificate if you haven’t changed the Localization Options previously. So, just enter by ssh and then type
sudo raspi-config and then go to Localization Options and then to Change Locale and then selecting en_US.UTF-8 UTF-8 (or your country) by clicking on the space-bar, then tab to select <Ok> and then enter to save. Make sure you unselect the country that was pre-selected before you made that change before leaving that section.
As well, keep in mind that reverse ssh does not work with mosh yet, and if you only allow certificates to get in, you will have to save the public key of the GCP in the Raspberry Pi (using
ssh-keygen -t rsa && cat ~/.ssh/id_rsa.pub to get it), and saving it in
.ssh/authorized_keys in the pi. To learn more about reverse ssh, you can see my story here.
With that, we have finally finished configuring everything necessary to use your Raspberry Pi (especially in relation to the iPad). If you would like to see a video tutorial on this, you can go here. Cheers.
Disclaimer: Some links in this article are affiliated (from Amazon). You are under no obligation to click on or use them. They are merely suggestions and are used because I wanted to help the reader find these things more easily, and was going to use links for this purpose either way.