From 61556a52154c35cf8e04cf5cd5eb518b1abb32ec Mon Sep 17 00:00:00 2001 From: Marco Kilchhofer Date: Tue, 4 Aug 2020 05:59:25 +0200 Subject: [PATCH] [adguard-home] Introduce config as code and add ability to run as non-root (#297) * [adguard-home] Introduce Config as code * [adguard-home] Rewrite Config as code with initContainers Configmaps are read only and the app fails to start when config is read-only: ~~~ [info] AdGuard Home, version v0.102.0, channel release, arch linux amd64 [error] Couldn't save YAML config: open /opt/adguardhome/conf/..2020_07_26_11_38_31.428232526/tmp266296205: read-only file system [fatal] open /opt/adguardhome/conf/..2020_07_26_11_38_31.428232526/tmp266296205: read-only file system ~~~ * [adguard-home] Add ability to run as non-root * [adguard-home] Bump chart version to 1.2.0 * [adguard-home] Use charts appVersion by default to specify the image tag --- charts/adguard-home/Chart.yaml | 4 +- charts/adguard-home/templates/configmap.yaml | 14 ++ charts/adguard-home/templates/deployment.yaml | 60 +++++- charts/adguard-home/values.yaml | 189 +++++++++++++++++- 4 files changed, 263 insertions(+), 4 deletions(-) create mode 100644 charts/adguard-home/templates/configmap.yaml diff --git a/charts/adguard-home/Chart.yaml b/charts/adguard-home/Chart.yaml index 2b82665d..4f8b899c 100644 --- a/charts/adguard-home/Chart.yaml +++ b/charts/adguard-home/Chart.yaml @@ -1,8 +1,8 @@ apiVersion: v1 -appVersion: "v0.8" +appVersion: v0.102.0 description: DNS proxy as ad-blocker for local network name: adguard-home -version: 1.1.0 +version: 1.2.0 keywords: - adguard-home - adguard diff --git a/charts/adguard-home/templates/configmap.yaml b/charts/adguard-home/templates/configmap.yaml new file mode 100644 index 00000000..87b97f74 --- /dev/null +++ b/charts/adguard-home/templates/configmap.yaml @@ -0,0 +1,14 @@ +{{- if .Values.configAsCode.enabled }} +kind: ConfigMap +apiVersion: v1 +metadata: + name: {{ include "adguard-home.fullname" . }} + labels: + app.kubernetes.io/name: {{ include "adguard-home.name" . }} + helm.sh/chart: {{ include "adguard-home.chart" . }} + app.kubernetes.io/instance: {{ .Release.Name }} + app.kubernetes.io/managed-by: {{ .Release.Service }} +data: + AdGuardHome.yaml: | + {{- toYaml .Values.configAsCode.config | nindent 4 }} +{{- end }} diff --git a/charts/adguard-home/templates/deployment.yaml b/charts/adguard-home/templates/deployment.yaml index bf53c593..19bd6eee 100644 --- a/charts/adguard-home/templates/deployment.yaml +++ b/charts/adguard-home/templates/deployment.yaml @@ -25,10 +25,51 @@ spec: {{- with .Values.podAnnotations }} {{ toYaml . | nindent 8 }} {{- end }} + {{- if .Values.configAsCode.enabled }} + checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }} + {{- end }} spec: + securityContext: + {{- toYaml .Values.podSecurityContext | nindent 8 }} + {{- if or .Values.configAsCode.enabled .Values.securityContext.runAsUser }} + initContainers: + {{- if .Values.configAsCode.enabled }} + - name: "config" + securityContext: + readOnlyRootFilesystem: true + image: "{{ .Values.configAsCode.image.repository }}:{{ .Values.configAsCode.image.tag }}" + imagePullPolicy: {{ .Values.configAsCode.image.pullPolicy }} + command: ["sh", "-c", "cat /configmap/AdGuardHome.yaml > /opt/adguardhome/conf/AdGuardHome.yaml"] + resources: {{- toYaml .Values.configAsCode.resources | nindent 12 }} + volumeMounts: + - name: configmap + mountPath: /configmap + - name: config + mountPath: /opt/adguardhome/conf + readOnly: false + {{- end }} + {{- if .Values.securityContext.runAsUser }} + - name: "volume-permissions" + securityContext: + readOnlyRootFilesystem: true + image: "{{ .Values.volumePermissions.image.repository }}:{{ .Values.volumePermissions.image.tag }}" + imagePullPolicy: {{ .Values.volumePermissions.image.pullPolicy }} + command: ["/bin/chown", "-R", "{{ .Values.securityContext.runAsUser }}:", "/opt/adguardhome/work", "/opt/adguardhome/conf"] + resources: {{- toYaml .Values.volumePermissions.resources | nindent 12 }} + volumeMounts: + - name: work + mountPath: /opt/adguardhome/work + readOnly: false + - name: config + mountPath: /opt/adguardhome/conf + readOnly: false + {{- end }} + {{- end }} containers: - name: {{ .Chart.Name }} - image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}" + securityContext: + {{- toYaml .Values.securityContext | nindent 12 }} + image: "{{ .Values.image.repository }}:{{ default .Chart.AppVersion .Values.image.tag }}" imagePullPolicy: {{ .Values.image.pullPolicy }} env: {{- if .Values.timezone }} @@ -44,12 +85,24 @@ spec: readOnly: false ports: - name: http + {{- if .Values.configAsCode.enabled }} + containerPort: {{ .Values.configAsCode.config.bind_port | default 3000 }} + {{- else }} containerPort: 3000 + {{- end }} - name: dns + {{- if .Values.configAsCode.enabled }} + containerPort: {{ .Values.configAsCode.config.dns.port | default 53 }} + {{- else }} containerPort: 53 + {{- end }} protocol: TCP - name: dns-udp + {{- if .Values.configAsCode.enabled }} + containerPort: {{ .Values.configAsCode.config.dns.port | default 53 }} + {{- else }} containerPort: 53 + {{- end }} protocol: UDP {{- if .Values.serviceDHCP.enabled }} - name: dhcp-server-udp @@ -100,6 +153,11 @@ spec: resources: {{- toYaml .Values.resources | nindent 12 }} volumes: + {{- if .Values.configAsCode.enabled }} + - name: configmap + configMap: + name: {{ include "adguard-home.fullname" . }} + {{- end }} - name: config {{- if .Values.persistence.config.enabled }} persistentVolumeClaim: diff --git a/charts/adguard-home/values.yaml b/charts/adguard-home/values.yaml index 03bdd4b6..65c6bc06 100644 --- a/charts/adguard-home/values.yaml +++ b/charts/adguard-home/values.yaml @@ -1,14 +1,192 @@ # upgrade strategy type (e.g. Recreate or RollingUpdate) strategyType: Recreate +configAsCode: + enabled: false + resources: {} + # requests: + # memory: 128Mi + # cpu: 100m + image: + repository: busybox + tag: latest + pullPolicy: Always + config: + bind_host: 0.0.0.0 + bind_port: 3000 + users: [] + # - name: admin + # password: $2y$05$mV4GSa5Dymk4Hjg3NCscBuCYSckCGfc2mbS57SNkBkBAfvqfOdFfm + http_proxy: "" + language: "en" + rlimit_nofile: 0 + debug_pprof: false + web_session_ttl: 720 + dns: + bind_host: 0.0.0.0 + port: 53 + statistics_interval: 1 + querylog_enabled: true + querylog_interval: 90 + querylog_size_memory: 1000 + anonymize_client_ip: false + protection_enabled: true + blocking_mode: default + blocking_ipv4: "" + blocking_ipv6: "" + blocked_response_ttl: 10 + parental_block_host: family-block.dns.adguard.com + safebrowsing_block_host: standard-block.dns.adguard.com + ratelimit: 0 + ratelimit_whitelist: [] + refuse_any: true + upstream_dns: + - https://dns10.quad9.net/dns-query + bootstrap_dns: + - 9.9.9.10 + - 149.112.112.10 + - 2620:fe::10 + - 2620:fe::fe:10 + all_servers: false + fastest_addr: false + allowed_clients: [] + # - 10.0.0.1 + # - 10.0.1.1/24 + disallowed_clients: [] + # - 10.0.1.1 + # - 10.0.11.1/24 + blocked_hosts: [] + # - example.org + # - '*.example.org' + # - '||example.org^' + cache_size: 4194304 + cache_ttl_min: 0 + cache_ttl_max: 0 + bogus_nxdomain: [] + aaaa_disabled: false + enable_dnssec: false + edns_client_subnet: false + filtering_enabled: true + filters_update_interval: 24 + parental_enabled: false + safesearch_enabled: false + safebrowsing_enabled: false + safebrowsing_cache_size: 1048576 + safesearch_cache_size: 1048576 + parental_cache_size: 1048576 + cache_time: 30 + rewrites: [] + # - domain: example.org + # answer: 127.0.0.1 + # - domain: '*.example.org' + # answer: 127.0.0.1 + blocked_services: [] + # - facebook + # - origin + # - twitter + # - snapchat + # - skype + # - whatsapp + # - instagram + # - youtube + # - netflix + # - twitch + # - discord + # - amazon + # - ebay + # - cloudflare + # - steam + # - epic_games + # - reddit + # - ok + # - vk + # - mail_ru + # - tiktok + tls: + enabled: false + server_name: "" + force_https: false + port_https: 443 + port_dns_over_tls: 853 + allow_unencrypted_doh: false + strict_sni_check: false + certificate_chain: "" + private_key: "" + certificate_path: "" + private_key_path: "" + filters: + - enabled: true + url: https://adguardteam.github.io/AdGuardSDNSFilter/Filters/filter.txt + name: AdGuard DNS filter + id: 1 + - enabled: false + url: https://adaway.org/hosts.txt + name: AdAway + id: 2 + - enabled: false + url: https://www.malwaredomainlist.com/hostslist/hosts.txt + name: MalwareDomainList.com Hosts List + id: 4 + whitelist_filters: [] + # - enabled: true + # url: https://easylist-downloads.adblockplus.org/exceptionrules.txt + # name: Allow nonintrusive advertising + # id: 1595760241 + user_rules: [] + # - '||example.org^' + # - '@@||example.org^' + # - 127.0.0.1 example.org + # - '! Here goes a comment' + # - '# Also a comment' + dhcp: + enabled: false + interface_name: "" + gateway_ip: "" + subnet_mask: "" + range_start: "" + range_end: "" + lease_duration: 86400 + icmp_timeout_msec: 1000 + clients: [] + # - name: myuser + # tags: + # - user_admin + # ids: + # - 192.168.91.1 + # use_global_settings: true + # filtering_enabled: false + # parental_enabled: false + # safesearch_enabled: false + # safebrowsing_enabled: false + # use_global_blocked_services: true + # blocked_services: [] + # upstreams: [] + log_file: "" + verbose: false + schema_version: 6 + image: repository: adguard/adguardhome - tag: v0.102.0 + # Image tag is set via charts appVersion. If you want to override the tag, specify it here + # tag: vX.Y.Z pullPolicy: IfNotPresent nameOverride: "" fullnameOverride: "" +podSecurityContext: {} + # fsGroup: 2000 + +securityContext: {} + # capabilities: + # drop: + # - ALL + # add: + # - NET_BIND_SERVICE + # readOnlyRootFilesystem: true + # runAsNonRoot: true + # runAsUser: 1000 + timezone: "UTC" ingress: @@ -143,6 +321,15 @@ persistence: ## Do not delete the pvc upon helm uninstall skipuninstall: false +volumePermissions: + image: + repository: busybox + tag: latest + pullPolicy: Always + resources: {} + # requests: + # memory: 128Mi + # cpu: 100m resources: {} # We usually recommend not to specify default resources and to leave this as a conscious