DEV Community

Cover image for Pi-hole on Raspberry Pi with IPv6
Arif Amirani
Arif Amirani

Posted on • Originally published at arif.co

9 2

Pi-hole on Raspberry Pi with IPv6

I've had a Raspberry Pi 4B sitting in my cabinet for a few months now. I dusted it off and realized that the SD card was busted. Got a replacement 64GB U3 A2 card and got it up and running with Ubuntu server. The primary intended use was to run docker with DB containers that I use for my side projects such as Postgres/MySQL/MongoDB.

My current home network consists of several routers for WiFi reachability. I try to ensure 5Ghz coverage to all my devices. Due to the concrete walls a single router does not suffice, hence a home made mesh.

The earlier ISP was a IPv4 only provider. Easy to setup. Worked out of the box. To safeguard other users of the network, I use a privacy sensitive DNS provider, Adguard. The issue with Adguard DNS was no geo proximity. It caused large ping times, as the closest CDN was never picked.

When I moved to my new ISP which supports IPv6, I decided to also deploy Pi-hole alongwith my docker containers.

Home Network Layout

Installing Pi-hole

Pi-hole is quite easy to deploy, especially with the auto install script.

curl -sSL https://install.pi-hole.net | bash
Enter fullscreen mode Exit fullscreen mode

Once I followed the steps I got Pi-hole running out of the box. As suggested you have to change your router settings to send the IP address of your Pi-hole server as your local DNS. Done and done.

Pi-hole home

The Problem

Ads still show!

To ensure that I wasn't fudging up DHCP/DNS discovery I used scutil:

scutil --dns

resolver #1
  search domain[0] : lan
  nameserver[0] : 2405:201:xxxx:xxxx:xxx:xxxx:4209:2091
  nameserver[1] : fe80::a204:60ff:fe43:3005%en0
  nameserver[2] : 192.168.2.50
  if_index : 6 (en0)
  flags    : Scoped, Request A records, Request AAAA records
  reach    : 0x00020002 (Reachable,Directly Reachable Address)

Enter fullscreen mode Exit fullscreen mode

IPv4 looked good. 192.168.2.50 is the IP of my pi-hole server.

However, the IPv6 didn't belong to pi-hole. The default ISP setting was to use stateless IPv6 config and DNS was being advertised by the router. It was using my upstream DNS (ISP) server.

To fix this, I made the following changes:

IPv6 on pi-hole

  • Get your Ipv6 address for pi-hole
ip addr show
Enter fullscreen mode Exit fullscreen mode
  • Enable IPv6 support on pi-hole

IPv6 Slaac

  • Set the IPV6_ADDRESS add /etc/pihole/setupVars.conf

This should've already been done during the installation of pi-hole but if isn't, you can manually set it up using the address above

IPV4_ADDRESS=192.168.2.50/24
IPV6_ADDRESS=2405:xxx:xxxx:xxxx::50/64
Enter fullscreen mode Exit fullscreen mode

A neat trick I learnt while assigning static IPv6 addresses is to the use the same suffix as IPv4. Easy to remember and deal with.

Restart FTL:

systemctl restart pihole-FTL
Enter fullscreen mode Exit fullscreen mode
  • Enable AAAA query analysis for Pi-hole

Pi-hole by default will only analyse A queries, so we need to add support for AAAA.

DBINTERVAL=60
MAXDBDAYS=7
AAAA_QUERY_ANALYSIS=yes

PRIVACYLEVEL=0
Enter fullscreen mode Exit fullscreen mode

I also added a throttling parameters to not wear out the SD Card.

  • Refresh Pi-hole

Reboot the server. Fetch gravity lists again

pihole -g
Enter fullscreen mode Exit fullscreen mode
  • Stateful DHCPv6

ISP Stateful DHCPv6

My attempts at trying to get DHCP v4 and v6 from pi-hole failed. This is probably due to wrong assumptions of SLAAC + RA.

  • Debug Pi-hole

At the end I made sure everything is kosher by running diagnosis on Pi-hole

pihole -d
Enter fullscreen mode Exit fullscreen mode

Setting up Unbound

I do not like using any of the open DNS servers. They have their place and provide a lot of value but it's not for me. I prefer a combo of ad-block and recursive DNS. Unbound works perfectly with Pi-hole. Setting it up is again very simple.

apt install unbound
Enter fullscreen mode Exit fullscreen mode

Update the unbound config to support Pi-hole

/etc/unbound/unbound.conf.d/pi-hole.conf

Make a note of the port, the default port 53 is used by Pi-hole and must be changed.

server:
    interface: 0.0.0.0
    interface: ::0
    port: 5335

    access-control: 192.168.2.0/24 allow
    access-control: 127.0.0.0 allow
    access-control: 2001:db8:dead:beef::/48 allow

    # unbound optimisation
    num-threads: 4
    msg-cache-slabs: 16
    rrset-cache-slabs: 16
    infra-cache-slabs: 16
    key-cache-slabs: 16
    outgoing-range: 206
    so-rcvbuf: 4m
    so-sndbuf: 4m
    so-reuseport: yes
    rrset-cache-size: 100m
    msg-cache-size: 50m

    # unbound security
    do-ip4: yes
    do-ip6: yes
    do-udp: yes
    do-tcp: yes
    cache-max-ttl: 86400
    cache-min-ttl: 3600
    hide-identity: yes
    hide-version: yes
    minimal-responses: yes
    prefetch: yes
    use-caps-for-id: yes
    verbosity: 1
    harden-glue: yes
    harden-dnssec-stripped: yes

    # download from ftp://ftp.internic.net/domain/named.cache
    # root-hints: "/var/lib/unbound/root.hints"

    # Ensure privacy of local IP ranges
    private-domain: "lan"
    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
Enter fullscreen mode Exit fullscreen mode

Tweak it as per your needs and restart Unbound

systemctl restart unbound
Enter fullscreen mode Exit fullscreen mode

Check unbound

Will pass:

root@pi-desktop:~# dig sigok.verteiltesysteme.net @127.0.0.1 -p 5335
Enter fullscreen mode Exit fullscreen mode
; <<>> DiG 9.16.6-Ubuntu <<>> sigok.verteiltesysteme.net @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 48863
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sigok.verteiltesysteme.net.    IN  A

;; ANSWER SECTION:
sigok.verteiltesysteme.net. 3600 IN A   134.91.78.139

;; Query time: 499 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Tue Feb 23 08:53:17 IST 2021
;; MSG SIZE  rcvd: 71
Enter fullscreen mode Exit fullscreen mode

Will fail:

root@pi-desktop:~# dig sigfail.verteiltesysteme.net @127.0.0.1 -p 5335
Enter fullscreen mode Exit fullscreen mode
; <<>> DiG 9.16.6-Ubuntu <<>> sigfail.verteiltesysteme.net @127.0.0.1 -p 5335
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: SERVFAIL, id: 56203
;; flags: qr rd ra; QUERY: 1, ANSWER: 0, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 4096
;; QUESTION SECTION:
;sigfail.verteiltesysteme.net.  IN  A

;; Query time: 1147 msec
;; SERVER: 127.0.0.1#5335(127.0.0.1)
;; WHEN: Tue Feb 23 08:53:43 IST 2021
;; MSG SIZE  rcvd: 57
Enter fullscreen mode Exit fullscreen mode

DHCP Confirmation

At least for IPv4, you can run the debug tool to make sure DHCP is correct.

root@pi-desktop:~# pihole-FTL dhcp-discover
Scanning all your interfaces for DHCP servers
Timeout: 10 seconds

* Received 301 bytes from eth0:192.168.2.1
  Offered IP address: 192.168.2.113
  Server IP address: 192.168.2.1
  Relay-agent IP address: N/A
  BOOTP server: (empty)
  BOOTP file: (empty)
  DHCP options:
   Message type: DHCPOFFER (2)
   server-identifier: 192.168.2.1
   lease-time: 3600 ( 1h )
   renewal-time: 1800 ( 30m )
   rebinding-time: 3150 ( 52m 30s )
   netmask: 255.255.255.0
   broadcast: 192.168.2.255
   router: 192.168.2.1
   dns-server: 192.168.2.50
   dns-server: 192.168.2.50
   domain-name: "lan"
   --- end of options ---
Enter fullscreen mode Exit fullscreen mode

Switching Pi-hole to use unbound

Disable all Upstream DNS servers and add custom DNS that you setup for Unbound.
Use the loopback addresses for Unbound:

IPv4 - 127.0.0.1#5335

IPv6 - ::1#5335

Unbound with Pi-hole

That should be it! Hope you enjoyed reading the article.

Reinvent your career. Join DEV.

It takes one minute and is worth it for your career.

Get started

Top comments (0)

👋 Kindness is contagious

Immerse yourself in a wealth of knowledge with this piece, supported by the inclusive DEV Community—every developer, no matter where they are in their journey, is invited to contribute to our collective wisdom.

A simple “thank you” goes a long way—express your gratitude below in the comments!

Gathering insights enriches our journey on DEV and fortifies our community ties. Did you find this article valuable? Taking a moment to thank the author can have a significant impact.

Okay