Skip to content

Commit

Permalink
Run unbound as pod with dedicated IP (unifi-utilities#346)
Browse files Browse the repository at this point in the history
* initial commit

* initial release version
  • Loading branch information
alxwolf authored Apr 13, 2022
1 parent e5f03a8 commit 840a08a
Show file tree
Hide file tree
Showing 6 changed files with 250 additions and 0 deletions.
95 changes: 95 additions & 0 deletions unbound/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
# Running `unbound` on the UDM/P

This example is "ready to run" out of the box, if you've already installed Pi-hole on your UDM/P. Adjust the MAC and IP addresses if necessary. As updating `podman`on UDM/P is prone to making mistakes, this is set up to run in a separate container.

## Prerequisites

Finish setup of [on_boot.d](../on-boot-script/) and [dns-common](../dns-common).

### Create another `podman` network

`unbound` will run on a different IP address to avoid any collisions.

In the current examples, the DNS resolver (e.g., pi-hole) is listening on `10.0.5.2`. The example will make `unbound` listen on `10.0.5.3`.

Follow the steps in [run-pihole](../run-pihole) to create a separate IP address, by copying the files in the sub-directories to UDM/P.

Adjust the `11-unbound-macvlanip` and `.conflist` files, run [init_unbound.sh](./scripts/init_unbound.sh), *or* execute the commands below manually.

* Link the boot script [11-unbound-macvlanip.sh](./on_boot.d/11-unbound-macvlanip.sh) -> `ln -s /mnt/data/unbound/on_boot.d/11-unbound-macvlanip.sh /mnt/data/on_boot.d/11-unbound-macvlanip.sh`
* Link the IPv4 only configuration: [21-unbound.conflist](./cni_plugins/21-unbound.conflist) -> `ln -s /mnt/data/unbound/cni_plugins/21-unbound.conflist /etc/cni/net.d/21-unbound.conflist` *or*
* Link the IPv4 and IPv6 configuration: [21-unboundipv6.conflist](./cni_plugins/21-unboundipv6.conflist) -> `ln -s /mnt/data/unbound/cni_plugins/21-unboundipv6.conflist /etc/cni/net.d/21-unbound.conflist`
* Create the network

```bash
podman network create unbound
sh ../on_boot.d/11-unbound-macvlanip.sh
```

The error - if it's the first time you run it - can be ignored.

## Run the container for the first time

Run the script to start the container.

```bash
sh ./scripts/upd_unbound.sh
```

## Using unbound as upstream server for Pi-hole

Two things are left to do: set the upstream server and de-activate caching in Pi-hole.

To use `unbound` as the upstream server for Pi-hole, change the following settings in Pi-hole's admin interface:

* Settings -> DNS -> Upstream DNS Servers
* Custom 1 (IPv4): 10.0.5.3 (or the IPv4 address you chose)
* Custom 2 (IPv6): fdca:5c13:1fb8::3 (or the IPv6 address you chose)

Both Pi-hole as well as `unbound` are caching their requests. To make the changes of your upstream DNS and to de-activate caching in Pi-hole permanent, modify your `podman run` command **for pi-hole** in this way:

```sh
podman run -d --network dns --restart always \
--name pihole \
-e TZ="America/Los Angeles" \
-v "/mnt/data/pihole/etc-pihole/:/etc/pihole/" \
-v "/mnt/data/pihole/etc-dnsmasq.d/:/etc/dnsmasq.d/" \
--dns=127.0.0.1 \
--dns=10.0.5.3 \
--hostname pi.hole \
-e VIRTUAL_HOST="pi.hole" \
-e PROXY_LOCATION="pi.hole" \
-e PIHOLE_DNS_="10.0.5.3" \
-e CUSTOM_CACHE_SIZE=0 \
-e FTLCONF_REPLY_ADDR4="10.0.5.2" \
-e FTLCONF_REPLY_ADDR6="fdca:5c13:1fb8::2" \
-e IPv6="False" \
pihole/pihole:latest
```

Again, replace the IPv4 and IPv6 addresses if you deviate from this example.

## Checking the configuration

To see if everything is configured properly, run the commands:

```bash
dig A doubleclick.net @10.0.5.2 +short
0.0.0.0
dig AAAA doubleclick.net @192.168.4.2 +short
::

dig A doubleclick.net @10.0.5.3 +short
142.251.37.14
dig AAAA doubleclick.net @192.168.4.3 +short
2a00:1450:4016:80b::200e
```

The first two commands query Pi-hole and do not return a valid IP address - as intended. The two following queries ask `unbound` and return valid IP addresses.

## Container image

This container is based on `klutchell/unbound`.

[Docker Hub](https://hub.docker.com/r/klutchell/unbound)
[Github](https://github.com/klutchell/unbound-docker)
24 changes: 24 additions & 0 deletions unbound/cni_plugins/21-unbound.conflist
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
{
"cniVersion": "0.4.0",
"name": "unbound",
"plugins": [
{
"type": "macvlan",
"mode": "bridge",
"master": "br5",
"mac": "EE:CC:EC:A2:7C:D1",
"ipam": {
"type": "static",
"addresses": [
{
"address": "10.0.5.3/24",
"gateway": "10.0.5.1"
}
],
"routes": [
{"dst": "0.0.0.0/0"}
]
}
}
]
}
28 changes: 28 additions & 0 deletions unbound/cni_plugins/21-unboundipv6.conflist
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
{
"cniVersion": "0.4.0",
"name": "unbound",
"plugins": [
{
"type": "macvlan",
"mode": "bridge",
"master": "br5",
"mac": "EE:CC:EC:A2:7C:D1",
"ipam": {
"type": "static",
"addresses": [
{
"address": "10.0.5.3/24",
"gateway": "10.0.5.1"
},
{
"address": "fdca:5c13:1fb8::3/64",
"gateway": "fdca:5c13:1fb8::1"
}
],
"routes": [
{"dst": "0.0.0.0/0"},{"dst": "::/0"}
]
}
}
]
}
60 changes: 60 additions & 0 deletions unbound/on_boot.d/11-unbound-macvlanip.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#!/bin/sh

## configuration variables:
VLAN=5
IPV4_IP="10.0.5.3"
# This is the IP address of the container. You may want to set it to match
# your own network structure such as 192.168.5.3 or similar.
IPV4_GW="10.0.5.1/24"
# As above, this should match the gateway of the VLAN for the container
# network as above which is usually the .1/24 range of the IPV4_IP

# if you want IPv6 support, generate a ULA, select an IP for the dns server
# and an appropriate gateway address on the same /64 network. Make sure that
# the 20-dns.conflist is updated appropriately. It will need the IP and GW
# added along with a ::/0 route. Also make sure that additional --dns options
# are passed to podman with your IPv6 DNS IPs when deploying the container for
# the first time. You will also need to configure your VLAN to have a static
# IPv6 block.

# IPv6 Also works with Prefix Delegation from your provider. The gateway is the
# IP of br(VLAN) and you can pick any ip address within that subnet that dhcpv6
# isn't serving
IPV6_IP="fdca:5c13:1fb8::3"
IPV6_GW="fdca:5c13:1fb8::1/64"

# to deactivate IPv6, uncomment lines below and comment out the lines above
#IPV6_IP=""
#IPV6_GW=""

# container name:unbound
CONTAINER=unbound

if ! test -f /opt/cni/bin/macvlan; then
echo "Error: CNI plugins not found. You can install it with the following command:" >&2
echo " curl -fsSLo /mnt/data/on_boot.d/05-install-cni-plugins.sh https://raw.githubusercontent.com/boostchicken-dev/udm-utilities/master/cni-plugins/05-install-cni-plugins.sh && /bin/sh /mnt/data/on_boot.d/05-install-cni-plugins.sh" >&2
exit 1
fi

# we assume that the VLAN bridge already exists, created by the filtering DNS (pi-hole) script
# add IPv4 IP
ip addr add "${IPV4_GW}" dev "br${VLAN}.mac" noprefixroute

# (optional) add IPv6 IP to VLAN bridge macvlan bridge
if [ -n "${IPV6_GW}" ]; then
ip -6 addr add "${IPV6_GW}" dev "br${VLAN}.mac" noprefixroute
fi

# add IPv4 route to unbound container
ip route add "${IPV4_IP}/32" dev "br${VLAN}.mac"

# (optional) add IPv6 route to DNS container
if [ -n "${IPV6_IP}" ]; then
ip -6 route add "${IPV6_IP}/128" dev "br${VLAN}.mac"
fi

if podman container exists "${CONTAINER}"; then
podman start "${CONTAINER}"
else
logger -s -t podman-unbound -p "ERROR Container ${CONTAINER} not found, make sure you set the proper name, you can ignore this error if it is your first time setting it up"
fi
25 changes: 25 additions & 0 deletions unbound/scripts/init_unbound.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#!/bin/sh

# init unbound container - quick and dirty for now
# no checks, no balances

echo "Creating links..."
# link the script to create an IP on the macvlan for unbound
ln -s /mnt/data/unbound/on_boot.d/11-unbound-macvlanip.sh /mnt/data/on_boot.d/11-unbound-macvlanip.sh

# configure either IPv4 only or IPv4 and IPv6 by uncommenting the proper line
#

# link the IPv4 configuration for CNI
# ln -s /mnt/data/unbound/cni_plugins/21-unbound.conflist /etc/cni/net.d/21-unbound.conflist

# link the IPv4 and IPv6 configuration for CNI
ln -s /mnt/data/unbound/cni_plugins/21-unboundipv6.conflist /etc/cni/net.d/21-unbound.conflist

# create the podman network unbound
echo "Creating podman network..."
podman network create unbound

# create the container IP
echo "Creating container IP..."
sh /mnt/data/on_boot.d/11-unbound-macvlanip.sh
18 changes: 18 additions & 0 deletions unbound/scripts/upd_unbound.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#!/bin/sh
CONTAINER=unbound
IMAGE=klutchell/unbound:latest

echo "Pulling image..."
podman pull $IMAGE
echo "Stopping container..."
podman stop $CONTAINER
echo "Removing container..."
podman rm $CONTAINER
echo "Updating root hints..."
mkdir -p /mnt/data/unbound/unbound.conf.d/
curl -m 30 -o /mnt/data/unbound/unbound.conf.d/root.hints https://www.internic.net/domain/named.root
echo "Running $CONTAINER container"
podman run -d --net unbound --restart always \
--name $CONTAINER \
-v "/mnt/data/unbound/unbound.conf.d/:/opt/unbound/etc/unbound/ " \
$IMAGE

0 comments on commit 840a08a

Please sign in to comment.