Sunday, February 23, 2020

Raspberry Pi - pi-hole setup notes

In the category of "why didn't I do this sooner" - I finally setup my full network ad-blocking pi-hole. It's great! I can't believe I waited this long. The install is really quite straightforward for a basic system, however there are always options for fine tuning.

The basic install is quite good and blocks quite a bit of junk.

One of the places that has more extensive information on pi-hole options is this smart home beginner article, which ironically also features a ton of ads that are not blocked by a pi-hole default install. :/

When considering which device to run pi-hole on, consider the requirements. It does not have to be a Raspberry Pi, although that's nearly a perfect platform for most users. I ended up choosing a prior-generation Raspberry Pi 3 Model B+ for the lower power consumption and a Samsung 32GB microSDHC EVO, purchased separately.  Given my actual requirements, I probably should have chosen the Raspberry Pi 2, instead. (see below on power details)

My Raspberry Pi 3B+ has built-in WiFi and Bluetooth. Both are features that I will not likely use for my pi-hole. I prefer the reliability (and security) of a wired Ethernet connection for something as important as DNS lookups.

One of the benefits of the 3B+ is that the official Raspberry Pi PoE HAT can be used to power the Raspberry Pi over Ethernet. I didn't go this route.

Update: see my blog on Raspberry Pi Headless Setup. I've found setting up those 4 pre-configured files and copying them to the root of SD card at image-write-time is quite handy and gets the RPi basically operational with minimal fuss.

A key detail is to edit the config.txt file on the root of SD card (found in /boot/config.txt once RPi is running) before inserting into the RPi; add this line to allow serial TTL communication and avoid needing to plug in a monitor and keyboard for initial setup:

enable_uart=1

Note that despite having 5V pins right next door, the Raspberry Pi serial port uses 3.3V logic.

Connect your favorite USB to TTL Serial cable:
Raspberry Pi pinout showing Serial TTL from raspberrypi.org docs
Then login with putty or some other terminal program. For more detailed information on setting up a headless Raspberry Pi, see this sparkfun how-to.

I prefer to run sudo raspi-config to do things like:
  • Assign password
Network Options:
  • assign host name such as "pi-hole"
Localisation Options:
  • Change the locale to en_US.UTF-8 UTF-8
  • Change timezone to Pacific Time
Interfacing Options:
  • Disable Camera
  • Enable SSH
  • Disable VNC
  • Disable SPI
  • Disable I2C
  • Enable Serial
  • Disable 1-Wire
  • Disable Remote GPIO
Advanced Options:
  • Expand Filesystem 
  • GPU Memory Split set to 16
Update raspi-config to the latest version.

Next assign a static IP address via sudo nano /etc/dhcpcd.conf and add these lines:

interface eth0
        static ip_address=192.168.1.77/24
        static routers=192.168.1.254
        static domain_name_servers=127.0.0.1

Put in your values for device IP address, router, and actual DNS (needed for initial install) . After setting up the pi_hole, set the DNS to 127.0.0.1 as shown.

Disable IPV6 unless you know you need it. Edit /etc/sysctl.conf and put these lines at the bottom:
net.ipv6.conf.all.disable_ipv6 = 1
net.ipv6.conf.default.disable_ipv6 = 1
net.ipv6.conf.lo.disable_ipv6 = 1
net.ipv6.conf.tun0.disable_ipv6 = 1


One of the main problems with the Raspberry Pi is the continual writing to the SD card and subsequent (lack of) reliability when in operation for years. See the log2ram install, below, that can help with this. Hackaday also has an article on the coolness of log2ram that refers to this log2ram blog by Erich Styger.

Next, main setup:

# system update
sudo apt-get update && sudo apt-get upgrade

# install essentials
sudo apt-get install git
sudo apt-get install fail2ban
sudo apt-get install dnsutils
sudo apt-get install arpwatch
sudo apt-get install iptables-persistent

# remove things that will not be used:
sudo apt-get purge realvnc-vnc-server --assume-yes

# basic pi-hole install
cd ~/
git clone --depth 1 https://github.com/pi-hole/pi-hole.git
cd "pi-hole/automated install/"
sudo bash basic-install.sh
sudo pihole -a -p

# log2ram install (optional)
cd ~/
curl -Lo log2ram.tar.gz https://github.com/azlux/log2ram/archive/master.tar.gz
tar xf log2ram.tar.gz
cd log2ram-master
chmod +x install.sh && sudo ./install.sh
# REBOOT BEFORE INSTALLING ANYTHING ELSE

This might be a good time to set that static domain_name_servers=127.0.0.1 setting.

Operational check for log2ram:

# not blank if working properly:
mount | grep log2ram

# not blank if working properly:
df -h | grep log2ram

If it appears the log files need more space, edit the /etc/log2ram.conf
.
See firewall notes for supported operating systems. Secure the RPi with IP Tables (optional):

# Flush the tables to apply changes
sudo iptables -F
sudo ip6tables -F

# Default policy to drop everything but our output to internet
sudo iptables -P FORWARD DROP
sudo iptables -P INPUT   DROP
sudo iptables -P OUTPUT  ACCEPT

# do the same for IPv6
sudo ip6tables -P FORWARD DROP
sudo ip6tables -P INPUT   DROP
sudo ip6tables -P OUTPUT  ACCEPT

# Allow established connections (the responses to our outgoing traffic)
sudo iptables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow IPv6 established connections (the responses to our outgoing traffic)
sudo ip6tables -A INPUT -m state --state ESTABLISHED,RELATED -j ACCEPT

# Allow local programs that use loopback (Unix sockets)
sudo iptables -A INPUT -s 127.0.0.0/8 -d 127.0.0.0/8 -i lo -j ACCEPT

# allow incoming SSH/SCP conections to this machine from 192.168.1.0/24 only
sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 22 -m state --state NEW -j ACCEPT

# In case a Windows drive is mapped, uncomment this line:
# sudo iptables -A INPUT -s 192.168.1.0/24 -p tcp --dport 445 -m state --state NEW -j ACCEPT

# pi-hole ports
iptables -I INPUT 1 -p tcp -m tcp --dport 80 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 53 -j ACCEPT
iptables -I INPUT 1 -p udp -m udp --dport 53 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 67 -j ACCEPT
iptables -I INPUT 1 -p udp -m udp --dport 67 -j ACCEPT
iptables -I INPUT 1 -p tcp -m tcp --dport 4711 -i lo -j ACCEPT

# save iptables to be in place after a reboot
sudo /sbin/iptables-save > ~/iptables.txt
sudo cp ~/iptables.txt /etc/iptables/rules
iptables-persistent
iptables --list


To make the IP Table changes stick, I chose iptables-persistent

See also: Linux Iptables: How to specify a range of IP addresses or ports.

If your pi-hole sits on a different network then all traffic it "sees" will appear to come from a single router IP address.

Some people may be interested in unbound recursive DNS server solution (see also this how-to). I didn't initially have much luck with it, and in fact I later saw my first system crash on a different Raspberry Pi within 24 hours of installing it.

Once everything is setup, there are MANY more lists to make the pi-hole even better. Thanks Jermal Smith for suggestions on other lists to block from his pi-hole blog.

For more information on manually adding domains, see the pihole command. Local lists can be appended by using the FILE:// syntax, although the data in that file does not seem to be successfully added to block list. No warning or other message is given:


file://c:/download/pi-hole/my_block_list.txt

Yet after refresh, the entry is not in the block domain list search:


So perhaps a GitHub gist is a better home for custom lists.

To add a large list of lists, such as this one from Jermal Smith, simply add them to the respective /etc/pihole/adlists.list on the pi-hole. Be sure to include only URL's and not the title text in the first line.

Some essentials that I needed to whitelist:


aka.ms - used for Visual Studio updates


A final fine-tuning: See the Raspberry Pi Power Requirements. It's a shame to waste standby power for things not being used. Note that the Raspberry Pi 3 Model B+ I chose typically uses 500mA. In contrast, the Raspberry Pi 2 uses only 350mA, Part of the difference is the on-board WiFi and Bluetooth capabilities.

These can be manually turned off:


sudo iwconfig wlan0 power off
This can be added to /etc/rc.local. Also consider editing /etc/modprobe.d/raspi-blacklist.conf as noted in the forum topic:


#wifi
blacklist brcmfmac
blacklist brcmutil
#bt
blacklist btbcm
blacklist hci_uart

or

# ref: https://www.raspberrypi.org/forums/viewtopic.php?f=63&t=138610
# bluetooth
blacklist hci_uart
blacklist btbcm
blacklist btintel
blacklist rfcom
blacklist btqca
blacklist btsdio
blacklist bluetooth


And edit the /boot/config.txt:


dtoverlay=pi3-disable-wifi
dtoverlay=pi3-disable-bt


Note the 1000BaseT has a higher power requirement.

My Raspberry Pi operates at about 50°C; (specs qualified from -40°C to 85°C)

For more information, see the pi-hole discourse.

2 comments:

  1. Pi-hole is fantastic. However, I stopped installing and configuring individual software components on my Pi long ago. These days every application runs isolated in its own Docker container. See https://www.youtube.com/watch?v=a6mjt8tWUws to get an idea of what that could look like.

    ReplyDelete
  2. Thank you for a great write-up, I found it very useful!

    A note for anyone following the instructions: setting up acceptance of HTTP traffic etc (below the line # pi-hole ports) requires su privileges, so the line should be pre-pended with sudo.

    ReplyDelete

comments are welcome, but I prefer not to allow links to promotions or other unrelated services.

Find gojimmypi at gojimmypi.github.io

I'm currently working on my new blog home at  gojimmypi.github.io After implementing a variety of features such as dark mode , syntax hi...