From 9cd32903bc790a9f3434398d4a69b795993c29a0 Mon Sep 17 00:00:00 2001 From: velvettear Date: Fri, 20 Oct 2023 13:06:49 +0200 Subject: [PATCH] initial commit --- .dockerignore | 2 + .gitignore | 2 + Dockerfile | 28 ++++++ LICENSE.md | 20 ++++ README.md | 6 ++ docker-compose.yml | 11 +++ unbound/APKBUILD | 116 ++++++++++++++++++++++ unbound/build.sh | 78 +++++++++++++++ unbound/conf.patch | 46 +++++++++ unbound/migrate-dnscache-to-unbound | 147 ++++++++++++++++++++++++++++ unbound/unbound.confd | 11 +++ unbound/unbound.initd | 48 +++++++++ unbound/unbound.pre-install | 7 ++ 13 files changed, 522 insertions(+) create mode 100644 .dockerignore create mode 100644 .gitignore create mode 100644 Dockerfile create mode 100644 LICENSE.md create mode 100644 README.md create mode 100644 docker-compose.yml create mode 100644 unbound/APKBUILD create mode 100755 unbound/build.sh create mode 100644 unbound/conf.patch create mode 100644 unbound/migrate-dnscache-to-unbound create mode 100644 unbound/unbound.confd create mode 100644 unbound/unbound.initd create mode 100644 unbound/unbound.pre-install diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 0000000..efe3d96 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,2 @@ +build +docker-compose.yml \ No newline at end of file diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..8aaadfe --- /dev/null +++ b/.gitignore @@ -0,0 +1,2 @@ +build +unbound/src/* \ No newline at end of file diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 0000000..4ca0047 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,28 @@ +FROM alpine:latest + +LABEL version="1.0.0" \ + author="Daniel Sommer " \ + license="MIT" + +MAINTAINER Daniel Sommer + +ENV VERSION= + +COPY [ "unbound", "/tmp/unbound" ] + +RUN apk upgrade --no-cache --progress \ + && apk add --no-cache --progress \ + alpine-sdk \ + dnssec-root \ + expat-dev \ + libevent-dev \ + linux-headers \ + openssl-dev \ + protobuf-c-dev \ + python3-dev \ + swig \ + hiredis-dev \ + bind-tools \ + ldns-tools + +ENTRYPOINT ["/tmp/unbound/build.sh"] \ No newline at end of file diff --git a/LICENSE.md b/LICENSE.md new file mode 100644 index 0000000..d342365 --- /dev/null +++ b/LICENSE.md @@ -0,0 +1,20 @@ +# MIT License +**Copyright (c) 2022 Daniel Sommer \** + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is furnished +to do so, subject to the following conditions: + +The above copyright notice and this permission notice (including the next +paragraph) shall be included in all copies or substantial portions of the +Software. + +**THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS +OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, +WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF +OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.** \ No newline at end of file diff --git a/README.md b/README.md new file mode 100644 index 0000000..a48725b --- /dev/null +++ b/README.md @@ -0,0 +1,6 @@ +# unbound-redis-apk + +build .apk files for [unbound](https://nlnetlabs.nl/projects/unbound) with support for as cache backend [redis](https://redis.io) for [alpine linux](https://alpinelinux.org/). + +**installation on alpine linux:** +`apk add --no-cache --allow-untrusted .apk` \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml new file mode 100644 index 0000000..348b647 --- /dev/null +++ b/docker-compose.yml @@ -0,0 +1,11 @@ +version: "3" + +services: + builder: + container_name: "unbound-redis-apk-builder" + build: "." + environment: + - VERSION= + volumes: + - /etc/resolv.conf:/etc/resolv.conf:ro + - ./build:/build \ No newline at end of file diff --git a/unbound/APKBUILD b/unbound/APKBUILD new file mode 100644 index 0000000..8d2ea14 --- /dev/null +++ b/unbound/APKBUILD @@ -0,0 +1,116 @@ +# Contributor: Sören Tempel +# Contributor: Carlo Landmeter +# Contributor: Natanael Copa +# Maintainer: Jakub Jirutka +pkgname=unbound +pkgver=0.0.0 +pkgrel=0 +pkgdesc="Unbound is a validating, recursive, and caching DNS resolver" +url="https://nlnetlabs.nl/projects/unbound/about/" +arch="all" +license="BSD-3-Clause" +depends="dnssec-root" +depends_dev="expat-dev" +_depends_migrate=" + /bin/sh + apk-tools + openrc + " +makedepends="$depends_dev + libevent-dev + linux-headers + openssl-dev>3 + protobuf-c-dev + python3-dev + swig + " +checkdepends=" + bind-tools + ldns-tools + " +install="$pkgname.pre-install" +pkgusers="unbound" +pkggroups="unbound" +subpackages=" + $pkgname-dbg + $pkgname-dev + $pkgname-doc + $pkgname-libs + $pkgname-openrc + py-unbound:py + $pkgname-migrate::noarch + " +source="https://unbound.net/downloads/unbound-$pkgver.tar.gz + conf.patch + migrate-dnscache-to-unbound + $pkgname.initd + $pkgname.confd + " + +build() { + export CFLAGS="$CFLAGS -flto=auto" + + PYTHON_VERSION=3 ./configure \ + --build="$CBUILD" \ + --host="$CHOST" \ + --prefix=/usr \ + --sysconfdir=/etc \ + --mandir=/usr/share/man \ + --localstatedir=/var \ + --with-username=unbound \ + --with-run-dir="" \ + --with-pidfile="" \ + --with-rootkey-file=/usr/share/dnssec-root/trusted-key.key \ + --with-libevent \ + --with-pthreads \ + --disable-static \ + --disable-rpath \ + --enable-dnstap \ + --with-ssl \ + --without-pythonmodule \ + --with-pyunbound \ + --with-libhiredis \ + --enable-cachedb + + # do not link to libpython + sed -i -e '/^LIBS=/s/-lpython.*[[:space:]]/ /' Makefile + + make +} + +check() { + make test +} + +package() { + make DESTDIR="$pkgdir" install + make DESTDIR="$pkgdir" unbound-event-install + + install -Dm755 contrib/update-anchor.sh \ + "$pkgdir"/usr/share/$pkgname/update-anchor.sh + + install -D -m644 doc/CREDITS doc/Changelog doc/FEATURES \ + doc/README doc/TODO -t "$pkgdir"/usr/share/doc/$pkgname/ + + cd "$pkgdir" + + install -Dm755 "$srcdir"/unbound.initd ./etc/init.d/unbound + install -Dm644 "$srcdir"/unbound.confd ./etc/conf.d/unbound +} + +py() { + pkgdesc="Python bindings to libunbound" + depends="$depends_py" + + amove usr/lib/python* +} + +migrate() { + pkgdesc="Simple tool to migrate from dnscache to unbound" + depends="$_depends_migrate" + + install -m755 -D "$srcdir"/migrate-dnscache-to-unbound \ + "$subpkgdir"/usr/bin/migrate-dnscache-to-unbound +} + +sha512sums="" \ No newline at end of file diff --git a/unbound/build.sh b/unbound/build.sh new file mode 100755 index 0000000..56999f2 --- /dev/null +++ b/unbound/build.sh @@ -0,0 +1,78 @@ +#!/usr/bin/env sh + +# exit on error +set -e + +# variables +unbound_dir="/tmp/unbound" +src_dir="$unbound_dir/src" + +# functions +function checkEnvironment() { + [[ -n "$VERSION" ]] && return + printf "environment variable 'VERSION' is unset, defaulting to 'latest'...\n" + VERSION="latest" +} + +function checkAndExtractArchive() { + cd "$src_dir" + archive="$(find "$src_dir" -type f -iname 'unbound*.tar.gz' -exec basename {} \;)" + [[ -n "$archive" ]] && tar -xzf "$archive" && rm -f "$archive" && return + archive="$(find "$src_dir" -type f -iname 'unbound*.zip' -exec basename {} \;)" + [[ -z "$archive" ]] && return + unzip -q "$archive" -d "$(basename -s ".zip" $archive)" && rm -f "$archive" +} + +function getPkgVersion() { + pkgver="$(find "$src_dir" -type d -iname 'unbound*' -exec sh -c "realpath {} | cut -d "-" -f2" \;)" +} + +function downloadSources() { + mkdir -p "$src_dir" + cd "$src_dir" + wget "https://nlnetlabs.nl/downloads/unbound/unbound-$VERSION.tar.gz" + tar -xzf "unbound-$VERSION.tar.gz" + rm -f "unbound-$VERSION.tar.gz" +} + +# main routine +printf "starting build process for unbound with redis support...\n" + +# check if an archive is in "$src_dir" present and extract it +checkAndExtractArchive + +# check if a valid version has been copied to "$src_dir" +getPkgVersion + +# if no valid version could be found, start a download +if [[ -z "$pkgver" ]]; then + checkEnvironment + downloadSources + getPkgVersion +fi + +# exit if no unbound version could be determined +[[ -z "$pkgver" ]] && printf "error: could not determine unbound version\n" && exit 1 + +# replace version in APKBUILD file +sed -i "s/pkgver=0.0.0/pkgver=$pkgver/" "$unbound_dir/APKBUILD" + +# generate key pairs +printf "\n" | abuild-keygen -a + +# generate checksums and start the build +cd "$unbound_dir" +abuild -F checksum +abuild -F -r + +# move the built packages +[[ ! -d "/build" ]] && mkdir -p "/build" +rm -rf "/build/"* +find $HOME/packages -type f -iname '*.apk' -exec mv {} /build \; + +# clean up +rm -rf "$unbound_dir" + +printf ".apk files can be found at '/build'\n" +cd "/build" +ls -1 \ No newline at end of file diff --git a/unbound/conf.patch b/unbound/conf.patch new file mode 100644 index 0000000..e92cc37 --- /dev/null +++ b/unbound/conf.patch @@ -0,0 +1,46 @@ +diff -upr unbound-1.13.0.orig/doc/example.conf.in unbound-1.13.0/doc/example.conf.in +--- unbound-1.13.0.orig/doc/example.conf.in 2020-12-21 09:58:04.154390497 +0100 ++++ unbound-1.13.0/doc/example.conf.in 2020-12-21 09:58:53.094583255 +0100 +@@ -355,9 +355,6 @@ server: + # print log lines that say why queries return SERVFAIL to clients. + # log-servfail: no + +- # the pid file. Can be an absolute path outside of chroot/work dir. +- # pidfile: "@UNBOUND_PIDFILE@" +- + # file to read root hints from. + # get one from https://www.internic.net/domain/named.cache + # root-hints: "" +@@ -507,7 +504,7 @@ server: + # you start unbound (i.e. in the system boot scripts). And enable: + # Please note usage of unbound-anchor root anchor is at your own risk + # and under the terms of our LICENSE (see that file in the source). +- # auto-trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@" ++ # auto-trust-anchor-file: "" + + # trust anchor signaling sends a RFC8145 key tag query after priming. + # trust-anchor-signaling: yes +@@ -519,7 +516,7 @@ server: + # with several entries, one file per entry. + # Zone file format, with DS and DNSKEY entries. + # Note this gets out of date, use auto-trust-anchor-file please. +- # trust-anchor-file: "" ++ trust-anchor-file: "@UNBOUND_ROOTKEY_FILE@" + + # Trusted key for validation. DS or DNSKEY. specify the RR on a + # single line, surrounded by "". TTL is ignored. class is IN default. +@@ -900,12 +897,13 @@ dynlib: + remote-control: + # Enable remote control with unbound-control(8) here. + # set up the keys and certificates with unbound-control-setup. +- # control-enable: no ++ control-enable: yes + + # what interfaces are listened to for remote control. + # give 0.0.0.0 and ::0 to listen to all interfaces. + # set to an absolute path to use a unix local name pipe, certificates + # are not used for that, so key and cert files need not be present. ++ control-interface: /run/unbound.control.sock + # control-interface: 127.0.0.1 + # control-interface: ::1 + diff --git a/unbound/migrate-dnscache-to-unbound b/unbound/migrate-dnscache-to-unbound new file mode 100644 index 0000000..03b34cd --- /dev/null +++ b/unbound/migrate-dnscache-to-unbound @@ -0,0 +1,147 @@ +#!/bin/sh + + +to_subnet() { + pref=$1 + case "$pref" in + *.*.*.*) echo $pref/32;; + *.*.*) echo $pref.0/24;; + *.*) echo $pref.0.0/16;; + *) echo $pref.0.0.0/8;; + esac +} + +gen_config() { + echo "# Config generated by $0, $(date)" + echo "server:" + + [ -n "$IP" ] && echo -e "\tinterface: $IP\n" + [ -n "$IPSEND" ] && echo -e "\toutgoing-interface: $IPSEND\n" + + for i in $access_control; do + echo -e "\taccess-control: $i allow" + done + echo "" + + # stub zones + local zonefile ip + local fwdtype="stub" + if [ -n "$FORWARDONLY" ]; then + fwdtype="forward" + fi + for zonefile in "$root"/etc/dnscache/servers/*; do + local zone=${zonefile##*/} + case "$zone" in + '@'|'*'|*.apk-new) continue;; + esac + echo "${fwdtype}-zone:" + echo -e "\tname: ${zone}" + for ip in $(cat $zonefile); do + echo -e "\t${fwdtype}-addr: $ip" + done + echo "" + done +} + +usage() { + cat >&2 <&2 + mv "$unbound_conf" "${unbound_conf}".backup +fi + +$quiet || echo "Generating $unbound_conf" >&2 +gen_config > "$unbound_conf" + +# stop dnscache and start unbound +if /etc/init.d/dnscache --quiet status 2>/dev/null; then + /etc/init.d/dnscache $quiet_opt stop + if ! /etc/init.d/unbound $quiet_opt start; then + echo "Failed to start unbound. Starting up dnscache again" + /etc/init.d/dnscache $quiet_opt start + exit 1 + fi +fi + +# update runlevels +errors=0 +if rc-update | grep -q -w dnscache; then + runlevels=$(rc-update | awk '$1 == "dnscache" { FS="|"; $0 = $0; print $2 }') + for level in $runlevels; do + rc-update $quiet_opt add unbound $level \ + || errors=$(($errors + 1)) + rc-update $quiet_opt del dnscache $level \ + || errors=$(($errors + 1)) + done +fi + +# cleanup if requested +if [ $errors -eq 0 ] && ! $keep_backup ; then + $quiet || echo "Purging dnscache and dnscache config" >&2 + apk del --purge $quiet_opt dnscache + rm -rf $root/etc/dnscache $root/etc/conf.d/dnscache + $quiet || echo "Purging ${unbound_conf}.backup" >&2 + rm -rf ${unbound_conf}.backup +fi + +exit $errors diff --git a/unbound/unbound.confd b/unbound/unbound.confd new file mode 100644 index 0000000..275081b --- /dev/null +++ b/unbound/unbound.confd @@ -0,0 +1,11 @@ +# Configuration for /etc/init.d/unbound + +# Path of the configuration file. +#cfgfile="/etc/unbound/$RC_SVCNAME.conf" + +# Additional arguments for the unbound command. +# Add "-v" to enable verbose logging (more times to increase verbosity). +#command_args="" + +# Uncomment to use process supervisor. +#supervisor=supervise-daemon diff --git a/unbound/unbound.initd b/unbound/unbound.initd new file mode 100644 index 0000000..c5c6d70 --- /dev/null +++ b/unbound/unbound.initd @@ -0,0 +1,48 @@ +#!/sbin/openrc-run + +extra_commands="checkconfig" +extra_started_commands="reload" + +name="unbound daemon" +description="unbound is a Domain Name Server (DNS) that is used to resolve host names to IP address." +description_checkconfig="Run syntax tests for configuration files only." +description_reload="Kills all children and reloads the configuration." + +# Upper case variables are here only for backward compatibility. +: ${cfgfile:=${UNBOUND_CONFFILE:-/etc/unbound/$RC_SVCNAME.conf}} + +command=/usr/sbin/unbound +command_args="-d $command_args" +command_background=yes +pidfile="/run/$RC_SVCNAME.pid" + +required_files="$cfgfile" + +depend() { + need net + use logger + provide dns + after auth-dns entropy +} + +checkconfig() { + ebegin "Checking $cfgfile" + /usr/sbin/unbound-checkconf -f "$cfgfile" >/dev/null + eend $? +} + +start_pre() { + checkconfig +} + +reload() { + start_pre || return $? + + ebegin "Reloading $name" + if [ "$supervisor" ]; then + $supervisor "$RC_SVCNAME" --signal HUP + else + start-stop-daemon --signal HUP --pidfile "$pidfile" + fi + eend $? +} diff --git a/unbound/unbound.pre-install b/unbound/unbound.pre-install new file mode 100644 index 0000000..94144c7 --- /dev/null +++ b/unbound/unbound.pre-install @@ -0,0 +1,7 @@ +#!/bin/sh + +addgroup -S unbound 2>/dev/null +adduser -S -D -H -h /etc/unbound -s /sbin/nologin -G unbound \ + -g "Unbound user" unbound 2>/dev/null + +exit 0