-
Notifications
You must be signed in to change notification settings - Fork 286
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Adding a 2nd docker-compose config for running both Pi-Hole and Unbound in the same container (following recommended steps in the Pi-Hole docs). Restructuring the project to maintain the old 2-container setup as well.
- Loading branch information
1 parent
a65711c
commit f976f46
Showing
16 changed files
with
296 additions
and
131 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
.env | ||
.DS_Store | ||
.idea | ||
build_and_push.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,134 +1,11 @@ | ||
# Pi-Hole + Unbound on Docker | ||
|
||
#### (Synology-compatible!) | ||
### Use Docker to run [Pi-Hole](https://pi-hole.net) with an upstream [Unbound](https://nlnetlabs.nl/projects/unbound/about/) resolver. | ||
|
||
## Description | ||
Changing this repo to support 2 different docker-compose configurations now: | ||
|
||
Running Pi-Hole in Docker can be challenging due to networking requirements by Pi-Hole, this is especially true when the ports that Pi-Hole uses are shared by the host it's running on (this is true for Synology in the default configuration). | ||
|
||
This project uses a [`macvlan` Docker network](https://docs.docker.com/network/macvlan/) to place your containers on your main network, with their own IP addresses and MAC addresses. | ||
|
||
- This docker-compose runs the following 2 containers | ||
- Pi-Hole ([pihole/pihole](https://hub.docker.com/r/pihole/pihole)) - Official from Pi-Hole | ||
- Unbound ([mvance/unbound](https://hub.docker.com/r/mvance/unbound)) - There are several choices here but I like this one the best | ||
|
||
Pi-Hole uses Unbound as it's resolver, and Unbound uses Cloudflare (1.1.1.1) and CleanBrowsing upstream in order to support DNSSEC and DNS-over-TLS. **This is an important detail** about this particular setup-- we are not making queries direct to the root servers as some of the Pi-Hole docs show in their examples. Here's a snippet from the [Unbound config](https://github.com/MatthewVance/unbound-docker/blob/master/1.8.3/unbound.sh) (v1.8.3 as of writing this doc) showing what's happening: | ||
|
||
``` | ||
... | ||
forward-zone: | ||
# Forward all queries (except those in cache and local zone) to | ||
# upstream recursive servers | ||
name: "." | ||
# Queries to this forward zone use TLS | ||
forward-tls-upstream: yes | ||
# https://dnsprivacy.org/wiki/display/DP/DNS+Privacy+Test+Servers | ||
# Cloudflare | ||
forward-addr: 1.1.1.1@853#cloudflare-dns.com | ||
forward-addr: 1.0.0.1@853#cloudflare-dns.com | ||
# CleanBrowsing | ||
forward-addr: 185.228.168.9@853#security-filter-dns.cleanbrowsing.org | ||
forward-addr: 185.228.169.9@853#security-filter-dns.cleanbrowsing.org | ||
... | ||
``` | ||
|
||
If you want to change any of this Unbound config then you can fork MatthewVance's [unbound-docker repo](https://github.com/MatthewVance/unbound-docker) and modify his `unbound.sh` file. | ||
|
||
## Disclaimer | ||
|
||
Using this type of configuration on a Synology NAS is somewhat of an advanced use-case, and it should come with some security/stability considerations: | ||
|
||
- Enabling SSH on your Synology NAS is non-default and should be done with care. | ||
- I would recommend __(1)__ configuring SSH to not use default port 22 and __(2)__ to __never__ forward the SSH port outside of your home network. | ||
- Poking around in the Synology CLI can lead to bad things in your NAS if you you don't know what you're doing. As a rule of thumb I would not touch any files outside of the `/volumeX/` folders unless you know what you're doing. These are the folders which are reflected to the user inside of `File Station` GUI. | ||
|
||
|
||
## Instructions | ||
|
||
### Hold your horses and configure some stuff first... | ||
|
||
- Update `docker-compose.yaml` to match your environment, eg. IP addresses/subnets. | ||
- Take note of the `networks.home.driver_opts.parent` value, the default value of `ovs_eth1` is for using the 2nd ethernet port on a Synology NAS with `Open vSwitch` enabled (configured in `Control Panel` -> `Network` -> `Network Interface` -> `Manage`), if disabled use `eth1` instead, or whichever other interface you might be using in your setup. | ||
- Add a `.env` file next to the docker-compose.yaml so you can pass in the `${WEBPASSWORD}` - this is your Pi-Hole admin password. You can optionally leave this step out and set the password via CLI (`pihole -a -p`) after the Pi-Hole is running | ||
- Update the secondary/backup nameserver in the `pihole/config/resolv.conf` file, or remove it if you don't have a backup (would recommend having one!) | ||
- Lastly, optionally, you can provide some manual DNS entries in the `pihole/config/dnsmasq.conf` and/or `pihole/config/hosts` files | ||
|
||
### Run it! | ||
|
||
Copy the files up to your Docker host (eg Synology) | ||
|
||
> __Note__: Synology does not support `docker-compose` via their GUI but the running containers that get created here will be visible there when you're done. | ||
On client machine: | ||
|
||
```bash | ||
# Make sure the target directory exists first! | ||
# Can use something like `mkdir -p /volume1/docker/pihole-unbound` | ||
|
||
cd docker-pihole-unbound | ||
scp -r ./* [email protected]:/volume1/docker/pihole-unbound/ | ||
``` | ||
|
||
On the Docker host (eg Synology) | ||
|
||
```bash | ||
cd /volume1/docker/pihole-unbound | ||
sudo docker-compose up -d | ||
``` | ||
|
||
__Note__: If you're using Synology, you'll need to `scp` these files to your NAS and run it from the CLI since `docker-compose` is not currently supported through their DSM GUI. | ||
|
||
### Test it! | ||
|
||
Test your configuration with dig | ||
|
||
> __Note__: change the IP to your new Pi-Hole's IP | ||
```bash | ||
dig google.com @192.168.1.5 | ||
# Expecting "status: NOERROR" | ||
``` | ||
|
||
You can also test for DNSSEC functionality: | ||
|
||
```bash | ||
dig sigfail.verteiltesysteme.net @192.168.1.5 | ||
# Expecting "status: SERVFAIL" | ||
|
||
dig sigok.verteiltesysteme.net @192.168.1.5 | ||
# Expecting "status: NOERROR" | ||
``` | ||
|
||
### Serve it! | ||
|
||
If all looks good, configure your router/DHCP server to serve your new Pi-Hole IP address (`192.168.1.5`) to your clients. | ||
|
||
> Note: it may take some time for the current DHCP leases to renew and for clients to get the new DNS service info -- generally the default is 24 hours or less. | ||
### Update it! | ||
|
||
When updated container images are released you can execute these commands on your Docker host to pull them in and run them | ||
|
||
```bash | ||
cd /volume1/docker/pihole-unbound | ||
sudo docker-compose pull | ||
sudo docker-compose down | ||
sudo docker-compose up -d | ||
``` | ||
|
||
## Acknowledgements | ||
|
||
- [http://tonylawrence.com/posts/unix/synology/free-your-synology-ports/][synology-ports] | ||
- [https://github.com/MatthewVance/unbound-docker][unbound-docker] | ||
- [https://pi-hole.net][pihole] | ||
- [https://nlnetlabs.nl/projects/unbound/about/][unbound] | ||
|
||
[synology-ports]: http://tonylawrence.com/posts/unix/synology/free-your-synology-ports/ | ||
[unbound-docker]: https://github.com/MatthewVance/unbound-docker | ||
[pihole]: https://pi-hole.net | ||
[unbound]: https://nlnetlabs.nl/projects/unbound/about/ | ||
- [`one-container`](one-container/) (new) - Install Unbound directly into the Pi-Hole container | ||
- This configuration contacts the DNS root servers directly, please read the Pi-Hole docs on [Pi-hole as All-Around DNS Solution](https://docs.pi-hole.net/guides/unbound/) to understand what this means. | ||
- With this approach, we can also simply our networking since `macvlan` is no longer necessary. | ||
- [`two-container`](two-container/) (legacy) - Use separate containers for Pi-Hole and Unbound | ||
- This configuration uses MatthewVance's [unbound-docker](https://github.com/MatthewVance/unbound-docker) container to implement encrypted DNS to third party DNS resolvers (eg Cloudflare). This is arguably less privacy-friendly since you're handing your DNS queries to those 3rd party providers. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,47 @@ | ||
# Pi-Hole + Unbound - 1 Container | ||
|
||
## Description | ||
|
||
This Docker deployment runs both Pi-Hole and Unbound in a single container. | ||
|
||
The base image for the container is the [official Pi-Hole container](https://hub.docker.com/r/pihole/pihole), with an extra build step added to install the Unbound resolver directly into to the container based on [instructions provided directly by the Pi-Hole team](https://docs.pi-hole.net/guides/unbound/). | ||
|
||
## Usage | ||
|
||
First create a `.env` file to substitute variables for your deployment. | ||
|
||
|
||
### Required environment variables | ||
|
||
> Vars and descriptions replicated from the [official pihole container](https://github.com/pi-hole/docker-pi-hole/): | ||
| Docker Environment Var | Description| | ||
| --- | --- | | ||
| `ServerIP: <Host's IP>`<br/> | **--net=host mode requires** Set to your server's LAN IP, used by web block modes and lighttpd bind address | ||
| `TZ: <Timezone>`<br/> | Set your [timezone](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones) to make sure logs rotate at local midnight instead of at UTC midnight. | ||
| `WEBPASSWORD: <Admin password>`<br/> | http://pi.hole/admin password. Run `docker logs pihole \| grep random` to find your random pass. | ||
| `REV_SERVER: <"true"|"false">`<br/> | Enable DNS conditional forwarding for device name resolution | ||
| `REV_SERVER_DOMAIN: <Network Domain>`<br/> | If conditional forwarding is enabled, set the domain of the local network router | ||
| `REV_SERVER_TARGET: <Router's IP>`<br/> | If conditional forwarding is enabled, set the IP of the local network router | ||
| `REV_SERVER_CIDR: <Reverse DNS>`<br/>| If conditional forwarding is enabled, set the reverse DNS zone (e.g. `192.168.0.0/24`) | ||
|
||
Example `.env` file in the same directory as your `docker-compose.yaml` file: | ||
|
||
``` | ||
ServerIP=192.168.1.10 | ||
TZ=America/Los_Angeles | ||
WEBPASSWORD=QWERTY123456asdfASDF | ||
REV_SERVER=true | ||
REV_SERVER_DOMAIN=local | ||
REV_SERVER_TARGET=192.168.1.1 | ||
REV_SERVER_CIDR=192.168.0.0/16 | ||
``` | ||
|
||
|
||
### Running the stack | ||
|
||
```bash | ||
docker-compose up -d | ||
``` | ||
|
||
> If using Portainer, just paste the `docker-compose.yaml` contents into the stack config and add your *environment variables* directly in the UI. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
version: '2' | ||
|
||
|
||
services: | ||
pihole: | ||
container_name: pihole | ||
image: cbcrowe/pihole-unbound:latest | ||
hostname: pihole | ||
domainname: pihole.local | ||
ports: | ||
- 8443:443/tcp | ||
- 53/tcp | ||
- 53/udp | ||
- 8080:80/tcp | ||
# - 22/tcp # Uncomment to enable SSH | ||
environment: | ||
ServerIP: ${ServerIP} | ||
TZ: ${TZ} | ||
WEBPASSWORD: ${WEBPASSWORD} | ||
REV_SERVER: ${REV_SERVER} | ||
REV_SERVER_TARGET: ${REV_SERVER_TARGET} | ||
REV_SERVER_DOMAIN: ${REV_SERVER_DOMAIN} | ||
REV_SERVER_CIDR: ${REV_SERVER_CIDR} | ||
DNS1: 127.0.0.1#5335 # Hardcoded to our Unbound server | ||
DNS2: 127.0.0.1#5335 # Hardcoded to our Unbound server | ||
DNSSEC: "true" # Enable DNSSEC | ||
network_mode: "host" | ||
volumes: | ||
- etc_pihole-unbound:/etc/pihole:rw | ||
- etc_pihole_dnsmasq-unbound:/etc/dnsmasq.d:rw | ||
restart: unless-stopped | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
FROM pihole/pihole:latest | ||
RUN apt update && apt install -y unbound | ||
|
||
COPY lighttpd-external.conf /etc/lighttpd/external.conf | ||
COPY unbound-pihole.conf /etc/unbound/unbound.conf.d/pi-hole.conf | ||
COPY install_unbound_and_s6_init.sh install_unbound_and_s6_init.sh | ||
|
||
RUN chmod +x install_unbound_and_s6_init.sh | ||
ENTRYPOINT ./install_unbound_and_s6_init.sh |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
v1.0.0 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
#!/bin/bash -e | ||
/etc/init.d/unbound start | ||
/s6-init |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
$HTTP["url"] =~ "^/admin/" { | ||
# Allow using Pi-Hole admin in iframes (eg, for Home Assistant) | ||
setenv.set-response-header += ( | ||
"X-Frame-Options" => "Allow" | ||
) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
# Config pulled from https://docs.pi-hole.net/guides/unbound/ | ||
|
||
server: | ||
# If no logfile is specified, syslog is used | ||
# logfile: "/var/log/unbound/unbound.log" | ||
verbosity: 0 | ||
|
||
interface: 127.0.0.1 | ||
port: 5335 | ||
do-ip4: yes | ||
do-udp: yes | ||
do-tcp: yes | ||
|
||
# May be set to yes if you have IPv6 connectivity | ||
do-ip6: no | ||
|
||
# You want to leave this to no unless you have *native* IPv6. With 6to4 and | ||
# Terredo tunnels your web browser should favor IPv4 for the same reasons | ||
prefer-ip6: no | ||
|
||
# Use this only when you downloaded the list of primary root servers! | ||
# If you use the default dns-root-data package, unbound will find it automatically | ||
#root-hints: "/var/lib/unbound/root.hints" | ||
|
||
# Trust glue only if it is within the server's authority | ||
harden-glue: yes | ||
|
||
# Require DNSSEC data for trust-anchored zones, if such data is absent, the zone becomes BOGUS | ||
harden-dnssec-stripped: yes | ||
|
||
# Don't use Capitalization randomization as it known to cause DNSSEC issues sometimes | ||
# see https://discourse.pi-hole.net/t/unbound-stubby-or-dnscrypt-proxy/9378 for further details | ||
use-caps-for-id: no | ||
|
||
# Reduce EDNS reassembly buffer size. | ||
# Suggested by the unbound man page to reduce fragmentation reassembly problems | ||
edns-buffer-size: 1472 | ||
|
||
# Perform prefetching of close to expired message cache entries | ||
# This only applies to domains that have been frequently queried | ||
prefetch: yes | ||
|
||
# One thread should be sufficient, can be increased on beefy machines. In reality for most users running on small networks or on a single machine, it should be unnecessary to seek performance enhancement by increasing num-threads above 1. | ||
num-threads: 1 | ||
|
||
# Ensure kernel buffer is large enough to not lose messages in traffic spikes | ||
so-rcvbuf: 1m | ||
|
||
# Ensure privacy of local IP ranges | ||
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 |
Oops, something went wrong.