Installation
BoronDNS ships as a single statically-linked musl binary for x86_64-linux. No runtime dependencies, no shared libraries. The release archive also includes a Docker image and an installer script.
System requirements
- CPU: x86-64 (static musl build)
- OS: Current Linux LTS kernel or later (standard POSIX networking and signal handling)
- Memory: Enough RAM to hold your zones; zone data lives in memory only — every process start is a cold start
- Ports: UDP/TCP 53 for DNS service; a management HTTP port (default 8080) for health and metrics
- Network: Outbound TCP access to each primary for AXFR/IXFR; inbound NOTIFY from configured primaries
BoronDNS is also supported in OCI-compatible containers (Docker, Podman, Kubernetes) and as a native Linux process under systemd or another supervisor.
Installer archive (recommended)
The tag-push release publishes a self-contained installer archive for x86_64-unknown-linux-musl. Download it from the releases page:
# Verify checksum
sha256sum -c borondns-0.2.0-x86_64-unknown-linux-musl.tar.xz.sha256
# Extract and install
tar -xf borondns-0.2.0-x86_64-unknown-linux-musl.tar.xz
cd borondns-0.2.0-x86_64-unknown-linux-musl/
sudo ./install.sh
The archive contains:
bin/borondns— the static server binarybin/boron-gun— the DNS load-testing tool (XDP-enabled)install.sh— installer script- systemd and OpenRC service templates
- Example config (
config/borondns.example.toml) - Licenses and SBOM
Docker image
The release also publishes an Alpine-based Docker image archive (not a registry image). Load it manually:
sha256sum -c borondns-0.2.0-x86_64-unknown-linux-musl-docker-image.tar.xz.sha256
xz -dc borondns-0.2.0-x86_64-unknown-linux-musl-docker-image.tar.xz | docker load
docker run --rm borondns:0.2.0 --version
Recommended runtime hardening — map host port 53 to the unprivileged container port 5300 to avoid CAP_NET_BIND_SERVICE:
docker run -d --name borondns \
--read-only \
--ulimit nofile=65536:65536 \
--cap-drop ALL \
--security-opt no-new-privileges \
--pids-limit 128 \
-p 53:5300/udp \
-p 53:5300/tcp \
-p 127.0.0.1:8080:8080/tcp \
-v /etc/borondns-secondary/config.toml:/etc/borondns-secondary/config.toml:ro \
borondns:0.2.0 \
serve --config /etc/borondns-secondary/config.toml
The image runs as UID/GID 53053 by default and binds unprivileged container ports.
Build from source
Install prerequisites:
# Rust stable toolchain (pinned in rust-toolchain.toml)
rustup toolchain install stable
rustup component add rustfmt clippy
Build the release binary:
git clone https://github.com/Integrity-Ltd/borondns.git
cd borondns
cargo build --locked --release -p borondns-cli
sudo install -m 0755 target/release/borondns /usr/local/bin/borondnssystemd service
The installer script places a systemd unit at /etc/systemd/system/borondns.service. For manual installs:
[Unit]
Description=BoronDNS secondary authoritative nameserver
Documentation=https://borondns.io/docs/
After=network-online.target
Wants=network-online.target
[Service]
Type=simple
User=borondns
Group=borondns
ExecStart=/usr/local/bin/borondns serve --config /etc/borondns-secondary/config.toml
Restart=on-failure
RestartSec=5s
LimitNOFILE=65536
# Bind to port 53 without root
AmbientCapabilities=CAP_NET_BIND_SERVICE
CapabilityBoundingSet=CAP_NET_BIND_SERVICE
# Hardening
NoNewPrivileges=yes
PrivateTmp=yes
ProtectSystem=strict
ProtectHome=yes
[Install]
WantedBy=multi-user.target
Create the service user and config directory:
sudo useradd --system --no-create-home --shell /usr/sbin/nologin borondns
sudo install -d -m 0755 /etc/borondns-secondary
sudo install -m 0640 config/borondns.example.toml /etc/borondns-secondary/config.toml
sudo chown borondns:borondns /etc/borondns-secondary/config.toml
Enable and start:
sudo systemctl daemon-reload
sudo systemctl enable --now borondns
sudo systemctl status borondnsVerifying the installation
borondns --version
# borondns 0.2.0 (x86_64-unknown-linux-musl, rustc 1.87.0)
curl -fsS http://127.0.0.1:8080/livez
# {"status":"alive","version":"0.2.0","uptime_seconds":5}Service manager notes
- BoronDNS ignores
SIGHUP— configuration topology changes require a process restart. SIGTERMandSIGINTtrigger graceful shutdown (drain in-flight queries, then exit).- Zone data lives in memory only. There is no persistent cache; every restart begins with a fresh AXFR/IXFR from configured primaries.
- For privileged port 53, prefer running as an unprivileged user with
CAP_NET_BIND_SERVICEgranted by systemd, rather than running as root.
Next: Configuration — all config.toml options explained.