Skip to content

Set Up Raspberry Pi OS

The tools below are linked to their official download pages.

macOS users can install tools both using Homebrew. Windows and Linux users can download installers directly from each link.

For macOS users with Homebrew:

From your Mac
brew install sdformatter raspberry-pi-imager
  1. Insert a microSD card, then open SD Card Formatter and choose the card from the Select card dropdown.
  2. Select Format to format the card.
    • The default settings are fine: Quick format and no volume label.
  3. Exit SD Card Formatter and leave the SD card inserted.

Raspberry Pi Imager makes the SD card a bootable drive. After you set up the SD card, you’ll install it in the Raspberry Pi as its primary drive.

  1. Open Raspberry Pi Imager.
  2. Select your Raspberry Pi Device: Raspberry Pi 4.
  3. Choose operating system: Raspberry Pi OS (64-bit).
  4. Select your storage device: Select the SD card.
  5. Customisation: Choose hostname: pi-hole.
  6. Customisation: Localisation: Select your location and time zone.
    • My selections:
      • Capital city: Washington, D.C. (United States)
      • Time zone: America/New_York
      • Keyboard layout: us
  7. Customisation: Choose username: Create a user account.
    • The examples in this guide use the username pi-admin.
  8. Customisation: Choose Wi-Fi to configure the wireless network connection.
    • Select Next if you will connect using Ethernet.
  9. Customisation: SSH authentication: Enable SSH and select Use password authentication.
  10. Write image: select Write.
  11. In the popup, review the warning, then select I understand, erase and write to continue.
  12. When the write completes, remove the SD card from your computer and insert it into the Raspberry Pi.
  13. Plug in the Pi and give it a few minutes to boot.
Rebuilds and Upgrades: Confirm Your Linux Version

Pi-hole v6 requires Debian 11 (Bullseye) or later.

If you’re on an existing Pi, use cat /etc/os-release | grep PRETTY_NAME to confirm the release version before you continue:

From the Pi
pi-admin@pi-hole:~ $ cat /etc/os-release | grep PRETTY_NAME
PRETTY_NAME="Debian GNU/Linux 13 (trixie)"
  1. Find the Pi’s IP Address:

    From your device
    ping -c 3 pi-hole.local
    Other ways to find the Pi’s IP
    • Check your router
      • Look for a page that says “DHCP clients” or “connected devices.”
    • Scan the network
      • Use nmap -sn 192.168.1.0/24 (adjust the subnet for your network, 192.168.1.0 in this example).
  2. SSH into the Pi from your local terminal:

    From your device
    ssh pi-admin@pi-hole.local

    You can also use the IP you find in step 1 instead of pi-hole.local.

  3. Enter the password you set in Raspberry Pi Imager when prompted.

  4. If you configured Wi-Fi and also plugged the Pi in via Ethernet, your Pi will have two IP addresses.

    To make it easier to enable network-wide blocking later, identify the Pi’s Ethernet IP address.

    Confirm the Ethernet IP address from inside the SSH session on the Pi:

    From the Pi
    ip addr show eth0
Section titled “TP-Link Omada-specific steps to find and fix the Pi’s IP”
Find the Pi and set a fixed IP on a TP-Link Omada controller
  1. Log in and select the site’s name.

  2. Select Clients then Wired to filter the table of connected clients.

  3. Select pi-hole in the Client Name column to open the Details sidebar.

  4. Select Manage Client > Config and check Enable next to Use Fixed IP Address.

  5. Select Save.

    You should still follow the steps in the Set a Static IP section when you get there.

Set fixed IP in Omada controller

The non-root user that Raspberry Pi Imager created can run sudo commands without a password.

Raspberry Pi Imager creates a configuration file to enforce passwordless sudo. Remove the file so that sudo commands require authentication.

  1. Remove the configuration file:

    From the Pi
    sudo rm /etc/sudoers.d/010_pi-nopasswd
  2. Log out of the SSH session, then log back in:

    Terminal window
    exit
    ssh pi-admin@pi-hole.local

UFW (Uncomplicated Firewall) restricts which ports are accessible on the Pi. Pi-hole requires ports for DNS and the web interface. SSH is allowed for remote administration.

  1. Install UFW:

    From the Pi
    sudo apt install ufw
  2. Allow SSH immediately to avoid getting locked out later:

    From the Pi
    sudo ufw allow OpenSSH
  3. Set the defaults for incoming and outgoing connections:

    From the Pi
    sudo ufw default deny incoming
    sudo ufw default allow outgoing
  4. Add the following to /etc/ufw/applications.d/pihole to group the required ports into a single app profile rule. Remember to use sudo to edit files throughout this guide:

    /etc/ufw/applications.d/pihole
    [Pi-hole]
    title=Pi-hole
    description=Pi-hole DNS and Web Interface
    ports=53/tcp|53/udp|80/tcp|443/tcp

    If you don’t have a preferred terminal-based text editor, you can use sudo nano /etc/ufw/applications.d/pihole. That will create the file and open the nano editor so you can add the rule.

    To save and exit nano: CTRL+X, then Y, then Enter.

  5. Allow the profile:

    From the Pi
    sudo ufw allow Pi-hole
  6. Enable UFW with the new configuration:

    From the Pi
    sudo ufw enable
  7. Verify the rules are active:

    From the Pi
    sudo ufw status
If you plan to use Pi-hole as a DHCP server

Pi-hole as a DHCP server is not covered in this guide, but this seems to be an issue people encounter.

If you plan to use Pi-hole as a DHCP server, add another ufw allow:

From the Pi
sudo ufw allow 67/udp comment 'DHCP'

Fail2Ban automatically bans IPs that fail too many login attempts. This helps minimize the risk of brute-force attacks.

  1. Install Fail2Ban:

    From the Pi
    sudo apt install fail2ban
  2. Create /etc/fail2ban/jail.local:

    /etc/fail2ban/jail.local
    [sshd]
    enabled = true
    banaction = ufw
    maxretry = 4
    bantime = 1h
    findtime = 10m

    banaction = ufw tells Fail2Ban to use UFW to block IPs instead of managing iptables (an alternative way to manage network access to the Pi) rules directly, keeping all firewall rules in one place.

    Remember to use sudo to edit the file (sudo nano /etc/fail2ban/jail.local if you’re new to this).

  3. Enable and start Fail2Ban:

    From the Pi
    sudo systemctl enable --now fail2ban
  4. Verify the SSH jail is active:

    From the Pi
    sudo fail2ban-client status sshd

    You should see the jail listed as active with 0 currently banned IPs on a fresh install.

Pi-hole needs a stable IP address. If the router reassigns the Pi’s IP after a reboot, all your DHCP clients will point at the wrong address and potentially lose access to the Internet.

These steps use nmcli to lock the IP. They set the Ethernet connection name as a temporary shell variable. The variable is cleared when you exit the session.

  1. Set the static IP, gateway, and DNS.

    This example is intentionally set to fail if you don’t adjust YOUR-PI-IP and YOUR-GATEWAY-IP. This way you’re less likely to get locked out if you don’t change the example first:

    From the Pi
    CON=$(nmcli -t -f NAME,DEVICE con show | grep eth0 | cut -d: -f1) && \
    echo $CON && \
    sudo nmcli con mod "$CON" \
    ipv4.addresses YOUR-PI-IP/24 \
    ipv4.gateway YOUR-GATEWAY-IP \
    ipv4.dns "1.1.1.1" \
    ipv4.method manual
    Help with this step
    • This setting uses the shell variable CON to make it easier to copy and paste the command consistently. The first line finds the device’s name, and sets it as the variable. echo $CON on the second line displays it in the terminal for your information.
    • Replace YOUR-PI-IP with the Pi’s IP you found in step 1 of Configure Raspberry Pi OS.
    • Replace YOUR-GATEWAY-IP with your router’s IP (or your gateway if you already know it).

    For more about these settings, see the Red Hat networking guide.

    • If you do get locked out, you’ll need to access the Pi directly. Then run this same command in the terminal with the correct IPs.
  2. Apply the changes:

    From the Pi
    sudo nmcli con up "$CON"
  3. If you changed the IP address, your SSH session will drop.

    Still in the terminal, but on your local machine, remove the old cached keys and reconnect at the new IP:

    From your device
    ssh-keygen -R YOUR-OLD-PI-IP
    ssh pi-admin@YOUR-PI-IP

    Accept the new host key when prompted.

  4. Verify the settings persisted on the Pi:

    From the Pi
    ip addr show eth0

    Confirm your static IP is listed.

  5. Reboot the Pi:

    From the Pi
    sudo reboot now

    Wait a few minutes before you SSH back in.

At this point you have a hardened Raspberry Pi OS ready for Pi-hole.

Before you continue, confirm the following:

  • SSH access works: ssh pi-admin@pi-hole.local.
  • UFW is active with Pi-hole rules: sudo ufw status.
  • Fail2Ban is protecting SSH: sudo fail2ban-client status sshd.
  • The Pi has a static IP that won’t change on reboot.
  • If you run into issues, see Common Pi-hole Issues.

The next page covers installing Pi-hole, configuring DNS, and optionally adding unbound for recursive resolution and Netdata for monitoring.