feat(dns): use Unbound and AdGuardHome for DNS

Unbound as a recursive resolver and AdGuardHome as main DNS backed by
Unbound
This commit is contained in:
Vegard Hagen
2024-08-18 12:44:30 +02:00
parent 38f118fa17
commit 9dec025db7
13 changed files with 506 additions and 3 deletions

View File

@@ -5,4 +5,4 @@ metadata:
spec:
blocks:
- start: 192.168.1.220
stop: 192.168.1.229
stop: 192.168.1.255

View File

@@ -0,0 +1,176 @@
http:
pprof:
port: 6060
enabled: false
address: 0.0.0.0:3000
session_ttl: 720h
users:
- name: veh
password: $2a$10$/84M9f9064xOSmb3MGXBmuApKPhvXnRxMGjISmvAmkp85ViiMd5l.
auth_attempts: 5
block_auth_min: 15
http_proxy: ""
language: ""
theme: auto
dns:
bind_hosts:
- 0.0.0.0
port: 53
anonymize_client_ip: false
ratelimit: 20
ratelimit_subnet_len_ipv4: 24
ratelimit_subnet_len_ipv6: 56
ratelimit_whitelist: []
refuse_any: true
upstream_dns:
- https://dns10.quad9.net/dns-query
upstream_dns_file: ""
bootstrap_dns:
- 9.9.9.10
- 149.112.112.10
- 2620:fe::10
- 2620:fe::fe:10
fallback_dns: []
upstream_mode: load_balance
fastest_timeout: 1s
allowed_clients: []
disallowed_clients: []
blocked_hosts:
- version.bind
- id.server
- hostname.bind
trusted_proxies:
- 127.0.0.0/8
- ::1/128
cache_size: 4194304
cache_ttl_min: 0
cache_ttl_max: 0
cache_optimistic: false
bogus_nxdomain: []
aaaa_disabled: false
enable_dnssec: false
edns_client_subnet:
custom_ip: ""
enabled: false
use_custom: false
max_goroutines: 300
handle_ddr: true
ipset: []
ipset_file: ""
bootstrap_prefer_ipv6: false
upstream_timeout: 10s
private_networks: []
use_private_ptr_resolvers: true
local_ptr_upstreams: []
use_dns64: false
dns64_prefixes: []
serve_http3: false
use_http3_upstreams: false
serve_plain_dns: true
hostsfile_enabled: true
tls:
enabled: false
server_name: ""
force_https: false
port_https: 443
port_dns_over_tls: 853
port_dns_over_quic: 853
port_dnscrypt: 0
dnscrypt_config_file: ""
allow_unencrypted_doh: false
certificate_chain: ""
private_key: ""
certificate_path: ""
private_key_path: ""
strict_sni_check: false
querylog:
dir_path: ""
ignored: []
interval: 2160h
size_memory: 1000
enabled: true
file_enabled: true
statistics:
dir_path: ""
ignored: []
interval: 24h
enabled: true
filters:
- enabled: true
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_1.txt
name: AdGuard DNS filter
id: 1
- enabled: false
url: https://adguardteam.github.io/HostlistsRegistry/assets/filter_2.txt
name: AdAway Default Blocklist
id: 2
whitelist_filters: []
user_rules: []
dhcp:
enabled: false
interface_name: ""
local_domain_name: lan
dhcpv4:
gateway_ip: ""
subnet_mask: ""
range_start: ""
range_end: ""
lease_duration: 86400
icmp_timeout_msec: 1000
options: []
dhcpv6:
range_start: ""
lease_duration: 86400
ra_slaac_only: false
ra_allow_slaac: false
filtering:
blocking_ipv4: ""
blocking_ipv6: ""
blocked_services:
schedule:
time_zone: UTC
ids: []
protection_disabled_until: null
safe_search:
enabled: false
bing: true
duckduckgo: true
google: true
pixabay: true
yandex: true
youtube: true
blocking_mode: default
parental_block_host: family-block.dns.adguard.com
safebrowsing_block_host: standard-block.dns.adguard.com
rewrites: []
safebrowsing_cache_size: 1048576
safesearch_cache_size: 1048576
parental_cache_size: 1048576
cache_time: 30
filters_update_interval: 24
blocked_response_ttl: 10
filtering_enabled: true
parental_enabled: false
safebrowsing_enabled: false
protection_enabled: true
clients:
runtime_sources:
whois: true
arp: true
rdns: true
dhcp: true
hosts: true
persistent: []
log:
file: ""
max_backups: 0
max_size: 100
max_age: 3
compress: false
local_time: false
verbose: false
os:
group: ""
user: ""
rlimit_nofile: 0
schema_version: 28

View File

@@ -0,0 +1,58 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: adguard
namespace: dns
spec:
replicas: 1
selector:
matchLabels:
app: adguard
strategy:
type: RollingUpdate
template:
metadata:
labels:
app: adguard
spec:
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: adguard
image: docker.io/adguard/adguardhome:v0.107.48 # renovate: docker=docker.io/adguard/adguardhome
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: true
# capabilities:
# drop: [ "ALL" ]
ports:
- name: dns-tcp
containerPort: 53
protocol: TCP
- name: dns-udp
containerPort: 53
protocol: UDP
- name: dchp
containerPort: 67
protocol: UDP
- name: http
containerPort: 3000
protocol: TCP
resources:
requests:
cpu: 50m
memory: 128Mi
limits:
cpu: 500m
memory: 256Mi
volumeMounts:
- name: adguard-conf
mountPath: /opt/adguardhome/conf
- name: adguard-work
mountPath: /opt/adguardhome/work
volumes:
- name: adguard-conf
emptyDir: {}
- name: adguard-work
emptyDir: {}

View File

@@ -0,0 +1,19 @@
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: adguard
namespace: dns
spec:
parentRefs:
- name: stonegarden
namespace: gateway
hostnames:
- "adguard.stonegarden.dev"
rules:
- matches:
- path:
type: PathPrefix
value: /
backendRefs:
- name: adguard
port: 3000

View File

@@ -0,0 +1,13 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: adguard-config
namespace: dns
files:
- config/AdGuardHome.yaml
resources:
- svc.yaml
- deployment.yaml
- http-route.yaml

View File

@@ -0,0 +1,24 @@
apiVersion: v1
kind: Service
metadata:
name: adguard
namespace: dns
annotations:
io.cilium/lb-ipam-ips: 192.168.1.253
spec:
type: LoadBalancer
ports:
- name: http
protocol: TCP
port: 3000
- name: dns-tcp
port: 53
protocol: TCP
- name: dns-udp
port: 53
protocol: UDP
- name: dchp
port: 67
protocol: UDP
selector:
app: adguard

View File

@@ -0,0 +1,7 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
resources:
- ns.yaml
- adguard
- unbound

View File

@@ -0,0 +1,4 @@
apiVersion: v1
kind: Namespace
metadata:
name: dns

View File

@@ -0,0 +1,115 @@
server:
# See https://github.com/MatthewVance/unbound-docker/blob/master/unbound.conf for details
interface: 0.0.0.0
port: 53
cache-max-ttl: 86400
cache-min-ttl: 300
directory: "/opt/unbound/etc/unbound"
do-ip4: yes
do-ip6: yes
prefer-ip6: yes
do-tcp: yes
do-udp: yes
edns-buffer-size: 1232
rrset-roundrobin: yes
username: "_unbound"
log-local-actions: no
log-queries: no
log-replies: no
log-servfail: yes
#logfile: /opt/unbound/etc/unbound/unbound.log
verbosity: 2
infra-cache-slabs: 4
incoming-num-tcp: 10
key-cache-slabs: 4
msg-cache-size: 142768128
msg-cache-slabs: 4
num-queries-per-thread: 4096
num-threads: 3
outgoing-range: 8192
rrset-cache-size: 285536256
rrset-cache-slabs: 4
minimal-responses: yes
prefetch: yes
prefetch-key: yes
serve-expired: yes
so-reuseport: yes
aggressive-nsec: yes
delay-close: 10000
do-daemonize: no
do-not-query-localhost: no
neg-cache-size: 4M
qname-minimisation: yes
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
access-control: fc00::/7 allow
access-control: ::1/128 allow
auto-trust-anchor-file: "var/root.key"
chroot: "/opt/unbound/etc/unbound"
deny-any: yes
harden-algo-downgrade: yes
harden-below-nxdomain: yes
harden-dnssec-stripped: yes
harden-glue: yes
harden-large-queries: yes
harden-referral-path: no
harden-short-bufsize: yes
hide-http-user-agent: no
hide-identity: yes
hide-version: yes
http-user-agent: "DNS"
identity: "DNS"
private-address: 10.0.0.0/8
private-address: 172.16.0.0/12
private-address: 192.168.0.0/16
private-address: 169.254.0.0/16
private-address: fd00::/8
private-address: fe80::/10
private-address: ::ffff:0:0/96
ratelimit: 1000
tls-cert-bundle: /etc/ssl/certs/ca-certificates.crt
unwanted-reply-threshold: 10000
use-caps-for-id: no
val-clean-additional: yes
include: /opt/unbound/etc/unbound/a-records.conf
include: /opt/unbound/etc/unbound/srv-records.conf
remote-control:
control-enable: no

View File

@@ -0,0 +1,58 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: unbound
namespace: dns
spec:
replicas: 2
selector:
matchLabels:
app: unbound
strategy:
type: Recreate
template:
metadata:
labels:
app: unbound
spec:
nodeSelector:
topology.kubernetes.io/zone: euclid
securityContext:
seccompProfile:
type: RuntimeDefault
containers:
- name: unbound
image: docker.io/mvance/unbound:1.20.0 # renovate: docker=docker.io/mvance/unbound
securityContext:
allowPrivilegeEscalation: false
readOnlyRootFilesystem: false
# capabilities:
# drop: [ "ALL" ]
ports:
- name: unbound-dns-tcp
containerPort: 5335
protocol: TCP
- name: unbound-dns-udp
containerPort: 5335
protocol: UDP
resources:
requests:
cpu: 50m
memory: 64Mi
limits:
cpu: 500m
memory: 128Mi
startupProbe:
exec:
command: ['drill', '@127.0.0.1', '-p', '53', 'nrk.no']
initialDelaySeconds: 10
failureThreshold: 3
timeoutSeconds: 5
volumeMounts:
- name: config
mountPath: /opt/unbound/etc/unbound/unbound.conf
subPath: unbound.conf
volumes:
- name: config
configMap:
name: unbound-config

View File

@@ -0,0 +1,12 @@
apiVersion: kustomize.config.k8s.io/v1beta1
kind: Kustomization
configMapGenerator:
- name: unbound-config
namespace: dns
files:
- config/unbound.conf
resources:
- svc.yaml
- deployment.yaml

View File

@@ -0,0 +1,17 @@
apiVersion: v1
kind: Service
metadata:
name: unbound
namespace: dns
spec:
type: ClusterIP
clusterIP: 10.96.0.11
ports:
- name: dns
port: 53
protocol: TCP
- name: dns-udp
port: 53
protocol: UDP
selector:
app: unbound

View File

@@ -9,14 +9,14 @@ spec:
- 'https://prometheus-community.github.io/helm-charts'
- 'https://argoproj.github.io/argo-helm'
destinations:
- namespace: 'adguard'
server: '*'
- namespace: 'argocd'
server: '*'
- namespace: 'cilium-secrets'
server: '*'
- namespace: 'cloudflared'
server: '*'
- namespace: 'dns'
server: '*'
- namespace: 'gateway'
server: '*'
- namespace: 'kube-system'