Download and run Raspberry Pi Imager on your desktop computer. You'll also want to insert the microSD card into a microSD card reader. Take note of the drive letter of the microSD card - but no need to format it ahead of time as Raspberry Pi imager will do this for you. Underneath 'Operating System' click 'CHOOSE OS' Then click on Raspberry Pi OS (other) and choose Raspberry Pi OS Lite (64-bit). We don't need any sort of GUI or extra software here, so the Lite version of the Raspberry Pi OS is going to be just fine. Next, click 'CHOOSE STORAGE'. You'll want to select your microSD card. MAKE SURE you don't overwrite any drive that isn't the microSD card!! This is the only warning! If you pick the wrong drive, you will never get them back. Finally, click the gear icon so that we can set some of the Raspberry Pi default settings. Check the box next to 'Set Hostname:' and pick a name. I'm going to call mine pihole3.local. Check the box next to 'Enable SSH' and then leave the radio button on 'Use Password Authetication'. Scroll down and set a username and password for your Pi-hole SSH. I'm going to leave 'pi' as the username, but set a strong password. Optionally, you can scroll further down and check the box next to 'Set Locale Settings' and then pick your time zone and keyboard layout. When finished, click 'SAVE'. Finally, click 'WRITE' and your brand new Raspberry Pi OS will be written to the microSD card. This takes about 3-4 minutes. Once complete, remove the microSD card and insert it into your Raspberry Pi. Boot your Pi-hole Plug power into your Raspberry Pi to boot it up - the boot process should only take a minute or so. Other than the power cord, you should also have the Pi's Ethernet port plugged into a network switch. Once your Raspberry Pi has booted, it will likely grab an IP address from your network's DHCP server SSH into the Pi Once you have your Raspberry Pi's IP address, use SSH to log in. ssh pi@192.168.200.182 Where 'pi' is your username, and 192.168.200.182 is the IP address of your Raspberry Pi. The first thing we want to do is update all packages. To do so, run this command: sudo apt update && sudo apt upgrade -y Updating the Pi takes 4-5 minutes. Set a Static IP Address We want to ensure that the IP address of the Raspbery Pi never changes, so we need to set a static IP. If you dont have alot of devices on your network, you should be good just leaving it as is. Install Pi-hole Once you've set your Pi-hole's networking to a static IP address and rebooted (or if you've done a DHCP reservation), it's time to install Pi-hole. Remember to re-connect to the NEW IP address if you set it statically on the Raspberry Pi. Run this command to install Pi-hole: curl -sSL https://install.pi-hole.net | bash press OK (enter) next window confirms your static ip. Now we are going to pick an upstream DNS provider. This is the DNS server that the Pi-hole will use to do DNS lookups (initial lookups - then they get cached). Since we're going to be installing Unbound, we'll be making our own DNS lookups to the primary root domain servers on the Internet, so for now, it's fine to pick any one of these - I'll be using Cloudflare (1.1.1.1) for this tutorial. Next we're asked if we want to use the default included block list - this block list is a list of domains that Pi-hole is going to block for us. This list is perfectly fine, and will block a significant chunk of suspect sites - however, there are many block lists available, and you'll likely want to add some more - we'll cover this later in the tutorial. Choose YES and press ENTER. Another notice about the web server – just choose YES and press ENTER. Next, we're asked if we want to enable query logging. Typically, you will want to say Yes here, but if you're super security conscious and you don't want any of your DNS lookups logged, you can also choose No. Now we're asked about the level of privacy - you can visit the website listed for more information. For this tutorial, we're going to select 'Show everything' and press Continue. That's it! After this step, Pi-hole has all of the information it needs to get started. You'll see it run through a bunch of scripts in the CLI (takes about 2 minutes), and will eventually be brought to the credential screen. This final screen is giving a summary of our install and also shows us our Admin Webpage login password. You don't need to copy this down - we're going to change that password in the next step. Change the Pi-hole Web GUI Admin Password You'll want to set a nice strong password for the Pi-hole admin GUI - to do that, run this command: pihole -a -p This will have you input a password and then confirm it. Log into the Pi-hole GUI We're now ready to log into the GUI for the first time! Open up a browser and input the IP address followed by /admin in this format: http://192.168.200.52/admin (Substitute my IP address with your own). Note also that this is HTTP and not HTTPS. Enter the Admin password that you set in the previous step and click 'Log in.' Upon logging in, we're presented with the Pi-hole Dashboard - let’s take a look around! Not to make it a long explination of pihole ill show the most important settings. on the left hand side. Query Log - this shows you the Pi-hole's history of DNS lookups in descending order (most recent lookups at the top). You can see all domain statuses - both passed and blocked domains. For passed domains, there is a button to blacklist, and for blocked domains, there is a button to whitelist. Long-Term Data - much like the Query Log, this section gives you a deeper dive look into the Pi-hole's DNS history and lets you filter into that data in great detail. Groups and Clients - some pretty interesting functionality here in Groups and Clients - we're not going to dig into this section for this tutorial, but you can use this section if you wanted to block DNS queries for all devices except for devices in a specific group. Or, if you wanted to ONLY block DNS queries for devices in a specific group - you can get very granular with which clients and groups use which block lists as well. Domains - this section allows you to specifically add domains to a blacklist or whitelist. For instance, if there are specific stores where you like to shop online, and those stores are being blocked, you can whitelist them here. Adlists - by default, we have the default block list which is well maintained and blocks plenty of sites without breaking normal Internet functionality. That being said, you can get VERY detailed in what you're blocking - malicious sites, adult content, ad sites, tracking & telemetry sites - there are specific public block lists for each of these types of content, but keep in mind that the MORE sites you add to your block lists, the greater chance you have of breaking something. Then you'll have your family complaining to you about 'the Internet' not working, and you’ll have to deal with it. The trick is to find the happy medium that does plenty of blocking without affecting the user experience. Since we're taking a look at various block lists, let's go ahead and add a few from The Firebog page. Copy the first link under 'Suspicious Lists' and paste it into the 'Address:' field - then click Add. https://firebog.net/ Repeat this for as many block lists as you want - for this tutorial, I’m going to copy/paste the first two green URLs from each of the Firebog sections. Once completed, we need to tell Pi-hole to import these lists. Navigate to Tools -> Update Gravity and then click the 'Update' button. This will comb through all of the block lists and add the blocked URLs to the Pi-hole database. Once complete, you'll see a green 'Success' banner at the top of the screen. Now click on Dashboard from the left-hand menu - notice anything different? Our 'Domains on Adlists' jumped from about 158k to 221k blocked domains. Settings Last but certainly not least, we have our Settings. This demands its own section of this tutorial. We’ll start with the 'System' tab - this shows us various info about the Pi-hole - software versions, resource utilization, etc. We also have the option of controlling DNS and the server itself using the buttons at the bottom. The DNS tab shows us which upstream providers we're using for non-cached DNS queries. Since I picked Cloudflare during the setup wizard, we can see Cloudflare is my primary and secondary lookup source. You can also play around with the primary and secondary checkboxes here to have different DNS query sources - for instance, Cloudflare + Google. If you're doing this full tutorial and installing Unbound, ignore this for now - we'll be changing this shortly. One other thing to point out on the DNS tab - on the right hand side is the 'Interface settings' section. By default, the Pi-hole is configured to ONLY respond to DNS queries from your local LAN. But in my case, I have 3 separate VLANs in my home network - LAN, Guests, and IoT Devices. I want all of them to be able to use the Pi-hole, so we need to change that setting to allow requests from other subnets. In my case, I'm going to choose the 'Respond only on interface eth0' which basically allows any DNS requests that come into the network port.Be sure to hit Save at the bottom of the screen when you make this change! DHCP tab - the Pi-hole can be used as a DHCP server if you want, but this is beyond the scope of this tutorial. Configure Devices to use the Pi-hole Awesome - we've got our Pi-hole all up and running, and configured to block ads and other bad guys. But - right now, nothing is using this Pi-hole! Let's fix that - there are two main ways to configure your devices to use the Pi-hole - manually, and via DHCP. Manual device configuration - to configure your devices to use the Pi-hole manually, you need to open up your device’s network settings and set your DNS server to be the IP address of the Pi-hole (or Pi-holes if you're setting up multiple for redundancy). Holy crap! Now imagine going around and doing this for all of your devices - no thank you. The far superior method is to use your DHCP server to set these Pi-hole settings. This way, when devices connect to your network and request IP address information, they're automatically provided with your Pi-hole DNS servers. This method is going to vary depending on your DHCP server, but it's usually going to be similar to the way I have mine set in the EdgeRouter 4. Once you've made this change, you should shortly start seeing stats hit the Pi-hole dashboard: Unbound Setup OK - so we have our Pi-hole working and blocking stuff - excellent! But let's take this a step further. Right now, when we look up a website, if the Pi-hole doesn't know where to find it, it forwards that request to an upstream DNS provider (as we have it configured right now, that upstream provider is Cloudflare). Those who are more security-conscious may not want some random 3rd party knowing which domains they're surfing to or looking up (even though Cloudflare doesn't keep logs of DNS queries). For those folks, you can install Unbound on your Pi-hole. Unbound is a service that directly queries the DNS root domain servers for any uncached FQDN requests. First we'll need to install Unbound, and then we'll configure it for use with our Pi-hole. To install Unbound, SSH into the Pi-hole and run this command: sudo apt install unbound -y This should only take about 10-15 seconds. Next, we need to add a whole wall of text to an Unbound configuration file - create this file by running this command to edit it: sudo nano -w /etc/unbound/unbound.conf.d/pi-hole.conf Copy all of this text below - server: # If no logfile is specified, syslog is used # logfile: "/var/log/unbound/unbound.log" verbosity: 0 interface: 127.0.0.1 port: 5335 do-ip4: yes do-udp: yes do-tcp: yes # May be set to yes if you have IPv6 connectivity do-ip6: no # You want to leave this to no unless you have *native* IPv6. With 6to4 and # Terredo tunnels your web browser should favor IPv4 for the same reasons prefer-ip6: no # Use this only when you downloaded the list of primary root servers! # If you use the default dns-root-data package, unbound will find it automatically #root-hints: "/var/lib/unbound/root.hints" # Trust glue only if it is within the server's authority harden-glue: yes # Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS harden-dnssec-stripped: yes # Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes # see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details use-caps-for-id: no # Reduce EDNS reassembly buffer size. # IP fragmentation is unreliable on the Internet today, and can cause # transmission failures when large DNS messages are sent via UDP. Even # when fragmentation does work, it may not be secure; it is theoretically # possible to spoof parts of a fragmented DNS message, without easy # detection at the receiving end. Recently, there was an excellent study # >>> Defragmenting DNS - Determining the optimal maximum UDP response size for DNS <<< # by Axel Koolhaas, and Tjeerd Slokker (https://indico.dns-oarc.net/event/36/contributions/776/) # in collaboration with NLnet Labs explored DNS using real world data from the # the RIPE Atlas probes and the researchers suggested different values for # IPv4 and IPv6 and in different scenarios. They advise that servers should # be configured to limit DNS messages sent over UDP to a size that will not # trigger fragmentation on typical network links. DNS servers can switch # from UDP to TCP when a DNS response is too big to fit in this limited # buffer size. This value has also been suggested in DNS Flag Day 2020. edns-buffer-size: 1232 # Perform prefetching of close to expired message cache entries # This only applies to domains that have been frequently queried prefetch: yes # One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1. num-threads: 1 # Ensure kernel buffer is large enough to not lose messages in traffic spikes so-rcvbuf: 1m # Ensure privacy of local IP ranges private-address: 192.168.0.0/16 private-address: 169.254.0.0/16 private-address: 172.16.0.0/12 private-address: 10.0.0.0/8 private-address: fd00::/8 private-address: fe80::/10 -hit CTRL+X followed by Y and ENTER to save and exit. Then we’ll restart the Unbound service: sudo service unbound restart If you then run: sudo service unbound status You should see that the Unbound service is active (running). Using Unbound with Pi-hole Log into the Pi-hole Admin GUI and navigate to Settings -> DNS. Uncheck the boxes next to Cloudflare (or whichever DNS provider you picked during the install wizard), and then add a new custom entry for Unbound: 127.0.0.1#5335 Click 'Save' at the bottom of this screen. All done! Treat yourself to a beer. Testing Ad Blocking If you want to test out Ad Blocking go here : https://d3ward.github.io/toolz/adblock.html Updating the Pi-hole Every so often, you'll want to update Pi-hole. To do so, simply log into the Pi-hole via SSH and run this command: sudo pihole -up AND VUALA YOUR DONE THAT WASN'T SO HARD GOOD JOB.