Super Pi Part 1: Pi-Hole

Posted on April 8, 2021

So I have quite a few Raspberry Pi computers, five in fact. Three 3B+, one 0W, and one 4B. The 4B is a media center in progress, the 0W isn't used for anything currently, maybe some kind of brewing thing somewhere down the line. I was going to delegate various home automation tasks between the remaining Pis: WireGuard, Pi-Hole, a Git server, Node-RED. It occurred to me, though, that I can run all of that on one. This post series, Super Pi, chronicles this unnecessary journey. We're starting from scratch, with a Pi and an SD card and a pocket full of dreams.

Raspberry Pi OS

The first thing to do is put an OS on an SD Card. In retrospect, it may have been easier to just use Raspberry Pi Imager. I've never used the tool myself. If you have Balena Etcher already installed, you can use that as well. For completeness's sake, you can also flash the OS using dd, which is how I typically do it. I've been doing this since before Raspberry Pi Imager was a thing and in my reluctance to add yet another package to my system, I didn't want to download Balena Etcher. In any case, there will be plenty of time to mull all of that over while the operating system downloads. If sticking to Raspberry Pi's operating systems, the Raspberry Pi release page provides full and light versions. The main distinction is that the lite version doesn't come with a desktop environment, so it's great for running headless, which is what I do pretty much all the time, Raspberry Pi or no. Since I'm doing this the old-fashioned way, I'm using dd:

sudo dd bs=4M if=2021-03-04-raspios-buster-armhf-lite.img of=/dev/sdb conv=fsync status=progress
sync

If you're doing the same, just replace the if parameter with the filename you downloaded, and ensure the of parameter matches the SD Card plugged into your computer. As with any image writer utility, make sure you're pointing to the right drive. I typically use lsblk to do this. Hopefully, your SD card has a different storage capacity than your hard drive, so when you open a terminal and run lsblk, the SIZE column should be a dead giveaway. When you use this drive identifier in your dd command, also make sure you leave off any numbers. You're writing the whole drive, here. Once this command completes, I followed it up by entering sync into the terminal to ensure everything was written before I removed the card. With that, operating system complete!

Alternatively, use Raspberry Pi Etcher.

SSH Setup

With the operating system out of the way, it's time to start adding stuff. The first thing I always do is enable SSH. I have to say, when I got my first Pi, I was a Windows user. I downloaded PuTTY so I could get to my Pi remotely, and couldn't get over how nifty it was to not have to have a monitor plugged in whenever I wanted to access the thing. I think SSH and Raspberry Pis are really the catalysts that made me decide to move to Linux. I guess my point is be careful. Anyway, there are two easy ways to enable SSH: the login way and the hacky way. Either way, logging into the Pi can be done afterward once the IP address of the Pi is known. If you're wondering how, just log into your router and look for an entry whose MAC address starts with B8. In my experience, the MAC address of every Pi I've ever owned starts with these two characters. My IP is 192.168.0.23. With the IP in hand (or mind), you can log in with ssh:

ssh pi@192.168.0.23

The Login Way

I typically log into my Pis directly only once, and that is to enable SSH via raspi-config. Log into the Pi and open a terminal if you have the Raspbian Desktop. If you're using the Lite version, a terminal is all you have, so you're good. Type sudo raspi-config and click on Interface Options, followed by SSH and enable the SSH server when prompted.

The Hacky Way

If you don't want to log in at all, just go into the boot directory on your SD card and add an empty file called ssh via your preferred method. Personally, I just open a command line, execute touch ssh in no particular directory, and copy the file into the boot Pi's boot directory.

If you're connecting your Pi to the net over ethernet, you're done. If you're going to use Wi-Fi, there's one last step. Create a file called wpa_supplicant with the following contents:

country=US
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=us

network={
    scan_ssid=1
    ssid="networkid"
    psk="networkpassword"
}

Replace networkid with the SSID of your network, and networkpassword with your network's password. Add this file to the same boot directory as the ssh file, and you're done. When you plug this SD card into your Pi, it should enable SSH straight away and connect to your network.

SSH Keys

I like to log into my Pi using SSH keys, and it's not terribly difficult to do, provided the IP of the Pi is statically assigned. I ran ssh-keygen and followed the prompts to generate the keys (I use all the defaults and provided a password), and executed ssh-copy-id pi@192.168.0.23. If you're following along, you'll (probably) have a different IP.

Disable Password Login

Now that we have SSH keys set up, we can disable password logins. This effectively means that only devices that have already run ssh-copy-id can access the Pi. To disable password logins, the file /etc/ssh/ssh_config has a line that starts with Password Authentication that needs to be uncommented by removing the # symbol and changed its default yes value to no. The line then becomes:

PasswordAuthentication no

This works for all users. If I add a new user that I want SSH access to, I'll have to log in as pi first and change the no value in this file back to yes.

Disable Root Login

Another way to harden a Pi a little is by disabling login as root. The file for this is in the same directory, but it's sshd_config instead of ssh_config. The line in question for this purpose is this:

#PermitRootLogin yes

Again, uncomment the line by removing the # sign and change yes to no. This setting I never change. Pi has sudo privileges, that's always been good enough for me. The line should now read:

PermitRootLogin no

With that out of the way, Pi-Hole is now in view!

Pi-Hole

Pi-Hole was easy to install just by following their documentation. All that's required is running the following script:

curl -sSL https://install.pi-hole.net | bash

I pretty much went with the defaults in the setup. When you get to DNS selection you have to make a choice. I went with CloudFlare here, but I intend to move to Unbound eventually. I avoid Google for the most part on principle. It's not difficult to change these settings. If I eventually move to Unbound, I'll write a post about it. The last thing I did was change the password to log in:

pihole -a -p

Once Pi-Hole is set up, I still need to set my router to use my Pi as its primary DNS. The location of these settings vary by router, but I found mine under an Advanced tab and Network heading and a DHCP Server sub-heading. After I set the Primary DNS to the Pi's IP (192.168.0.23), I was able to verify Pi-Hole was eating requests.

It turns out, this was more setup than anything else, but instead of the takeaway being that I'm bad at this, I think the takeaway should instead be that Pi-Hole is just that easy.