commit e5b26c41c5e3ac5f7f5171fad519c6f7da09f875 Author: sujiba <65259334+sujiba@users.noreply.github.com> Date: Thu May 4 01:33:01 2023 +0200 first commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..4c49bd7 --- /dev/null +++ b/.gitignore @@ -0,0 +1 @@ +.env diff --git a/README.md b/README.md new file mode 100644 index 0000000..76ecd4b --- /dev/null +++ b/README.md @@ -0,0 +1,94 @@ +# Pihole + Unbound + Hyperlocal +### Overview +- [Introduction](https://github.com/sujiba/pihole-unbound-hyperlocal#introduction) +- [Prerequisites](https://github.com/sujiba/pihole-unbound-hyperlocal#prerequisites) +- [First startup](https://github.com/sujiba/pihole-unbound-hyperlocal#first-startup) + - [Testing](https://github.com/sujiba/pihole-unbound-hyperlocal#testing) + - [Additional configuration](https://github.com/sujiba/pihole-unbound-hyperlocal#additional-configuration) +- [Blocklists](https://github.com/sujiba/pihole-unbound-hyperlocal#blocklists) +- [Acknowledgement](https://github.com/sujiba/pihole-unbound-hyperlocal#acknowledgement) + +## Introduction +**Pi-hole**: +- Pi-hole is a DNS sinkhole that protects your devices from unwanted content, without installing any client-side software. + +**Unbound**: +- Unbound is a validating, recursive, caching DNS resolver. It is designed to be fast and lean and incorporates modern features based on open standards. + +**Hyperlocal**: +- To spare the initial DNS query to the DNS-Root-Servers by Unbound, we provide Unbound with an appropriate configuration. With each Pi-hole update, the DNS-Root-Zone (root.hints) is also updated. + +## Prerequisites +- Install [Docker](https://docs.docker.com/get-docker/) +- Install [Docker-Compose](https://docs.docker.com/compose/install/) +- Download the repository to your favored directory + +## First startup +Copy example.env to .env and change the parameters +``` +cp example.env .env +vi .env +``` +Start the container +``` +docker-compose up -d +``` + +### Testing +``` +docker exec -it pihole bash +dig github.com @127.0.0.1 +short +dig sigfail.verteiltesysteme.net @127.0.0.1 | grep status +dig sigok.verteiltesysteme.net @127.0.0.1 | grep status +``` +- First dig should show an IP address +- Second dig should show status: SERVFAIL +- Last dig should show status: NOERROR + +### Additional configuration +Edit the file pihole-FTL.conf +``` +vi ./etc-pihole/pihole-FTL.conf +``` +and add the following lines: +``` +# How many days should Pi-hole store requests - discard older entries +MAXDBDAYS=30 + +# Write FTL database from RAM to SD card every x minutes. - To spare the SD card's life +DBINTERVAL=60 +``` +Edit setupVars.conf +``` +vi ./etc-pihole/setupVars.conf +``` +and add +``` +# Caching is done by unbound +CACHE_SIZE=0 +``` + +#### Self-created docker network +If you are using a self-created docker network, uncomment the following line in the docker-compose.yaml +``` +#- ./resolv.conf:/etc/resolv.conf +``` + +### Restart the container +``` +docker-compose up -d --force-recreate +``` + +## Blocklists +- [Firebog Non-crossed lists](https://v.firebog.net/hosts/lists.php?type=nocross) +- [x0uid SpotifyAdBlock](https://raw.githubusercontent.com/x0uid/SpotifyAdBlock/master/SpotifyBlocklist.txt) +- [Perflyst SmartTV](https://raw.githubusercontent.com/Perflyst/PiHoleBlocklist/master/SmartTV.txt) +- [mmotti Pi-hole RegEx](https://raw.githubusercontent.com/mmotti/pihole-regex/master/regex.list) +- [Privacy-Handbuch Windows 10 Telemetry](https://www.privacy-handbuch.de/handbuch_90a2.htm) + +## Acknowledgement +- [Docker Pi-hole](https://github.com/pi-hole/docker-pi-hole) +- [Unbound](https://nlnetlabs.nl/projects/unbound/about/) +- [Pi-hole Unbound](https://docs.pi-hole.net/guides/dns/unbound/) +- [Pi-Hole + Unbound - 1 Container](https://github.com/chriscrowe/docker-pihole-unbound/tree/master/one-container) +- [[Pi-hole][Unbound] Mit dem Pi zur größtmöglichen Unabhängigkeit – DNS](https://forum.kuketz-blog.de/viewtopic.php?f=53&t=8759) diff --git a/docker-build/Dockerfile b/docker-build/Dockerfile new file mode 100644 index 0000000..a18f3ac --- /dev/null +++ b/docker-build/Dockerfile @@ -0,0 +1,27 @@ +# Get the latet Pi-hole version +FROM pihole/pihole:2021.09 + +# Install necessary programs +RUN apt-get update && \ + apt-get upgrade -y && \ + apt-get install -y \ + unbound \ + wget + +# Additional configs +# unbound +COPY unbound-v1.9_pihole.conf /etc/unbound/unbound.conf.d/pihole.conf + +# Download the DNS-Root-Zone. Change owner and move it to the right directory +RUN wget -O root.hints https://www.internic.net/domain/named.root && \ + chown unbound:unbound root.hints && \ + mv root.hints /var/lib/unbound/ + +# Unbound startup script +COPY start_unbound_and_s6_init.sh start_unbound_and_s6_init.sh +RUN chmod +x start_unbound_and_s6_init.sh +ENTRYPOINT ./start_unbound_and_s6_init.sh + +# Remove unnecessary programs +RUN apt-get remove -y \ + wget diff --git a/docker-build/README.md b/docker-build/README.md new file mode 100644 index 0000000..df61ef0 --- /dev/null +++ b/docker-build/README.md @@ -0,0 +1,20 @@ +# Build it yourself + +https://docs.docker.com/buildx/working-with-buildx/#work-with-builder-instances + + ``` + # This creates a new builder instance with a single node based on your current configuration. + docker buildx create + # To list all available builders, use + docker buildx ls + # To switch between different builders, use + docker buildx use + # After creating a new instance, you can delete it with + docker buildx rm +``` + +Build it as a multi-platform image: +``` +chmod +x build_and_push.sh +./build_and_push.sh +``` \ No newline at end of file diff --git a/docker-build/VERSION b/docker-build/VERSION new file mode 100644 index 0000000..76c052b --- /dev/null +++ b/docker-build/VERSION @@ -0,0 +1 @@ +2021.09 diff --git a/docker-build/build_and_push.sh b/docker-build/build_and_push.sh new file mode 100755 index 0000000..a81b959 --- /dev/null +++ b/docker-build/build_and_push.sh @@ -0,0 +1,2 @@ +docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 -t sujiba/pihole-unbound-hyperlocal:`cat VERSION` --push . +docker buildx build --platform linux/arm/v7,linux/arm64/v8,linux/amd64 -t sujiba/pihole-unbound-hyperlocal:latest --push . \ No newline at end of file diff --git a/docker-build/start_unbound_and_s6_init.sh b/docker-build/start_unbound_and_s6_init.sh new file mode 100644 index 0000000..c7dd36a --- /dev/null +++ b/docker-build/start_unbound_and_s6_init.sh @@ -0,0 +1,3 @@ +#!/bin/bash -e +/etc/init.d/unbound start +/s6-init \ No newline at end of file diff --git a/docker-build/unbound-v1.13_pihole.conf b/docker-build/unbound-v1.13_pihole.conf new file mode 100644 index 0000000..05e016c --- /dev/null +++ b/docker-build/unbound-v1.13_pihole.conf @@ -0,0 +1,228 @@ +server: + ########################################################################### + # BASIC SETTINGS + ########################################################################### + + # Listen to for queries from clients and answer from this network interface + # and port. + interface: 127.0.0.1 + port: 5335 + do-ip4: yes + do-udp: yes + do-tcp: yes + + # Maybe set to yes if you have IPv6 connectivity + do-ip6: no + # and for *native* IPv6 + prefer-ip6: no + + # where to find root server data + root-hints: /usr/share/dns/root.hints + + # Reduce EDNS reassembly buffer size. + # Suggested by the unbound man page to reduce fragmentation reassembly problems + edns-buffer-size: 1472 + + # Rotates RRSet order in response (the pseudo-random number is taken from + # the query ID, for speed and thread safety). + rrset-roundrobin: yes + + # Drop user privileges after binding the port. + username: "_unbound" + + ########################################################################### + # LOGGING + ########################################################################### + + # If no logfile is specified, syslog is used + #logfile: "/var/log/unbound/unbound.log" + log-time-ascii: yes + + # The verbosity number, + # level 0 means no verbosity, only errors. + # level 1 gives operational information. + verbosity: 1 + + # Do not print log lines to inform about local zone actions + log-local-actions: no + + # Do not print one line per query to the log + log-queries: no + + # Do not print one line per reply to the log + log-replies: no + + # Do not print log lines that say why queries return SERVFAIL to clients + log-servfail: no + + # Further limit logging + logfile: /dev/null + + ########################################################################### + # PRIVACY SETTINGS + ########################################################################### + + # RFC 8198. Use the DNSSEC NSEC chain to synthesize NXDO-MAIN and other + # denials, using information from previous NXDO-MAINs answers. In other + # words, use cached NSEC records to generate negative answers within a + # range and positive answers from wildcards. This increases performance, + # decreases latency and resource utilization on both authoritative and + # recursive servers, and increases privacy. Also, it may help increase + # resilience to certain DoS attacks in some circumstances. + aggressive-nsec: yes + + # Extra delay for timeouted UDP ports before they are closed, in msec. + # This prevents very delayed answer packets from the upstream (recursive) + # servers from bouncing against closed ports and setting off all sort of + # close-port counters, with eg. 1500 msec. When timeouts happen you need + # extra sockets, it checks the ID and remote IP of packets, and unwanted + # packets are added to the unwanted packet counter. + delay-close: 10000 + + # Prevent the unbound server from forking into the background as a daemon + do-daemonize: no + + # Add localhost to the do-not-query-address list. + do-not-query-localhost: no + + # Number of bytes size of the aggressive negative cache. + neg-cache-size: 4M + + # Send minimum amount of information to upstream servers to enhance + # privacy (best privacy). + qname-minimisation: yes + + ########################################################################### + # SECURITY SETTINGS + ########################################################################### + + # Only give access to recursion clients from LAN IPs + access-control: 127.0.0.1/32 allow + access-control: 192.168.0.0/16 allow + access-control: 172.16.0.0/12 allow + access-control: 10.0.0.0/8 allow + + # Enable chroot (i.e, change apparent root directory for the current + # running process and its children) + chroot: "/etc/unbound" + + # Deny queries of type ANY with an empty response. + deny-any: yes + + # Harden against algorithm downgrade when multiple algorithms are + # advertised in the DS record. + harden-algo-downgrade: yes + + # RFC 8020. returns nxdomain to queries for a name below another name that + # is already known to be nxdomain. + harden-below-nxdomain: yes + + # Require DNSSEC data for trust-anchored zones, if such data is absent, the + # zone becomes bogus. If turned off you run the risk of a downgrade attack + # that disables security for a zone. + harden-dnssec-stripped: yes + + # Trust glue only if it is within the server's authority + harden-glue: yes + + # Ignore very large queries. + harden-large-queries: yes + + # Perform additional queries for infrastructure data to harden the referral + # path. Validates the replies if trust anchors are configured and the zones + # are signed. This enforces DNSSEC validation on nameserver NS sets and the + # nameserver addresses that are encountered on the referral path to the + # answer. Experimental option. + harden-referral-path: no + + # Ignore very small EDNS buffer sizes from queries. + harden-short-bufsize: yes + + # Refuse id.server and hostname.bind queries + hide-identity: yes + + # Refuse version.server and version.bind queries + hide-version: yes + + # Set the HTTP User-Agent header for outgoing HTTP requests. If + # set to "", the default, then the package name and version are + # used. + http-user-agent: "DNS" + + # Report this identity rather than the hostname of the server. + identity: "DNS" + + # These private network addresses are not allowed to be returned for public + # internet names. Any occurrence of such addresses are removed from DNS + # answers. Additionally, the DNSSEC validator may mark the answers bogus. + # This protects against DNS Rebinding + private-address: 10.0.0.0/8 + private-address: 172.16.0.0/12 + private-address: 169.254.0.0/16 + private-address: 192.168.0.0/16 + private-address: fd00::/8 + private-address: fe80::/10 + + # Enable ratelimiting of queries (per second) sent to nameserver for + # performing recursion. More queries are turned away with an error + # (servfail). This stops recursive floods (e.g., random query names), but + # not spoofed reflection floods. Cached responses are not rate limited by + # this setting. Experimental option. + ratelimit: 1000 + + # Set the total number of unwanted replies to eep track of in every thread. + # When it reaches the threshold, a defensive action of clearing the rrset + # and message caches is taken, hopefully flushing away any poison. + # Unbound suggests a value of 10 million. + unwanted-reply-threshold: 10000 + + # 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 + # !! Änderung gegenüber Pi-hole. Wenn es Fehler gibt, hier no statt yes probieren. !! + use-caps-for-id: yes + + # Help protect users that rely on this validator for authentication from + # potentially bad data in the additional section. Instruct the validator to + # remove data from the additional section of secure messages that are not + # signed properly. Messages that are insecure, bogus, indeterminate or + # unchecked are not affected. + val-clean-additional: yes + + ########################################################################### + # PERFORMANCE SETTINGS + ########################################################################### + # https://nlnetlabs.nl/documentation/unbound/howto-optimise/ + # https://nlnetlabs.nl/news/2019/Feb/05/unbound-1.9.0-released/ + + # Perform prefetching of close to expired message cache entries + # This only applies to domains that have been frequently queried + prefetch: yes + + # fetch DS records earlier (DNSSEC): more cpu usage, less latency + prefetch-key: yes + + # One thread should be sufficient, can be increased on beefy machines + num-threads: 1 + + # increase cache size to utilize more RAM, rrset=msg*2 + msg-cache-size: 64m + rrset-cache-size: 128m + + +remote-control: + control-enable: no + +# get data for all TLDs by IXFR (or AXFR) from root servers +# b,c,g are the only servers that answer a IXFR query +auth-zone: + name: "." + primary: 199.9.14.201 # b.root-servers.net + primary: 192.33.4.12 # c.root-servers.net + primary: 192.112.36.4 # g.root-servers.net + primary: 2001:500:200::b # b.root-servers.net + primary: 2001:500:2::c # c.root-servers.net + primary: 2001:500:12::d0d # g.root-servers.net + fallback-enabled: yes + for-downstream: no + for-upstream: yes + zonefile: /var/lib/unbound/root.zone diff --git a/docker-build/unbound-v1.9_pihole.conf b/docker-build/unbound-v1.9_pihole.conf new file mode 100644 index 0000000..a788c33 --- /dev/null +++ b/docker-build/unbound-v1.9_pihole.conf @@ -0,0 +1,57 @@ +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 + + # increase cache size to utilize more RAM + msg-cache-size: 128m + rrset-cache-size: 256m + + # 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 diff --git a/docker-compose.yaml b/docker-compose.yaml new file mode 100644 index 0000000..1db9d2e --- /dev/null +++ b/docker-compose.yaml @@ -0,0 +1,35 @@ +version: "3" + +services: +# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/ + pihole-unbound: + image: sujiba/pihole-unbound-hyperlocal:latest + container_name: pihole-unbound + hostname: ${HOSTNAME} + ports: + - "53:53/tcp" + - "53:53/udp" + - "67:67/udp" + - "${HTTP_PORT}:80/tcp" + # - 5335:5335/tcp # For testing purposes, uncomment to enable unbound access on local server + environment: + TZ: ${TZ} + WEBPASSWORD: ${WEBPASSWORD} + PIHOLE_DNS_: ${PIHOLE_DNS} + DNSSEC: ${DNSSEC} + CUSTOM_CACHE_SIZE: ${CUSTOM_CACHE_SIZE} + DNS_BOGUS_PRIV: ${DNS_BOGUS_PRIV} + DNS_FQDN_REQUIRED: ${DNS_FQDN_REQUIRED} + TEMPERATUREUNIT: ${TEMPERATUREUNIT} + WEBTHEME: ${WEBTHEME} + # Volumes store your data between container upgrades + volumes: + - ./etc-pihole/:/etc/pihole/ + - ./etc-dnsmasq.d/:/etc/dnsmasq.d/ + # You'll need this, if you are using a self-created network + #- ./resolv.conf:/etc/resolv.conf + # 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 \ No newline at end of file diff --git a/etc-dnsmasq.d/10-pihole-extra.conf b/etc-dnsmasq.d/10-pihole-extra.conf new file mode 100644 index 0000000..cd626a7 --- /dev/null +++ b/etc-dnsmasq.d/10-pihole-extra.conf @@ -0,0 +1,6 @@ +# https://thekelleys.org.uk/dnsmasq/docs/dnsmasq-man.html +# Copy the DNSSEC Authenticated Data bit from upstream servers to downstream clients. +# This is an alternative to having dnsmasq validate DNSSEC, +# but it depends on the security of the network between dnsmasq and the upstream servers, +# and the trustworthiness of the upstream servers. +proxy-dnssec diff --git a/example.env b/example.env new file mode 100644 index 0000000..6e356ff --- /dev/null +++ b/example.env @@ -0,0 +1,39 @@ +# More info at https://github.com/pi-hole/docker-pi-hole/ and https://docs.pi-hole.net/ + +HOSTNAME=pihole + +# 80 or an alternative port if you use a reverse proxy like nginx +HTTP_PORT=80 + +# Set your timezone to make sure logs rotate at local midnight instead of at UTC midnight. +TZ='Europe/Berlin' + +# http://pi.hole/admin password. Run docker logs pihole | grep random to find your random pass. +WEBPASSWORD=PASSWORD + +# Upstream DNS server(s) for Pi-hole to forward queries to, seperated by a semicolon +# (supports non-standard ports with #[port number]) e.g 127.0.0.1#5053;8.8.8.8;8.8.4.4 +# Hardcoded to our Unbound server +PIHOLE_DNS=127.0.0.1#5335 + +# We disable DNSSEC because it is done by Unbound +DNSSEC="false" + +# Set the cache size for dnsmasq. +# Useful for increasing the default cache size or to set it to 0. +# Note that when DNSSEC is "true", then this setting is ignored. +CUSTOM_CACHE_SIZE=0 + +# Never forward reverse lookups for private ranges +DNS_BOGUS_PRIV=true + +# Never forward non-FQDNs +DNS_FQDN_REQUIRED=true + +# Set preferred temperature unit to +# c: Celsius, k: Kelvin, or f Fahrenheit units. +TEMPERATUREUNIT=c + +# User interface theme to use. +# "default-dark"|"default-darker"|"default-light" +WEBTHEME="default-dark" \ No newline at end of file diff --git a/resolv.conf b/resolv.conf new file mode 100644 index 0000000..0b8ccee --- /dev/null +++ b/resolv.conf @@ -0,0 +1,2 @@ +nameserver 127.0.0.1 +options ndots:0 \ No newline at end of file