Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add DoT support #78

Merged
merged 6 commits into from
Sep 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 7 additions & 11 deletions .github/workflows/docker-publish-dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -8,15 +8,11 @@ name: Docker MultiArch Build Dev
on:
workflow_dispatch:
push:
branches: [ dev ]
branches: [ 76-add-doh-and-dot-support ]
paths-ignore:
- '**/README.md'
# Publish semver tags as releases.
tags: [ 'v*.*.*' ]
pull_request:
branches: [ main ]
paths-ignore:
- '**/README.md'

env:
# Use docker.io for Docker Hub if empty
Expand All @@ -38,19 +34,19 @@ jobs:

steps:
- name: Checkout repository
uses: actions/checkout@v2
uses: actions/checkout@v4

- name: Set up QEMU
uses: docker/setup-qemu-action@v2
uses: docker/setup-qemu-action@v3

- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v2
uses: docker/setup-buildx-action@v3

# Login against a Docker registry except on PR
# https://github.com/docker/login-action
- name: Log into registry ${{ env.REGISTRY }}
if: github.event_name != 'pull_request'
uses: docker/login-action@v2
uses: docker/login-action@v3
with:
registry: ${{ env.REGISTRY }}
username: ${{ github.actor }}
Expand All @@ -60,7 +56,7 @@ jobs:
# https://github.com/docker/metadata-action
- name: Extract Docker metadata
id: meta
uses: docker/metadata-action@v4
uses: docker/metadata-action@v5
with:
images: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}
tags: |
Expand All @@ -77,7 +73,7 @@ jobs:
# https://github.com/docker/build-push-action
- name: Build and push Docker image
id: build-and-push
uses: docker/build-push-action@v3
uses: docker/build-push-action@v5
with:
context: .
platforms: linux/amd64,linux/arm/v7,linux/arm64
Expand Down
13 changes: 12 additions & 1 deletion Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -6,16 +6,23 @@ ENV DNSDIST_BIND_IP=0.0.0.0
ENV ALLOWED_CLIENTS=127.0.0.1
ENV ALLOWED_CLIENTS_FILE=
ENV EXTERNAL_IP=

ENV DNSDIST_ENABLE_DOT=false
ENV DNSDIST_DOT_CERT_TYPE=auto-self

ENV DNSDIST_WEBSERVER_PASSWORD=
ENV DNSDIST_WEBSERVER_API_KEY=
ENV DNSDIST_WEBSERVER_NETWORKS_ACL="127.0.0.1, ::1"

ENV DNSDIST_UPSTREAM_CHECK_INTERVAL=10
ENV DNSDIST_UPSTREAM_POOL_NAME="upstream"

ENV DNSDIST_RATE_LIMIT_DISABLE=false
ENV DNSDIST_RATE_LIMIT_WARN=800
ENV DNSDIST_RATE_LIMIT_BLOCK=1000
ENV DNSDIST_RATE_LIMIT_BLOCK_DURATION=360
ENV DNSDIST_RATE_LIMIT_EVAL_WINDOW=60

ENV SPOOF_ALL_DOMAINS=false
ENV DYNDNS_CRON_SCHEDULE="*/15 * * * *"
ENV INSTALL_DEFAULT_DOMAINS=true
Expand All @@ -28,6 +35,7 @@ EXPOSE 5300/udp
EXPOSE 8080/tcp
EXPOSE 8443/tcp
EXPOSE 8083/tcp
EXPOSE 8530/tcp

RUN echo "I'm building for $TARGETPLATFORM"

Expand All @@ -38,10 +46,13 @@ RUN apk update && apk upgrade
RUN addgroup snidust && adduser -D -H -G snidust snidust

# Install needed packages and clean up
RUN apk add --no-cache jq tini dnsdist curl bash gnupg procps ca-certificates openssl dog lua5.4-filesystem ipcalc libcap nginx nginx-mod-stream supercronic && rm -rf /var/cache/apk/*
RUN apk add --no-cache jq tini dnsdist curl bash gnupg procps ca-certificates openssl dog lua5.4-filesystem ipcalc libcap nginx nginx-mod-stream supercronic step-cli && \
rm -f /etc/nginx/conf.d/*.conf && \
rm -rf /var/cache/apk/*

# Setup Folder(s)
RUN mkdir -p /etc/dnsdist/conf.d && \
mkdir -p /etc/dnsdist/certs && \
mkdir -p /etc/snidust/domains.d && \
mkdir -p /etc/sniproxy/ && \
mkdir -p /var/lib/snidust/domains.d
Expand Down
4 changes: 4 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,10 @@ In case Systemd is already using port 53 you can follow this [Guide](https://www

## Advanced setups

### DoT

For examples how to use an setup DoT see `docker-compose.dot.yml` and `docker-compose.acme.sh-dot.yml`

### Disable installtion of repo default domains

If do not want use the default domain lists of this repo, you can disable this by setting the environment variable `INSTALL_DEFAULT_DOMAINS` to `false`.
Expand Down
15 changes: 15 additions & 0 deletions configs/dnsdist/conf.d/00-SniDust.conf
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,21 @@ function trim(s)
return s:match "^%s*(.*%S)" or ""
end

function ReloadCerts(dq)
infolog("[INFO] [SniDust] Reloading certs...")

-- prevent the query from going upstream
dq.dh:setQR(true)

-- load
reloadAllCertificates()

infolog("[INFO] [SniDust] Certs reloaded!")

-- respond with a local address just in case
return DNSAction.Spoof, "127.0.0.7"
end

-- read all the domains in a set
function LoadBlocklists(smn, folder)
f = io.popen('/bin/ls ' .. folder .. '*.lst')
Expand Down
18 changes: 15 additions & 3 deletions configs/dnsdist/dnsdist.conf.template
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,18 @@ echo "end"
echo ""

echo ""
echo "-- Add Bind"
echo "-- Add plain DNS bind"
echo "addLocal('${DNSDIST_BIND_IP}:5300')"
echo ""

if [ "${DNSDIST_ENABLE_DOT}" == "true" ]; then
echo "-- Add DoT bind"
echo "addTLSLocal('${DNSDIST_BIND_IP}:8530','/etc/dnsdist/certs/tls.pem','/etc/dnsdist/certs/tls.key')"
echo ""
else
echo "-- TLS Endpoints disabled"
fi

echo "-- Include Config"
echo "includeDirectory(\"/etc/dnsdist/conf.d\")"
echo ""
Expand Down Expand Up @@ -59,14 +67,18 @@ if [ "${DNSDIST_DEBUG}" == "true" ]; then
echo ""
fi

echo "-- query reload.blocklist.unblockdock.local to reload Blocklist"
echo "-- query reload.domainlist.snidust.local to reload Blocklist"
echo "addAction(AndRule({QNameRule(\"reload.domainlist.snidust.local\"),QTypeRule(\"A\")}),LuaAction(ReloadBlocklist))"
echo ""

echo "-- query reload.acl.unblockdock.local to reload Blocklist"
echo "-- query reload.acl.snidust.local to reload Blocklist"
echo "addAction(AndRule({QNameRule(\"reload.acl.snidust.local\"),QTypeRule(\"A\")}),LuaAction(ReloadACL))"
echo ""

echo "-- query reload.certs.snidust.local to reload certificates used for DoT"
echo "addAction(AndRule({QNameRule(\"reload.certs.snidust.local\"),QTypeRule(\"A\")}),LuaAction(ReloadCerts))"
echo ""

if [ "${SPOOF_ALL_DOMAINS}" == "true" ]; then
echo " -- rewrite it for ALL Domains"
echo "addAction(AllRule(), SpoofAction(\"${EXTERNAL_IP}\"))"
Expand Down
47 changes: 47 additions & 0 deletions docker-compose.acme.sh-dot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# NOTE: This is just an example (which is also not fully tested yet) how you could use sniDust with DoT and a trusted certificate.
# Is uses acme.sh and the DNS-01 method in conjuntion with cloudflare. For other options using acme.sh please see here: https://github.com/acmesh-official/acme.sh/wiki/
#
#
# You need run acme.sh ONCE manually. After the container will manually renew certs and call snidust to reload certs
# docker exec \
# -e CF_Token="TOKEN" \
# -e CF_Email="[email protected]" \
# acme.sh --issue -d dot.example.com --dns dns_cf
#
volumes:
acme_sh:
driver: local

services:
acme.sh:
container_name: acme.sh
image: neilpang/acme.sh
command: daemon
volumes:
- acme_sh:/acme.sh
- /var/run/docker.sock:/var/run/docker.sock
environment:
- DEPLOY_DOCKER_CONTAINER_LABEL=sh.acme.autoload.domain=dot.example.com
- DEPLOY_DOCKER_CONTAINER_KEY_FILE=/etc/dnsdist/cert/tls.key
- DEPLOY_DOCKER_CONTAINER_CERT_FILE="/etc/dnsdist/cert/cert.pem"
- DEPLOY_DOCKER_CONTAINER_CA_FILE="/etc/dnsdist/cert/ca.pem"
- DEPLOY_DOCKER_CONTAINER_FULLCHAIN_FILE="/etc/dnsdist/cert/tls.pem"
- DEPLOY_DOCKER_CONTAINER_RELOAD_CMD="/usr/bin/dog @127.0.0.1:5300 --short reload.certs.snidust.local"
sniDust:
container_name: sniDust
labels:
- sh.acme.autoload.domain=dot.example.com
environment:
- 'ALLOWED_CLIENTS=127.0.0.1/32, myDynDNSDomain.no-ip.com' # CHANGE THIS
- 'EXTERNAL_IP=10.111.123.8' # CHANGE THIS TO YOUR VPS PUBLIC IP
- TZ=Europe/Berlin
- DNSDIST_ENABLE_DOT=true
- DNSDIST_DOT_CERT_TYPE=manual
ports:
- '443:8443'
- '80:8080'
- '53:5300/udp'
- '53:5300/tcp'
- '853:8530/tcp'
image: 'ghcr.io/seji64/snidust:main'
restart: unless-stopped
21 changes: 21 additions & 0 deletions docker-compose.dot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
services:
sniDust:
container_name: sniDust
environment:
- 'ALLOWED_CLIENTS=127.0.0.1/32, myDynDNSDomain.no-ip.com' # CHANGE THIS
- 'EXTERNAL_IP=10.111.123.8' # CHANGE THIS TO YOUR VPS PUBLIC IP
- TZ=Europe/Berlin
- DNSDIST_ENABLE_DOT=true
- DNSDIST_DOT_CERT_TYPE=auto-self # Generate self-signed cert. Can also be set to 'manual'
# Uncomment this if you choose manual. Align paths to match your environment -> Just an example!
# volumes:
# - /etc/letsencrypt/live/dot.example.com/fullchain.pem:/etc/dnsdist/cert/tls.pem:ro
# - /etc/letsencrypt/live/dot.example.com/privkey.pem:/etc/dnsdist/cert/tls.key:ro
ports:
- '443:8443'
- '80:8080'
- '53:5300/udp'
- '53:5300/tcp'
- '853:8530/tcp'
image: 'ghcr.io/seji64/snidust:main'
restart: unless-stopped
3 changes: 1 addition & 2 deletions docker-compose.yml
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
version: '3.8'
services:
seji64:
sniDust:
container_name: sniDust
environment:
- 'ALLOWED_CLIENTS=127.0.0.1/32, myDynDNSDomain.no-ip.com' # CHANGE THIS
Expand Down
19 changes: 19 additions & 0 deletions entrypoint.sh
Original file line number Diff line number Diff line change
@@ -1,4 +1,23 @@
#!/bin/bash -e

# Validate DoT config
if [ "${DNSDIST_ENABLE_DOT}" == "true" ]; then
VALID_CERT_TYPE_VALUES=("auto-self" "manual")
if [[ -z "$DNSDIST_DOT_CERT_TYPE" ]]; then
echo "The environment variable DNSDIST_DOT_CERT_TYPE is not set."
exit 1
fi

if [[ " ${VALID_CERT_TYPE_VALUES[*]} " =~ " ${DNSDIST_DOT_CERT_TYPE} " ]]; then
if [ "${DNSDIST_DOT_CERT_TYPE}" == "auto-self" ]; then
/usr/bin/step certificate create dot.snidust.local /etc/dnsdist/certs/tls.pem /etc/dnsdist/certs/tls.key --profile self-signed --subtle --no-password --insecure
fi
else
echo "[ERROR] Invalid value for DNSDIST_DOT_CERT_TYPE: $DNSDIST_DOT_CERT_TYPE"
exit 1
fi
fi

if [ -z "${EXTERNAL_IP}" ];
then
echo "[INFO] External IP not set - trying to get IP by myself"
Expand Down