DNSlog-GO is a DNS server you point your own domain at, for out of band callbacks
DNSLog-GO 是一款golang编写的监控 DNS 解析记录的工具,自带WEB界面 / DNSLog-GO is a monitoring tool written in Golang that monitors DNS resolution records. It comes with a web interface.
At a glance
- What is it?
- DNSlog-GO is a Go service that answers DNS queries and shows you what was looked up, with a web console, an HTTP API, a CLI and a Go SDK. It is useful for seeing blind callbacks from SSRF, XXE or template injection, and the cost of running it yourself is a domain, its own NS records, and a privileged container to bind port 53.
- Who is it for?
- DNSlog-GO fits a security engineer who needs to see out of band DNS callbacks from an application under test, and who is willing to run a domain and a server for the purpose. It is the wrong tool if you only want to check one URL once, since a hosted logging service does the same job without the domain and NS setup.
- Can I use it commercially?
- Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 8 days ago.
- What is it written in?
- Mainly Go, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 24, 2026, and from our analysis. They are not legal advice.
Editorial analysis
A DNS server that records what was looked up
DNSlog-GO is a monitoring tool written in Golang that monitors DNS resolution records, and it comes with a web interface. The README lists what it supports, and the list is short enough to be precise.
It deploys with one docker command. It works in web interface mode or API mode. It supports multiple accounts, for several people to use, or for tool driven scanning and manual testing to run side by side with the data not interfering with each other. And it supports setting DNS A records, for temporary testing or for ns service self resolution.
The job it does is deceptively simple. The tool runs a DNS server. You give it a domain, delegate it to that server, and every query that arrives is recorded and shown. The reason that is interesting is what shows up in those records. A server side request forgery, an XML external entity, an out of band template injection or a DNS exfiltration attempt all produce a lookup somewhere, and a tool that answers every query can show you the hostname, the source address and the timing of a callback that would otherwise be invisible.
The multi-user model matters for that use case. If a scanner is generating callbacks continuously and a human is testing an endpoint by hand, the two would otherwise contaminate each other's results, so each account gets its own subdomain and its own view.
The project is MIT licensed, the repository is not archived, and the last push was on 2026-10-15. It has also joined the 404 star chain project, the 404StarLink programme run by knownsec, which tracks Chinese security tooling.
A domain and its own NS records, and up to two days of waiting
The setup section is where most of the effort goes, and it is worth being blunt about that, because it is the part that is easy to underestimate.
You need a domain, and a public IP address. Then you change the NS records of that domain to two nameservers of the form NS1.vpsip.NIP.IO and NS2.vpsip.NIP.IO, which resolve from the IP you own, so that a name like ns1.1.1.1.1.nip.io points at 1.1.1.1.
The README flags a real constraint here. Some domain providers only allow the NS records to be changed to nameserver addresses that have already been authenticated, so you need to find a provider that allows pointing NS records at your own nameservers. And after the NS records are changed, some regions need 24 to 48 hours for the change to take effect.
That delay is a practical constraint on how you can use the tool in a test cycle.
The alternative to running your own server is a hosted DNS logging service, which removes the domain and NS work entirely and gives you a subdomain immediately. The difference in approach is ownership: a hosted service keeps the query records on someone else's infrastructure, while this one keeps them on a server you control, along with the tokens and the web console.
One configuration file for the HTTP listener, the users and the domain
The configuration is a YAML file, and the sample in the README is short enough to read in full.
Http:
host: 0.0.0.0
port: 8000
consoleDisable: false
User:
#"token":"用户对应子域名"
'admin': 'dnslog'
Dns:
domain: demo.com
ARecord:
'www': '1.1.1.1'Three blocks, three responsibilities. The Http block binds the web console and the API, and consoleDisable turns the console off when you want the service to be API only. The User block maps a token to the subdomain that belongs to that user, which is how the multi-account separation works. The Dns block names the domain the server is authoritative for, and the ARecord sub-block lets you serve an A record for a name, which is the temporary testing and self resolution feature.
One operational note in the README is easy to miss and painful to debug. After the server is restarted, if the subdomain for a user has been changed, the browser's localStorage has to be cleared, otherwise the data cannot be fetched. The console keeps the old subdomain in the browser, and the server no longer recognises it.
The repository also ships a Dockerfile and a docker-compose.yml. The image exposes 53/udp and 8000, the compose file maps 53:53 for TCP, 53:53/udp and 28888:8000 for the web interface, mounts the config file, and runs privileged so the container can bind the low port.
The CLI is the automation surface, and it prints JSON
The command line client is the most recent addition to the project and the most scriptable part of it. There are prebuilt archives in the releases, dnslog-cli-macos.zip, dnslog-cli-linux.zip and dnslog-cli-windows.zip, all amd64, and the binary is dnslog-cli, or dnslog-cli.exe on Windows. It can also be built from source.
make build-cliConfiguration is set through the CLI rather than by hand editing a file.
./build/dnslog-cli config set \
--url "http://127.0.0.1:8000" \
--token "admin"The config goes to ~/.config/dnslog-go/config.yaml with file permissions 0600, and the README makes a security point about it: the token may be kept in your shell history, so on a shared machine you should turn history off temporarily or use an environment variable instead. The environment variables DNSLOG_BASE_URL and DNSLOG_TOKEN take precedence over the config file, and DNSLOG_CONFIG points at a different config file path.
The command list shows the design.
./build/dnslog-cli verify-token
./build/dnslog-cli config path
./build/dnslog-cli get-dns
./build/dnslog-cli verify-dns abc.dnslog.demo.com
./build/dnslog-cli verify-http /dnslog/test --timeout 15s --interval 1s
./build/dnslog-cli random-domain
./build/dnslog-cli helpverify-dns and verify-http query once immediately, and when nothing is found they retry every 500ms by default, waiting up to 10s, adjustable with --timeout and --interval, and --timeout 0 disables polling entirely. A successful query that did not hit returns {"found":false}, and a failed request or a timeout returns a non-zero exit code with the error written to standard error. Apart from the help output, everything the CLI prints on standard output is JSON, which the README says makes it suitable for being called by an agent.
The Go SDK can confirm many lookups in one request
For a Go program that is testing an application, the SDK removes the need to speak the HTTP API by hand.
client, err := sdk.NewDnsLogClient("http://127.0.0.1:8000", "admin")
...
dnslog := client.RandomSubDomain(10)
client.RandomSSRFUrl(10)
http.Get("http://" + dnslog)
if ok, _ := client.VerifyDns(dnslog); ok {
println(">> [DNS] 验证成功", dnslog)
}
if ok, _ := client.VerifyDnsV2(dnslog); ok {
println(">> [DNS] 验证成功", dnslog)
}
client.Clear()Two verification methods are offered and the difference is the point. VerifyDns checks one domain per request, while VerifyDnsV2 verifies multiple DNS records in one request, which the code comment describes as higher efficiency and suitable for scanners sending a large number of DNS requests. For a tool that is generating thousands of callbacks, the number of round trips is the difference between a test that finishes and a test that times out.
The rest of the client is the surrounding mechanics. RandomSubDomain and RandomSSRFUrl generate names, and Clear removes the records the test created, which matters if the same server is used for many test cases in sequence.
There is also a Python example in the README that shows the same idea over raw HTTP, with an initial call to /api/verifyToken that returns the subdomain belonging to the token, and a /api/verifyDns call that takes a Query field. The API reference lives in API.md at the repository root. The Go SDK itself is in pkg/sdk, and the server entrypoint is cmd/server/main.go.
Binding port 53 is why the container needs privileged mode
The one command install in the README is worth looking at closely, because every flag in it is a consequence of what the tool does.
wget https://raw.githubusercontent.com/lanyi1998/DNSlog-GO/master/config.yaml
docker run -d -p 53:53 -p 53:53/udp -p 8000:8000 -v `pwd`/config.yaml:/DNSlog-GO/config.yaml --name dnslog --privileged --restart=always lanyi1998/dnslog-go:latestPort 53 has to be published on both TCP and UDP, because DNS resolution uses both and a client will fall back from one to the other. The web interface is on 8000, matching the Http block of the config file. The config file is mounted from the working directory, so editing it on the host and restarting the container is the intended workflow. And --privileged is there because binding a low port inside the container needs the privilege, which the compose file says explicitly in a comment about binding low ports such as 53.
The Dockerfile shows the server itself is small. It builds a static binary with CGO_ENABLED=0, ldflags to strip the symbol table, copies the binary and the config into an alpine image, sets the timezone, and exposes 53/udp and 8000. The Go module is small in the same way, with gin for the HTTP layer, zap for logging, yaml for configuration and asn1-ber for the DNS wire format, on Go 1.24 with a toolchain of 1.24.7.
The limitation to be aware of is the environment rather than the software. A server that answers DNS on port 53 on a well known address is a honeypot shaped object, and binding that port in a container, on a shared host, or behind a provider that blocks low ports, is where the deployment stops being simple.
An Agent Skill that deliberately does not hold the token
The repository ships an Agent Skill under skills/dnslog-go, designed to be used together with the CLI. The security design is stated in one sentence: the Skill does not store or receive the token, and the CLI reads the credentials automatically from the environment variable or from the user configuration file.
That is a sensible boundary. An agent prompt is a place where secrets leak, and keeping the credential in a file with 0600 permissions or in an environment variable keeps it out of the conversation.
Installation is either go install for the CLI, or a release archive, and then the skill is copied into the Codex skills directory.
go install github.com/lanyi1998/DNSlog-GO/cmd/dnslog-cli@latestmkdir -p ~/.codex/skills
cp -R skills/dnslog-go ~/.codex/skills/dnslog-goAfter that the skill can be called explicitly as $dnslog-go, or an agent can select it automatically when it recognises a DNSlog-GO task. The README also notes that after installing the CLI from a release archive you should add its directory to PATH so the skill can invoke dnslog-cli, and that dnslog-cli help is the way to check the installation worked.
The project also carries a .claude/ directory and a skills/ directory at the top level, next to the usual cmd/, internal/, pkg/ and tests/. The release history is regular, with v2.3.1 on 2026-01-21, v2.3.0 on 2025-12-19 and v2.2.3 on 2025-11-29, and the licence is MIT with the file at the repository root.
Editorial conclusion
DNSlog-GO fits a security engineer who needs to see out of band DNS callbacks from an application under test, and who is willing to run a domain and a server for the purpose. It is the wrong tool if you only want to check one URL once, since a hosted logging service does the same job without the domain and NS setup. Verify first that you can delegate NS records for your domain, that the propagation delay of up to 48 hours is acceptable for your test cycle, and that your resolver allows the server to answer on port 53 in your environment.
Frequently asked questions
What is DNSlog-GO used for?
It is a Go tool that monitors DNS resolution records and comes with a web interface, so you can see queries that arrive at a domain you control. That makes it a way to observe out of band callbacks such as those produced by SSRF, XXE or template injection during a test.
What do I need to run DNSlog-GO?
A domain you control and a public IP address. You change the domain's NS records to nameservers of the form NS1.vpsip.NIP.IO pointing at your IP, and the README notes that some providers only allow NS records to be set to already authenticated nameservers, and that the change can take 24 to 48 hours to take effect in some regions.
How do I use the DNSlog-GO command line client?
Download dnslog-cli-linux.zip, dnslog-cli-macos.zip or dnslog-cli-windows.zip from the releases, or run make build-cli, then use config set with --url and --token to write the config, and the verify-token, get-dns, verify-dns, verify-http and random-domain commands. The CLI writes JSON to standard output and errors to standard error.
Why does the DNSlog-GO container run in privileged mode?
Because the service binds port 53, and the compose file explains that privileged mode is usually needed to bind a low port such as 53. The container publishes 53:53 over TCP, 53:53/udp and 8000:8000 for the web interface.
Does the DNSlog-GO Agent Skill store the token?
No. The README states that the Skill does not store or receive the token, and that the CLI reads the credentials from the environment variable or from the user configuration file, which is written with 0600 permissions.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/lanyi1998-dnslog-go)Was this useful?