Skip to content
Open
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
51 changes: 51 additions & 0 deletions .github/workflows/pr-build-install-selftest.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
name: PR Build Install Selftest

on:
pull_request:
workflow_dispatch:

jobs:
build-install-selftest:
runs-on: ubuntu-latest

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

- name: Install dependencies
run: |
sudo apt-get update
sudo apt-get install --no-install-recommends -y \
libwolfssl-dev \
libnghttp2-dev \
curl \
openssl \
xxd \
iproute2

- name: Build
run: |
make -j"$(nproc)"

- name: Install to staging prefix
run: |
make install DESTDIR=/tmp/dohd-install-ci VERSION=0.8
test -x /tmp/dohd-install-ci/usr/local/sbin/dohd
test -x /tmp/dohd-install-ci/usr/local/sbin/dohproxyd
test -x /tmp/dohd-install-ci/usr/local/sbin/ns2dohd
test -x /tmp/dohd-install-ci/usr/local/sbin/odoh-keygen

- name: Run ODoH proxy+target self-test
run: |
DOHD_BIN=/tmp/dohd-install-ci/usr/local/sbin/dohd \
DOHPROXYD_BIN=/tmp/dohd-install-ci/usr/local/sbin/dohproxyd \
WORKDIR=/tmp/dohd-odoh-selftest \
examples/odoh/selftest-proxy-target-curl.sh

- name: Upload self-test artifacts on failure
if: failure()
uses: actions/upload-artifact@v4
with:
name: odoh-selftest-logs
path: /tmp/dohd-odoh-selftest
if-no-files-found: ignore
66 changes: 46 additions & 20 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,32 @@ BINDIR ?= $(PREFIX)/sbin
MANDIR ?= $(PREFIX)/share/man

build:
make -C src
make -C ns2dohd
$(MAKE) -C src
$(MAKE) -C ns2dohd
$(MAKE) -C proxy
$(MAKE) -C tools

debug:
make -C src debug
make -C ns2dohd debug
$(MAKE) -C src debug
$(MAKE) -C ns2dohd debug
$(MAKE) -C proxy debug
$(MAKE) -C tools debug

dmalloc:
make -C src dmalloc
$(MAKE) -C src dmalloc

asan:
make -C src asan
make -C ns2dohd asan
$(MAKE) -C src asan
$(MAKE) -C ns2dohd asan
$(MAKE) -C proxy asan
$(MAKE) -C tools asan

clean:
make -C src clean
make -C ns2dohd clean
make -C test clean
$(MAKE) -C src clean
$(MAKE) -C ns2dohd clean
$(MAKE) -C proxy clean
$(MAKE) -C tools clean
$(MAKE) -C test clean

docker-build:
docker build -f devops/Dockerfile . -t dyne/dohd:${VERSION}
Expand All @@ -34,38 +42,38 @@ docker-run:

# Run all unit tests
check:
make -C test check
$(MAKE) -C test check

# Run unit tests with ASAN (for leak detection)
check-asan: asan
make -C test check
$(MAKE) -C test check

# Run integration tests (requires running dohd instance)
check-integration:
make -C test integration
$(MAKE) -C test integration

# Run valgrind leak detection test
check-valgrind:
make -C test valgrind
$(MAKE) -C test valgrind

# Stress tests (auto-launch dohd, bombard until failure)
stress:
make -C test stress
$(MAKE) -C test stress

stress-escalate:
make -C test stress-escalate
$(MAKE) -C test stress-escalate

stress-flood:
make -C test stress-flood
$(MAKE) -C test stress-flood

stress-chaos:
make -C test stress-chaos
$(MAKE) -C test stress-chaos

stress-all:
make -C test stress-all
$(MAKE) -C test stress-all

stress-asan:
make -C test stress-asan
$(MAKE) -C test stress-asan

# requires https://github.com/DNS-OARC/flamethrower
# default upstream GENERATOR: -g randomlabel lblsize=10 lblcount=4 count=1000
Expand All @@ -84,15 +92,33 @@ install: build
install -d $(DESTDIR)$(BINDIR)
install -m 0755 src/dohd $(DESTDIR)$(BINDIR)/dohd
install -m 0755 ns2dohd/ns2dohd $(DESTDIR)$(BINDIR)/ns2dohd
install -m 0755 proxy/dohproxyd $(DESTDIR)$(BINDIR)/dohproxyd
install -m 0755 tools/odoh-keygen $(DESTDIR)$(BINDIR)/odoh-keygen
install -d $(DESTDIR)$(MANDIR)/man8
install -m 0644 man/dohd.8 $(DESTDIR)$(MANDIR)/man8/dohd.8
install -m 0644 man/ns2dohd.8 $(DESTDIR)$(MANDIR)/man8/ns2dohd.8
install -m 0644 man/dohproxyd.8 $(DESTDIR)$(MANDIR)/man8/dohproxyd.8
install -d $(DESTDIR)$(MANDIR)/man1
install -m 0644 man/odoh-keygen.1 $(DESTDIR)$(MANDIR)/man1/odoh-keygen.1
install -d $(DESTDIR)$(PREFIX)/share/dohd/examples
install -m 0755 examples/odoh/deploy-target-example.sh $(DESTDIR)$(PREFIX)/share/dohd/examples/deploy-target-example.sh
install -m 0755 examples/odoh/deploy-proxy-example.sh $(DESTDIR)$(PREFIX)/share/dohd/examples/deploy-proxy-example.sh
install -m 0755 examples/odoh/selftest-proxy-target-curl.sh $(DESTDIR)$(PREFIX)/share/dohd/examples/selftest-proxy-target-curl.sh
install -m 0644 examples/odoh/dodh_targets $(DESTDIR)$(PREFIX)/share/dohd/examples/dodh_targets

uninstall:
rm -f $(DESTDIR)$(BINDIR)/dohd
rm -f $(DESTDIR)$(BINDIR)/ns2dohd
rm -f $(DESTDIR)$(BINDIR)/dohproxyd
rm -f $(DESTDIR)$(BINDIR)/odoh-keygen
rm -f $(DESTDIR)$(MANDIR)/man8/dohd.8
rm -f $(DESTDIR)$(MANDIR)/man8/ns2dohd.8
rm -f $(DESTDIR)$(MANDIR)/man8/dohproxyd.8
rm -f $(DESTDIR)$(MANDIR)/man1/odoh-keygen.1
rm -f $(DESTDIR)$(PREFIX)/share/dohd/examples/deploy-target-example.sh
rm -f $(DESTDIR)$(PREFIX)/share/dohd/examples/deploy-proxy-example.sh
rm -f $(DESTDIR)$(PREFIX)/share/dohd/examples/selftest-proxy-target-curl.sh
rm -f $(DESTDIR)$(PREFIX)/share/dohd/examples/dodh_targets

.PHONY: build debug dmalloc asan clean docker-build docker-build-alpine docker-run \
check check-asan check-integration check-valgrind check-flame site \
Expand Down
40 changes: 40 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,16 @@ option: `--enable-tls13` or simply `--enable-all`).
sudo make install
```

Installed helper tool:

- `odoh-keygen` (manpage: `man odoh-keygen`) generates ODoH X25519 key material in the exact formats required by `dohd`/`ns2dohd`.

Example:

```bash
odoh-keygen -s /etc/dohd/odoh-target.secret -p /etc/dohd/odoh-target.public -c /etc/dohd/odoh-target.config
```

***
# 🎮 Quick start

Expand Down Expand Up @@ -119,6 +129,36 @@ Usage: dohd -c cert -k key [-p port] [-d dnsserver] [-F] [-u user] [-V] [-v] [-h
- Manpage: `man ns2dohd`
- To route system DNS through `ns2dohd`, set `nameserver 127.0.0.1` in `/etc/resolv.conf` or set `127.0.0.1` as primary DNS in NetworkManager.
- Run `ns2dohd` as root in daemon mode and drop privileges with `-u`.
- ODoH mode: run `ns2dohd -O --odoh-proxy https://proxy.example/dns-query --odoh-config /path/to/odoh.config ...`

## dohproxyd

`dohproxyd` is a standalone DoH/ODoH proxy daemon.

- Binary: `proxy/dohproxyd`
- Manpage: `man dohproxyd`
- Installed by `make install` together with `dohd` and `ns2dohd`
- Use `--target-cert` and `--target-key` when forwarding to a `dohd -O` target that enforces authorized proxy certificates.
- For legacy RFC8484 forwarding, provide targets with repeated `--target-url` or `--targets-file`; target selection uses RFC-style random rotation.

## ODoH Deployment Warning (RFC 9230)

For ODoH privacy properties to hold, **do not deploy proxy and target on the same host or under the same organization**.
The proxy and target are expected to be independently operated and separately observable entities.
If one operator controls or can observe both sides, it can correlate client identity/metadata at the proxy with decrypted DNS content at the target, defeating obliviousness.

Running both locally is acceptable only for protocol evaluation, development, and interoperability testing.

## ODoH Helper Scripts

Example scripts are provided in `examples/odoh/`:

- `examples/odoh/deploy-target-example.sh`
- `examples/odoh/deploy-proxy-example.sh`
- `examples/odoh/selftest-proxy-target-curl.sh`
- `examples/odoh/dodh_targets` (sample input for `dohproxyd --targets-file`)

The self-test script intentionally runs proxy+target on one host and uses `curl` for transport checks. It is not a production deployment model.

***
# 😍 Acknowledgements
Expand Down
47 changes: 47 additions & 0 deletions examples/odoh/deploy-proxy-example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
#!/bin/sh
set -eu

# RFC 9230 trust separation warning:
# Deploy this proxy under a different operator and infrastructure than the target.
# Do not co-host proxy and target in production.

DOHPROXYD_BIN="${DOHPROXYD_BIN:-/usr/local/sbin/dohproxyd}"
RUN_AS="${RUN_AS:-dohd}"
LISTEN_PORT="${LISTEN_PORT:-8443}"

TLS_CERT="${TLS_CERT:-/etc/dohd/proxy.crt}"
TLS_KEY="${TLS_KEY:-/etc/dohd/proxy.key}"

# mTLS identity presented by this proxy to targets (if targets require it).
TARGET_CERT="${TARGET_CERT:-/etc/dohd/proxy-client.crt}"
TARGET_KEY="${TARGET_KEY:-/etc/dohd/proxy-client.key}"

# Optional legacy RFC8484 targets:
# export TARGET_URLS="https://target-a.example/dns-query https://target-b.example/dns-query"
# export TARGETS_FILE="/etc/dohd/dodh_targets"
TARGET_URLS="${TARGET_URLS:-}"
TARGETS_FILE="${TARGETS_FILE:-}"

set -- \
"$DOHPROXYD_BIN" \
-F \
-u "$RUN_AS" \
-c "$TLS_CERT" \
-k "$TLS_KEY" \
-p "$LISTEN_PORT" \
--target-cert "$TARGET_CERT" \
--target-key "$TARGET_KEY"

if [ -n "$TARGETS_FILE" ]; then
set -- "$@" --targets-file "$TARGETS_FILE"
fi

if [ -n "$TARGET_URLS" ]; then
for u in $TARGET_URLS; do
set -- "$@" --target-url "$u"
done
fi

echo "Launching ODoH proxy:"
printf ' %s\n' "$@"
exec "$@"
41 changes: 41 additions & 0 deletions examples/odoh/deploy-target-example.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
#!/bin/sh
set -eu

# RFC 9230 trust separation warning:
# Run ODoH target and ODoH proxy in different administrative domains.
# This script is only an example of target launch/configuration.

DOHD_BIN="${DOHD_BIN:-/usr/local/sbin/dohd}"
RUN_AS="${RUN_AS:-dohd}"
LISTEN_PORT="${LISTEN_PORT:-8053}"
UPSTREAM_DNS="${UPSTREAM_DNS:-1.1.1.1}"

TLS_CERT="${TLS_CERT:-/etc/dohd/target.crt}"
TLS_KEY="${TLS_KEY:-/etc/dohd/target.key}"

ODOH_CONFIG="${ODOH_CONFIG:-/etc/dohd/odoh-target.config}"
ODOH_SECRET="${ODOH_SECRET:-/etc/dohd/odoh-target.secret}"
AUTHORIZED_PROXY_DIR="${AUTHORIZED_PROXY_DIR:-/etc/dohd/proxies}"

echo "Launching ODoH target resolver:"
echo " binary: $DOHD_BIN"
echo " tls: $TLS_CERT / $TLS_KEY"
echo " odoh: $ODOH_CONFIG / $ODOH_SECRET"
echo " authz: $AUTHORIZED_PROXY_DIR"
echo
echo "Reminder: install proxy client-cert public keys in:"
echo " $AUTHORIZED_PROXY_DIR"
echo "One PEM file per authorized proxy key."
echo

exec "$DOHD_BIN" \
-F \
-u "$RUN_AS" \
-c "$TLS_CERT" \
-k "$TLS_KEY" \
-p "$LISTEN_PORT" \
-d "$UPSTREAM_DNS" \
-O \
--odoh-config "$ODOH_CONFIG" \
--odoh-secret "$ODOH_SECRET" \
--authorized-proxies-dir "$AUTHORIZED_PROXY_DIR"
4 changes: 4 additions & 0 deletions examples/odoh/dodh_targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Example legacy RFC8484 target list for dohproxyd --targets-file
# One https URL per line.
https://target-a.example.net/dns-query
https://target-b.example.net/dns-query
Loading