From 356bc0bc1e8c4b63088ad2992a2537512b71a582 Mon Sep 17 00:00:00 2001 From: Pieter Lexis Date: Fri, 11 Dec 2020 11:28:53 +0100 Subject: [PATCH] Port the dockerfiles from master to rec-4.4 --- .dockerignore | 1 - Dockerfile-recursor | 104 +++++++++++++++++++++++++++++++++++++++ Makefile.docker | 36 ++++++++++++++ dockerdata/recursor.conf | 2 + dockerdata/startup.py | 67 +++++++++++++++++++++++++ 5 files changed, 209 insertions(+), 1 deletion(-) create mode 100644 Dockerfile-recursor create mode 100644 Makefile.docker create mode 100644 dockerdata/recursor.conf create mode 100755 dockerdata/startup.py diff --git a/.dockerignore b/.dockerignore index 7a1bfd3327..c1f2fc99d5 100644 --- a/.dockerignore +++ b/.dockerignore @@ -1,3 +1,2 @@ builder/tmp built_pkgs -.git diff --git a/Dockerfile-recursor b/Dockerfile-recursor new file mode 100644 index 0000000000..ccebb237a8 --- /dev/null +++ b/Dockerfile-recursor @@ -0,0 +1,104 @@ +# USAGE + +# docker build --build-arg MAKEFLAGS=-j8 -t recursor -f docker/Dockerfile-recursor . +# docker run -p 1053:53 -p 1053:53/udp -ti --rm recursor +# dig a www.example.com @0 -p 1053 + +# Builder +FROM debian:10-slim AS builder + +# Reusable layer for base update +RUN apt-get update && apt-get -y dist-upgrade && apt-get clean + +# devscripts gives us mk-build-deps (and a lot of other stuff) +RUN apt-get install -y --no-install-recommends devscripts equivs git curl && apt-get clean + +COPY builder-support /source/builder-support + +# TODO: control file is not in tarballs at all right now +RUN mk-build-deps -i -t 'apt-get -y -o Debug::pkgProblemResolver=yes --no-install-recommends' /source/builder-support/debian/recursor/debian-buster/control && \ + apt-get clean +# RUN apt-get -y install protobuf-compiler && apt-get clean + +COPY pdns /source/pdns +COPY build-aux /source/build-aux +COPY m4 /source/m4 +COPY ext /source/ext +COPY .git /source/.git +COPY builder/helpers/set-configure-ac-version.sh /usr/local/bin + +# build and install (TODO: before we hit this line, rearrange /source structure if we are coming from a tarball) +WORKDIR /source/pdns/recursordist + +ARG MAKEFLAGS= +ENV MAKEFLAGS ${MAKEFLAGS:--j2} + +ARG DOCKER_FAKE_RELEASE=NO +ENV DOCKER_FAKE_RELEASE ${DOCKER_FAKE_RELEASE} + +# Manpage deps +# RUN apt-get install -y python3-venv && apt-get clean + +# Manpage prevent +RUN touch pdns_recursor.1 rec_control.1 # avoid installing pandoc + +RUN if [ "${DOCKER_FAKE_RELEASE}" = "YES" ]; then \ + BUILDER_VERSION="$(BUILDER_MODULES=recursor ./builder-support/gen-version | sed 's/\([0-9]\+\.[0-9]\+\.[0-9]\+\).*/\1/')" set-configure-ac-version.sh;\ + fi && \ + BUILDER_MODULES=recursor autoreconf -vfi + +RUN mkdir /build && \ + ./configure \ + --with-lua=luajit \ + LDFLAGS=-rdynamic \ + --sysconfdir=/etc/powerdns \ + --enable-option-checking=fatal && \ + make clean && \ + make $MAKEFLAGS install DESTDIR=/build && make clean && \ + strip /build/usr/local/bin/* /build/usr/local/sbin/* +RUN cd /tmp && mkdir /build/tmp/ && mkdir debian && \ + echo 'Source: docker-deps-for-pdns' > debian/control && \ + dpkg-shlibdeps /build/usr/local/bin/rec_control /build/usr/local/sbin/pdns_recursor && \ + sed 's/^shlibs:Depends=/Depends: /' debian/substvars >> debian/control && \ + equivs-build debian/control && \ + dpkg-deb -I equivs-dummy_1.0_all.deb && cp equivs-dummy_1.0_all.deb /build/tmp/ + +# Runtime +FROM debian:10-slim + +# Reusable layer for base update - Should be cached from builder +RUN apt-get update && apt-get -y dist-upgrade && apt-get clean + +# Ensure python3 and jinja2 is present (for startup script), and tini for signal management +RUN apt-get install -y python3 python3-jinja2 tini libcap2-bin && apt-get clean + +# Executables from builder +COPY --from=builder /build / +RUN chmod 1777 /tmp # FIXME: better not use /build/tmp for equivs at all +RUN setcap 'cap_net_bind_service=+eip' /usr/local/sbin/pdns_recursor + +# Ensure dependencies are present +RUN apt install -y /tmp/equivs-dummy_1.0_all.deb && apt clean + +# Start script +COPY dockerdata/startup.py /usr/local/sbin/pdns_recursor-startup + +# Config file(s) from builder +COPY dockerdata/recursor.conf /etc/powerdns/ + +# Is recursor.d necessary if we copy the config into recursor.conf? (see above) +RUN mkdir -p /etc/powerdns/recursor.d /var/run/pdns-recursor /etc/powerdns/templates.d + +# Work with pdns user - not root +RUN adduser --system --disabled-password --disabled-login --no-create-home --group pdns --uid 953 +RUN chown pdns:pdns /var/run/pdns-recursor /etc/powerdns/recursor.d /etc/powerdns/templates.d +USER pdns + +# DNS ports +EXPOSE 53/udp +EXPOSE 53/tcp + +# webserver port +EXPOSE 8082/tcp + +ENTRYPOINT ["/usr/bin/tini", "--", "/usr/local/sbin/pdns_recursor-startup"] diff --git a/Makefile.docker b/Makefile.docker new file mode 100644 index 0000000000..e882a1eb79 --- /dev/null +++ b/Makefile.docker @@ -0,0 +1,36 @@ +.PHONY: all build build-nocache dep auth recursor dnsdist + +VERSION=experimental +REVISION=1 + +all: build + +auth: + docker build --build-arg VERSION=$(VERSION) -t powerdns/pdns-auth-master:$(VERSION)-$(REVISION) --rm -f Dockerfile-auth . + +recursor: + docker build --build-arg VERSION=$(VERSION) -t powerdns/pdns-recursor-master:$(VERSION)-$(REVISION) --rm -f Dockerfile-recursor . + +dnsdist: + docker build --build-arg VERSION=$(VERSION) -t powerdns/dnsdist-master:$(VERSION)-$(REVISION) --rm -f Dockerfile-dnsdist . + +build: auth recursor dnsdist + @true + +build-nocache: + docker build --build-arg VERSION=$(VERSION) -t powerdns/pdns-auth-master:$(VERSION)-$(REVISION) --no-cache --rm -f Dockerfile-auth . + docker build --build-arg VERSION=$(VERSION) -t powerdns/pdns-recursor-master:$(VERSION)-$(REVISION) --no-cache --rm -f Dockerfile-recursor . + docker build --build-arg VERSION=$(VERSION) -t powerdns/dnsdist-master:$(VERSION)-$(REVISION) --no-cache --rm -f Dockerfile-dnsdist . + +push: build + docker push powerdns/pdns-auth-master:$(VERSION)-$(REVISION) + docker push powerdns/pdns-recursor-master:$(VERSION)-$(REVISION) + docker push powerdns/dnsdist-master:$(VERSION)-$(REVISION) + +push-latest: build + docker tag powerdns/pdns-auth-master:$(VERSION)-$(REVISION) powerdns/pdns-auth-master:latest + docker push powerdns/pdns-auth-master:latest + docker tag powerdns/pdns-recursor-master:$(VERSION)-$(REVISION) powerdns/pdns-recursor-master:latest + docker push powerdns/pdns-recursor-master:latest + docker tag powerdns/dnsdist-master:$(VERSION)-$(REVISION) powerdns/dnsdist-master:latest + docker push powerdns/dnsdist-master:latest diff --git a/dockerdata/recursor.conf b/dockerdata/recursor.conf new file mode 100644 index 0000000000..efc61ad181 --- /dev/null +++ b/dockerdata/recursor.conf @@ -0,0 +1,2 @@ +local-address=0.0.0.0,:: +include-dir=/etc/powerdns/recursor.d diff --git a/dockerdata/startup.py b/dockerdata/startup.py new file mode 100755 index 0000000000..7819cc306e --- /dev/null +++ b/dockerdata/startup.py @@ -0,0 +1,67 @@ +#!/usr/bin/env python3 +import os +import sys +import jinja2 + +program = sys.argv[0].split('-')[0] +product = os.path.basename(program) + +apienvvar = None +apiconftemplate = None +templateroot = '/etc/powerdns/templates.d' +templatedestination = '' +args = [] + +if product == 'pdns_recursor': + args = ['--disable-syslog'] + apienvvar = 'PDNS_RECURSOR_API_KEY' + apiconftemplate = """webserver +api-key={{ apikey }} +webserver-address=0.0.0.0 +webserver-allow-from=0.0.0.0/0 +webserver-password={{ apikey }} + """ + templatedestination = '/etc/powerdns/recursor.d' +elif product == 'pdns_server': + args = ['--disable-syslog'] + apienvvar = 'PDNS_AUTH_API_KEY' + apiconftemplate = """webserver +api +api-key={{ apikey }} +webserver-address=0.0.0.0 +webserver-allow-from=0.0.0.0/0 +webserver-password={{ apikey }} + """ + templatedestination = '/etc/powerdns/pdns.d' +elif product == 'dnsdist': + args = ['--supervised', '--disable-syslog'] + apienvvar = 'DNSDIST_API_KEY' + apiconftemplate = """webserver("0.0.0.0:8083", '{{ apikey }}', '{{ apikey }}', {}, '0.0.0.0/0') +controlSocket('0.0.0.0:5199') +setKey('{{ apikey }}') +setConsoleACL('0.0.0.0/0') + """ + templateroot = '/etc/dnsdist/templates.d' + templatedestination = '/etc/dnsdist/conf.d' + +apikey = os.getenv(apienvvar) +if apikey is not None: + webserver_conf = jinja2.Template(apiconftemplate).render(apikey=apikey) + conffile = os.path.join(templatedestination, '_api.conf') + with open(conffile, 'w') as f: + f.write(webserver_conf) + print("Created {} with content:\n{}\n".format(conffile, webserver_conf)) + +templates = os.getenv('TEMPLATE_FILES') +if templates is not None: + for templateFile in templates.split(','): + template = None + with open(os.path.join(templateroot, templateFile + '.j2')) as f: + template = jinja2.Template(f.read()) + rendered = template.render(os.environ) + target = os.path.join(templatedestination, templateFile + '.conf') + with open(target, 'w') as f: + f.write(rendered) + print("Created {} with content:\n{}\n".format(target, rendered)) + +os.execv(program, [program]+args+sys.argv[1:]) -- 2.47.2