trustworth.ee A most trustworth.ee corner of the Internet.

Running Docker Pihole on Synology Diskstation Manager v 7

2023-08-17

Background

I run a fair bit of OpenBSD in my home network. At this time, my firewall setup runs a chain of Unbound (with RPZ to block ads) to NSD (to maintain my internal domain hosts) to dnscrypt_proxy (to send my recursive queries to external hosts).

The unbound portion of this work is kinda clunky and homegrown. It was essentially trying to emulate a pihole setup that I didn’t want to dedicate hardware or an OpenBSD vmm to.

This page describes an incremental move away from that approach: I start by implementing pihole and forwarding everything to my router DNS service; since pihole will block everything that unbound would block, unbound will thus serve to either do local name resolution for my internal domain (lan.ckure.com) or send to the recursive upstream resolvers via dnscrypt_proxy.

Requirements

Setup

I decided to execute the pihole/pihole-latest container via a project. I’m not sure if that’s the best approach. But it was pretty straightforward, except that binding pihole to the “host” network wasn’t working. I looked at several things to solve a couple of issues:

Ultimately, I settled on IPTables forwarding of DNS traffic into the Docker network.

With that said, here are the key components of my working setup:

docker.compose

version: "3"

services:
  pihole:
    container_name: pihole
    image: pihole/pihole:latest

    ports:
      - "53:53/tcp"
      - "53:53/udp"
      # - "67:67/udp" # Only required if you are using Pi-hole as your DHCP server
      - "843:80/tcp"
    environment:
      TZ: 'America/New_York'
      WEBPASSWORD: ...
      PIHOLE_DNS_: $InternalDnsIp # eg. '192.168.1.254'
      REV_SERVER: "true"
      REV_SERVER_DOMAIN: $MyInternalDomain # eg. 'lan.ckure.com'
      REV_SERVER_TARGET: $InternalDnsIp # eg. '192.168.1.254'; you need this if you have an internal domain for your hosts
      REV_SERVER_CIDR: $MyLanSubnet # eg. '192.168.1.0/16'; you use this to tell pihole which subnet to send to REV_SERVER_TARGET for local DNS resolution
    # Volumes store your data between container upgrades
    volumes:
      - './etc-pihole:/etc/pihole'
      - './etc-dnsmasq.d:/etc/dnsmasq.d'
    # cap_add:
    #  - NET_ADMIN # Required if you are using Pi-hole as your DHCP server, else not needed
    restart: unless-stopped

scheduled task

In order to get past the container NAT and expose the 192.168.1.0/16 client IP addresses / reverse name lookups in pihole’s “Client” view, I need to add some IP tables rules. To do that, we run a scheduled task on boot:

  1. Control Panel > Task Scheduler

  2. Create a new user-defined script

    Pihole Nat Boot-up Script

  3. Use the following script to forward 53/udp and 53/tcp past the Docker NAT

    #!/bin/bash
    currentAttempt=0
    totalAttempts=10
    delay=3

    while [ $currentAttempt -lt $totalAttempts ]
    do
    currentAttempt=$(( $currentAttempt + 1 ))
    echo “Attempt $currentAttempt of $totalAttempts…"
    result=$(iptables-save)
    if [[ $result =~ “-A DOCKER -i docker0 -j RETURN” ]]; then

    echo “Docker rules found! Modifying…"
    iptables -t nat -A PREROUTING -p tcp –dport 53 -m addrtype –dst-type LOCAL -j DOCKER
    iptables -t nat -A PREROUTING -p udp –dport 53 -m addrtype –dst-type LOCAL -j DOCKER
    echo “Done!"
    break
    fi

    echo “Docker rules not found! Sleeping for $delay seconds…”

    sleep $delay
    done

References