Installation¶
There are three common ways to install DNSao. After that, follow the post-install steps to point clients at the server.
After installation, follow Post-install to make devices use DNSao.
If this is your first time using DNSao, start with the Quick Start. This page is the full installation reference.
After installation, point your devices, or ideally your router/DHCP server, to DNSao as their DNS server. Then open the web port defined in application.yml to check the dashboard.
Before Installing¶
Make sure:
- Nothing else is listening on host port
53/udpor53/tcpif DNSao will serve DNS directly. - The dashboard port, usually
8044/tcp, is reachable from machines that should access it. - Java 17 or newer is installed if you are not using Docker.
- Any directory used for
server.statsDbPathor log files already exists and is writable by the DNSao process.
Check port 53:
sudo ss -tulpn | grep :53
This should return nothing when DNSao will bind directly to port 53.
Installation via Docker¶
Docker is the recommended first installation path because it does not require Java on the host and keeps the runtime isolated.
Make sure the host machine is not running anything on port 53:
sudo ss -tulpn | grep :53
Then use Docker Compose:
services:
dnsao:
image: ghcr.io/vitallan/dnsao:latest
container_name: dnsao
restart: unless-stopped
ports:
- "53:8053/tcp"
- "53:8053/udp"
- "8044:8044"
volumes:
- /your/local/volume:/etc/dnsao
Start the service:
docker compose up -d
The container listens on port 8053 internally. The Compose file maps host port 53 to container port 8053, so clients still use normal DNS port 53.
If /your/local/volume is empty, DNSao will download the default Docker application.yml file to the volume and use it.
DNSao stores metrics and query history in a SQLite file by default. If you set a custom server.statsDbPath, such as /etc/dnsao/stats.db, ensure your volume mount is writable by the container.
Installation via script¶
The only dependency of DNSao is the presence of a JDK version 17 or higher.
DNSao stores metrics and query history in a SQLite file by default ({tmpdir}/dnsao.db). If you set a custom server.statsDbPath, make sure the parent directory exists and is writable (DNSao will not create directories).
If your server is Debian-based:
apt-get update -y
apt-get install -y openjdk-17-jre-headless
If red hat based:
dnf install -y java-17-openjdk-headless
Other options can be found on the official OpenJDK website. After installing the JDK, the machine will be ready to run DNSao.
Before installing, visit the installation script to review and confirm what will be executed. Also, confirm that nothing else is listening on port 53 to avoid conflict:
sudo ss -tulpn | grep :53
This should return nothing.
To execute the installation script, run it as root:
curl -sSL https://raw.githubusercontent.com/vitallan/dnsao/refs/heads/main/scripts/install.sh | sudo bash
On the server itself, if the dig command is available, you can validate the installation with:
dig debian.org @127.0.0.1
The result should look like this:
; <<>> DiG 9.20.11-4-Debian <<>> debian.org @127.0.0.1
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 4434
;; flags: qr rd ra ad; QUERY: 1, ANSWER: 4, AUTHORITY: 0, ADDITIONAL: 1
;; OPT PSEUDOSECTION:
; EDNS: version: 0, flags:; udp: 512
;; QUESTION SECTION:
;debian.org. IN A
;; ANSWER SECTION:
debian.org. 279 IN A 151.101.2.132
debian.org. 279 IN A 151.101.130.132
debian.org. 279 IN A 151.101.194.132
debian.org. 279 IN A 151.101.66.132
;; Query time: 7 msec
;; SERVER: 192.168.150.150#53(192.168.150.150) (UDP)
;; WHEN: Wed Jan 05 17:38:05 -03 2020
;; MSG SIZE rcvd: 103
Application logs are available through the systemd journal and, when file logging is enabled by the sample config, under /var/log/dnsao:
journalctl -u dnsao -e
tail -f /var/log/dnsao/*.log
You can now reach http://YOUR.SERVER.IP:8044 and check the metrics dashboard. Using this method will make DNSao run as a systemctl service, so systemctl commands should work:
sudo systemctl stop dnsao
sudo systemctl enable dnsao
sudo systemctl start dnsao
To uninstall, you can use the uninstall script.
Manual installation¶
You can also download the latest jar and perform a manual configuration. All configuration is done in the single application.yml file. A standard execution example would be as follows:
java -Dconfig=/etc/dnsao/application.yml -jar dnsao.jar
Keep in mind that, on Linux, ports below 1024 require root privileges to run without being managed by a service. Consider this when running the server manually.
Another important detail: since it’s a Java application, it’s recommended to limit memory usage. In its default installation script, DNSao runs with the following flags:
- -Xms128m -Xmx256m: starts the heap at 128 MB and caps it at 256 MB
- -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m: limits the metaspace size
- -Xss320k: limits the maximum stack size per thread
The final command is then:
java -Dconfig=/etc/dnsao/application.yml -Xms128m -Xmx256m -XX:MetaspaceSize=64m -XX:MaxMetaspaceSize=128m -Xss320k -jar /etc/dnsao/dnsao.jar
Upgrade¶
Before upgrading, keep a copy of /etc/dnsao/application.yml, especially if you customized upstreams, local mappings, groups, logs, or cache settings.
For systemd installations created by the install script, review the upgrade script and run:
curl -sSL https://raw.githubusercontent.com/vitallan/dnsao/refs/heads/main/scripts/upgrade.sh | sudo bash
The script downloads the latest released dnsao.jar, replaces /etc/dnsao/dnsao.jar, and restarts dnsao.service. It does not replace your existing /etc/dnsao/application.yml.
For Docker Compose installations, update the image and recreate the container:
docker compose pull
docker compose up -d
For manual installations, stop DNSao, replace the JAR with the downloaded release artifact, and start it again:
sudo systemctl stop dnsao
sudo curl -fL https://github.com/vitallan/dnsao/releases/latest/download/dnsao.jar -o /etc/dnsao/dnsao.jar
sudo chown dnsao:dnsao /etc/dnsao/dnsao.jar
sudo systemctl start dnsao
Operations¶
For systemd installations, common service commands are:
sudo systemctl status dnsao
sudo systemctl restart dnsao
sudo systemctl stop dnsao
Logs are available through systemd journal and, when file logging is configured, under /var/log/dnsao:
journalctl -u dnsao -e
tail -f /var/log/dnsao/*.log
Metrics and query history use SQLite by default. When server.statsDbPath is unset, DNSao stores the database in the operating system temporary directory. For persistent deployments, configure a path such as /etc/dnsao/stats.db and ensure the parent directory exists and is writable by the DNSao process.
Cache rewarm refreshes entries that are near the end of their TTL. Rewarm attempts are rate-limited by cache.maxRewarmPerMinute; DNSao enforces this as a per-second budget and each rewarm attempt sends one upstream query.
resolver.multiplier controls how many upstreams receive a normal client query. Higher values may improve latency but expose each query to more upstream resolvers. Rewarm does not use the multiplier.
Block and allow lists are downloaded at startup. When misc.refreshLists is true, DNSao refreshes them every 12 hours.
Verify Installation¶
Validate DNS resolution from the DNSao host:
dig example.com @127.0.0.1
Validate from another machine on the network:
dig example.com @DNSAO_IP
Open the dashboard:
http://DNSAO_IP:8044
If queries work but the dashboard is unreachable, check firewall rules for 8044/tcp. If the dashboard works but DNS does not, check firewall rules for 53/udp and 53/tcp.
Post install¶
After setting up the server with one of the above installation methods, you will need to configure your router to serve to it's DHCP clients to use DNSao as their DNS server, which will make the devices in your network use it.
Such configuration depends on the which router is used.
Another way is to set each individual device to use DNSao as it's DNS server, which might not be ideal for multiple devices, but can be done, and it is also useful to test the installation before going full on.