Run unbound as pod with dedicated IP (#346)

* initial commit

* initial release version
This commit is contained in:
Alexander Wolf 2022-04-13 12:32:38 +02:00 committed by GitHub
parent e5f03a8d80
commit 840a08a1e3
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
6 changed files with 250 additions and 0 deletions

95
unbound/README.md Normal file
View File

@ -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)

View File

@ -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"}
]
}
}
]
}

View File

@ -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"}
]
}
}
]
}

View File

@ -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
unbound/scripts/init_unbound.sh Executable file
View File

@ -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
unbound/scripts/upd_unbound.sh Executable file
View File

@ -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