0

After reading few guides on how to setup PiHole with docker and IPv6 I tried to do it in my network. First things first, my ISP provides me with a Prefix Delegation which is then used to provide addresses to the rest of the network though router assignment (RA). The prefix is not static and is rotated every few days.

ULA setup

I am using a Ubiquity UDM-Pro and I have added the ULA prefix to the br0 interface as follows,

ip address add fd79:71d8:a0b7::1/64 dev br0

After which, all of my IPv6 capable devices are immediately assigned with a ULA address with that prefix.

docker configuration

To get docker working, I had to explicitly enable IPv6 and provide the cidr range. To do so, I created the daemon.json in /etc/docker with the following contents,

{
  "ipv6": true,
  "fixed-cidr-v6": "fd79:71d8:a0b7::/80"
}

Then I added to the NAT table in ip6tables the following command,

sudo ip6tables -t nat -A POSTROUTING -s fd79:71d8:a0b7::/80 ! -o docker0 -j MASQUERADE

Which allows the docker0 interface to receive IPv6 traffic. Of course, since these changes do not persist across reboots I also installed iptables-persistent and netfilter-persistent packages which allows these changes to persist across reboots.

I checked that IPv6 connectivity could be established by using,

$ docker run --rm -t busybox ping6 -c 4 google.com
PING google.com (2a00:1450:4017:811::200e): 56 data bytes
64 bytes from 2a00:1450:4017:811::200e: seq=0 ttl=56 time=62.514 ms
64 bytes from 2a00:1450:4017:811::200e: seq=1 ttl=56 time=61.256 ms
64 bytes from 2a00:1450:4017:811::200e: seq=2 ttl=56 time=61.503 ms
64 bytes from 2a00:1450:4017:811::200e: seq=3 ttl=56 time=61.850 ms

--- google.com ping statistics ---
4 packets transmitted, 4 packets received, 0% packet loss
round-trip min/avg/max = 61.256/61.780/62.514 ms

pihole configuration

The configuration of pihole was fairly straightforward, I used the following yaml saved as pihole.yaml for the docker-compose,

version: "3.8"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest
    ports:
      # dns ports
      - "53:53/tcp"
      - "53:53/udp"
      # ports for http interface
      - "19080:80/tcp"
      - "19443:443/tcp"
    environment:
      # redacted full address
      FTLCONF_LOCAL_IPV4: 10.10.x.25
      # redacted full address
      FTLCONF_LOCAL_IPV6: fd79:71d8:a0b7:0:...:ae38
    # IPs of your DNS entries
    dns:
      # this is for resolved conf, assuming you have ubuntu and disabled it
      - 127.0.0.1
      # proper DNS entries follow
      - 1.1.1.1
      - 1.0.0.1
      - 2606:4700:4700::1111
      - 2606:4700:4700::1001
    # Recommended but not required (DHCP needs NET_ADMIN)
    #   https://github.com/pi-hole/docker-pi-hole#note-on-capabilities
    cap_add:
      - NET_ADMIN
    restart: unless-stopped

Which I brought up using docker-compose -f pihole.yaml up.

Issue: replies come from another address or timeout

The issue is that I am not able to use this from other computers. In the machine the docker image is running I am able to use dig without any issue. For example, I get the following if I type the command in the host machine,

$ dig @fd79:71d8:a0b7:0:...:ae38 -p 53 google.com AAAA

; <<>> DiG 9.18.12-0ubuntu0.22.04.1-Ubuntu <<>> @fd79:71d8:a0b7:0:...:ae38 -p 53 google.com AAAA
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 60684
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1

;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com.            IN  AAAA

;; ANSWER SECTION:
google.com.     83  IN  AAAA    2a00:1450:4017:805::200e

;; Query time: 8 msec
;; SERVER: fd79:71d8:a0b7:0:...:ae38#53(fd79:71d8:a0b7:0:...:ae38) (UDP)
;; WHEN: Mon May 15 01:44:42 EEST 2023
;; MSG SIZE  rcvd: 67

However, then I type this in another Linux based machine - the command just times out, namely,

dig -6 @fd79:71d8:a0b7:0:...:ae38 -p 53 google.com
;; communications error to fd79:71d8:a0b7:0:...:ae38#53: timed out
;; communications error to fd79:71d8:a0b7:0:...:ae38#53: timed out
;; communications error to fd79:71d8:a0b7:0:...:ae38#53: timed out

; <<>> DiG 9.18.12-0ubuntu0.22.04.1-Ubuntu <<>> -6 @fd79:71d8:a0b7:0:...:ae38 -p 53 google.com
; (1 server found)
;; global options: +cmd
;; no servers could be reached

To investigate, I tried to see if the address was block or anything like that, but netcat shows that the port is open for business,

nc -z fd79:71d8:a0b7:0:...:ae38 53 -v

Connection to fd79:71d8:a0b7:0:...:ae38 53 port [tcp/domain] succeeded!

Upon further investigation, it seems that using dig from MacOS it gives a bit more information. The connection does not seem to timeout per se but reply from another address.

The output of dig in MacOS is as follows using the same address as before,

$ dig -6 @fd79:71d8:a0b7:0:...:ae38 google.com
;; reply from unexpected source: fd79:71d8:a0b7::60b#53, expected fd79:71d8:a0b7:0:...:ae38#53
;; reply from unexpected source: fd79:71d8:a0b7::60b#53, expected fd79:71d8:a0b7:0:...:ae38#53
; <<>> DiG 9.10.6 <<>> -6 @fd79:71d8:a0b7:0:5043:6018:fb4f:ae38 google.com
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached

Using the address that is being said to provide the answers works as expected,

dig -6 @fd79:71d8:a0b7::60b google.com
; <<>> DiG 9.10.6 <<>> -6 @fd79:71d8:a0b7::60b google.com
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9440
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 1232
;; QUESTION SECTION:
;google.com.            IN  A
;; ANSWER SECTION:
google.com.     156 IN  A   172.217.17.142
;; Query time: 22 msec
;; SERVER: fd79:71d8:a0b7::60b#53(fd79:71d8:a0b7::60b)
;; WHEN: Mon May 15 01:51:58 EEST 2023
;; MSG SIZE rcvd: 55

Looking at the interface IPs using ip -6 addr show dev enp9s0f1 reveals the following,

5: enp9s0f1: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc mq state UP group default qlen 1000
    link/ether b4:xx:xx:xx:xx:a6 brd ff:ff:ff:ff:ff:ff
    inet 10.10.x.25/24 brd 10.10.x.255 scope global dynamic noprefixroute enp9s0f1
       valid_lft 83538sec preferred_lft 83538sec
    inet6 2a02:587:<redacted>/128 scope global dynamic noprefixroute 
       valid_lft 83539sec preferred_lft 83539sec
    inet6 fd79:71d8:a0b7::60b/128 scope global dynamic noprefixroute 
       valid_lft 83539sec preferred_lft 83539sec
    inet6 2a02:587:<redacted>/64 scope global dynamic noprefixroute 
       valid_lft 73590sec preferred_lft 73590sec
    inet6 fd79:71d8:a0b7:0:...:ae38/64 scope global dynamic noprefixroute 
       valid_lft 86138sec preferred_lft 86138sec
    inet6 fe80::1ea:<redacted>:eb62/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

Why does the reply come from another address? I have disabled RFC4941 which uses a different address for outbound addresses, as is evidenced from here,

$ nmcli con show "Wired connection 4" | grep ipv6.ip
ipv6.ip6-privacy:                       0 (disabled)

The routing for IPv6 is as follows,

$ ip -6 route show
::1 dev lo proto kernel metric 256 pref medium
2a02:587:...::60b dev enp9s0f1 proto kernel metric 100 pref medium
2a02:587:...::/64 dev enp9s0f1 proto ra metric 100 pref medium
fd79:71d8:a0b7::60b dev enp9s0f1 proto kernel metric 100 pref medium
fd79:71d8:a0b7::/80 dev docker0 proto kernel metric 256 linkdown pref medium
fd79:71d8:a0b7::/80 dev docker0 metric 1024 linkdown pref medium
fd79:71d8:a0b7::/64 dev enp9s0f1 proto ra metric 100 pref medium
fe80::/64 dev docker0 proto kernel metric 256 linkdown pref medium
fe80::/64 dev br-5c9052b3a88b proto kernel metric 256 pref medium
fe80::/64 dev br-ba2b20fe7aa1 proto kernel metric 256 pref medium
fe80::/64 dev veth3fb9416 proto kernel metric 256 pref medium
fe80::/64 dev veth7a050e3 proto kernel metric 256 pref medium
fe80::/64 dev vethe299802 proto kernel metric 256 pref medium
fe80::/64 dev veth5110238 proto kernel metric 256 pref medium
fe80::/64 dev cali7ffb27b031d proto kernel metric 256 pref medium
fe80::/64 dev calib5cff4a4a14 proto kernel metric 256 pref medium
fe80::/64 dev cali6b881403436 proto kernel metric 256 pref medium
fe80::/64 dev calib1a2ba7ef9f proto kernel metric 256 pref medium
fe80::/64 dev cali20c73fad203 proto kernel metric 256 pref medium
fe80::/64 dev calib05d5a88d5c proto kernel metric 256 pref medium
fe80::/64 dev vxlan.calico proto kernel metric 256 pref medium
fe80::/64 dev enp9s0f1 proto kernel metric 1024 pref medium
default via fe80::...:62b3 dev enp9s0f1 proto ra metric 100 pref high

Can anyone help me understand why is this happening? I just cannot figure out why the response is coming from another address all the time... I would like to use stable ULA addresses for my DNS server because I cannot use the prefix provided by my ISP since it changes over time nor the privacy addresses as again these change over time.

jtimz
  • 101
  • 1
  • 1

0 Answers0