This is the source code for dnstools.ws.
DNSTools is split into two pieces:
The website is a C# ASP .NET Core 8.0 website, built using React and SignalR.
The "worker" (or "agent") is a small app that runs on multiple servers around the world. It's a gRPC service written in C# using .NET Core 8.0 and compiled to a single executable using Native AoT. In production, the workers are a mix of KVM and OpenVZ7 VPSes running Debian Bookworm (12).
Some workers (such as pings and traceroutes) use the standard ping and traceroute command-line utilities. Pings can only be sent by root, and reusing existing well-tested code is more secure than creating our own setuid binaries. Other tools (like DNS lookups) are all performed using C# code.
The DnsTools.sln Visual Studio 2022 solution contains both the website and the worker.
The website consists of two parts: A frontend app built using Create React App, and a backend app built using C#. To run the development version of the website, you need to start both:
- Frontend: Run
yarn startin thesrc/DnsTools.Web/ClientAppdirectory - Backend: Run
DnsTools.Webfrom Visual Studio, or viadotnet runat the command-line
You can then hit the site at http://localhost:31429/. The C# backend is running on https://localhost:5001/ but this is only used for API requests - All webpages are loaded via the Webpack dev server.
The worker requires a few Linux utilities (like ping and traceroute) to be available.
To build the Alpine version, musl is required:
# On Fedora
sudo dnf install musl-gcc musl-libc-static
# on Debian
sudo apt install musl-tools
Build and deploy the site using the publish script:
cd src/DnsTools.web
./publish.ps1The workers are all configured and deployed using Ansible.
Some manual configuration is required before running Ansible:
- Generate a random password and store it in
./ansible/vault-password - Store servers'
sudopassword in an encrypted Ansible Vault file:
cd ansible
ansible-vault create passwd.yml
ansible-vault edit passwd.yml --vault-password-file=vault-passwordIn the file, add:
sudo_pass: put_the_password_here- Start
ssh-agentand load the Ansible SSH key:
eval `ssh-agent`
ssh-add ~/.ssh/id_ed25519_ansibleRunning the deploy-workers.sh script will run the playbook to deploy all the workers. Be sure to publish the worker app first:
dotnet publish --no-self-contained -r linux-x64 -c ReleaseFor new workers, some manual configuration is required after the first time it's deployed using Ansible:
Create a TLS certificate for the worker:
sudo certbot certonly --manual --manual-auth-hook /etc/letsencrypt/acme-dns-auth.py --preferred-challenges dns --debug-challenges --server https://acme-v02.api.letsencrypt.org/directory --cert-name dnstools-worker -d xx.worker.networktest.org(where xx is some identifier for the worker, like fr for France or us-ny for New York)