DomainMapper: resolving service domain names into router-ready IP lists
A tool for scanning and resolving DNS names into IP addresses
At a glance
- What is it?
- DomainMapper is a Python tool that resolves the domain names of popular web services into IP addresses and writes the result out in formats routers, VPNs and operating systems can consume. It aggregates adjacent addresses into subnets without losing coverage, keeps the DNS server lists and service domain lists current from upstream projects, and offers a Docker image, a Windows executable and several output formats including MikroTik, WireGuard, Keenetic CLI and OVPN.
- Who is it for?
- Adopt DomainMapper if you maintain router, VPN or firewall rules for blocked services and want the address lists maintained for you rather than hand-written. Do not expect the results to be stable, because a domain resolves to a different set of addresses over time and any static list will age.
- 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 16 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 25, 2026, and from our analysis. They are not legal advice.
Editorial analysis
What the tool does and the problem it addresses
DomainMapper is a tool for scanning and resolving DNS names into IP addresses. The README describes it in more detail as a Python tool intended for resolving the DNS names of popular web services into IP addresses and saving them as ready-made routes or lists for routers, VPNs and operating systems.
The use case is specific and, for the audience it addresses, obvious. If you run a router or a VPN server and need certain services to route somewhere particular, you need the IP addresses those services resolve to, and you need them as a list your device can consume. Writing those lists by hand means looking up each domain, noting each address, and maintaining the list as the service changes its infrastructure.
The features list names the capabilities in order. Converting domain names of popular services into IP addresses. Route aggregation, meaning merging neighbouring addresses either without loss or with a limit on the number of routes while capturing as few unnecessary addresses as possible. Optional filtering of Cloudflare IP addresses. Many output formats for saving results. And splitting large files into parts for the Keenetic BAT format.
The Cloudflare filter is worth a sentence, because it cuts the other way. Cloudflare fronts a very large share of the internet, so a service you resolve may return a Cloudflare address, and including it in a routing list is often not what you want. Being able to exclude them makes the output usable for a specific purpose rather than a general one.
The repository is MIT licensed, the default branch is main, the last push was on 2026-10-11 and the most recent tagged release is v0.1.3 from 2024-10-10, with v0.1.2 and v0.1.1 before it.
The service list and where the data comes from
The supported services list is long and specific, and it covers the kind of services that get blocked or throttled: Youtube, Anthropic, Linkedin, Facebook, Meta, Openai, Tik-Tok, Instagram, Twitter, Netflix, Bing, Adobe, Apple, Google, torrent trackers, search engines, Github Copilot, Twitch, Discord, Jetbrains, Xbox, Telegram, WhatsApp, online movie theaters, Windsurf, Roblox, Zscaler, Disney+, Eufy, Petlibro and TMDB, plus a custom DNS list for personal domains.
Two of these are community-maintained lists rather than hand-entered names: the Antifilter community edition, and ITDog Inside and ITDog Outside.
The names in the menu can be written in any case in config.ini, which is a small thing that saves a lot of frustration when you are typing a service name.
The domain lists themselves are updated automatically twice a month from two upstream projects: v2fly/domain-list-community and runetfreedom/russia-v2ray-rules-dat. Meta was added to the list and WhatsApp was moved to its own list, which tells you the upstream lists change shape over time and the tool has to follow.
There is also a platformdb directory in the repository alongside the dnsdb directory, and the DNS server list is loaded from the dnsdb directory or from disk in local mode. The distinction matters: the service domain lists come from upstream and refresh on a schedule, while the DNS server list is configuration the tool reads.
The DNS servers available are numbered in config.ini, and the list is worth reading because it shows the intent. Zero means all of the servers listed below. Then the system DNS from the operating system settings, Google Public DNS, Quad9, Cloudflare, OpenDNS, AdGuard DNS without filtering, Control D without filtering, CleanBrowsing with the security filter, UltraDNS Public, NextDNS and Yandex DNS.
The two entries marked without filtering are deliberate. A tool that resolves domains for you would otherwise resolve them through a filtering resolver and return filtered addresses, which would be useless for the stated purpose.
Route aggregation, DNS rate limiting and the progress bar
The most recent release notes describe a substantial rework, and three parts of it matter for anyone relying on the output.
The first is the aggregation change. The previous modes of 16, 24 and mix have been replaced by a new IP address aggregation in which exact merges neighbouring addresses without loss, while a limit on the number of routes with subnet set to 1000 captures two to five times fewer unnecessary addresses than the old mix mode at the same number of lines. This is the core of the tool's value: a list of individual host addresses is useless for routing, and a list of overly large subnets is a routing policy you did not intend. Getting the aggregation right is what makes the output safe to apply.
The second is the rate limiting mechanism, which is the part that makes the tool usable at all. There is a global limit across all DNS servers, total_rate_limit, a per-server limit with automatic reduction in frequency on timeouts called rate_limit, and retries for requests the server did not answer. The notes say failures are practically nonexistent as a result, and that scanning becomes faster when one or two servers are chosen.
That last point cuts against the obvious instinct. The tool can query many DNS servers in parallel, and the rate limiting is what stops that from producing garbage. A domain that resolves differently depending on which resolver you ask is a real phenomenon, so querying several and comparing is a feature, but only if the queries are not overwhelming the servers. The global limit and the per-server limit with automatic slowdown are what balance those two requirements.
The third is the reporting change, which is about being honest about the data. Domains without an A record are now separated from actual failures in the report, so a name that genuinely has no address does not look like a lookup that broke. The new progress bar updates continuously, shows the speed, the number of failures and an exact estimate of the remaining time, and adapts to the window width.
Also in this release: the code was reworked into a single domainmapper package with lower memory use, and identical domains from different services are checked once rather than repeatedly.
Output formats and the multiple ways to run it
The tool writes its results in several formats, and the history in the README shows them arriving one at a time from user requests.
The MikroTik format was the first, and it has an option in config.ini to not add a comment naming the service when saving IP addresses in MikroTik format. The Keenetic CLI format followed, then WireGuard, then OVPN, and a Keenetic BAT format for saving, which is the format that needs the file splitting. There is also a separate utility for route conversion, and a set of utilities for searching subdomains.
The aggregation of routes to /24 and /16 was requested separately, and the option to turn off the display of loaded configuration information in config.ini came later, as did passing the configuration file name as a command line argument.
Running it comes in three shapes. It is a Python program with main.py at the root and a domainmapper/ package. For Windows there is a ready-made DomainMapper.exe, so Python is no longer needed, and the old Win.bat launch commands still work and now download the executable. The configuration files are read in both UTF-8 and the Windows encoding. And there is a Docker image built on python:3.12-slim with the results saved to a separate folder.
The Dockerfile shows the layout. The requirements are copied and installed first, then main.py with the platformdb and dnsdb directories, then the domainmapper package and the platforms directory, and the working directory is switched to /data before the entrypoint runs python /app/main.py. That last detail is the one that matters in practice: results land outside the application directory, so they survive a container rebuild.
The split utility was removed, because DomainMapper now divides large files into parts itself.
The Python dependencies are minimal: dnspython 2.6.1 or newer for the DNS work, httpx 0.27.0 or newer, and colorama for terminal colours.
Limits: a snapshot of a moving internet, and a licence to check
The limits are worth stating plainly, because the output of this tool looks authoritative and is not.
The first is that the addresses are a snapshot. A domain resolves to a different set of addresses over time, and the service's own infrastructure changes as it scales, migrates or moves behind a CDN. A list generated today is out of date in a matter of weeks. The tool's design implies this, since the DNS lists refresh twice a month and the upstream domain lists are updated continuously, but the operational implication is that the output has to be regenerated on a schedule and applied on a schedule, and that a list sitting in a router for a year is a list of addresses nobody uses any more.
The second is the resolution point. Which DNS server you query affects what you get back, and the tool supports querying many of them. That is useful for coverage and it is also a source of inconsistency, which the per-server rate limiting and the failure reporting address in part, but not entirely. A domain that answers differently to different resolvers will produce a list that depends on which servers the tool happened to use.
The third is the aggregation trade-off. Merging neighbours without loss is safe but produces many routes, and limiting the route count captures fewer unnecessary addresses but is a coarse approximation that includes addresses the service does not use. The tool offers both and the config lets you choose, which means the choice of policy is yours and each has a cost.
The fourth is the platform list. The output formats cover MikroTik, Keenetic CLI, Keenetic BAT, WireGuard and OVPN, but a format that is not listed is not supported, and the semantics of each format, particularly the subnet notation and the comment syntax, are device-specific in ways the tool cannot fully generalise.
The fifth is the scope of the service list. It covers the services people ask for, and it will never cover everything, which is why the custom DNS list for personal domains exists as an escape hatch.
Finally, the licence question. GitHub records the licence as unknown, and the top-level listing does not show a LICENSE file at all. Before you push the output into a device that routes your traffic, it is worth confirming what you are allowed to do with the tool and with the lists it produces.
This tool against running a public resolver and against a domain-to-IP service
Two comparisons make the choice clearer.
The first is against just using a public DNS resolver directly and copying the answers by hand. The difference in approach is that DomainMapper does the whole population for you: it knows the domain list for each service, queries them across several resolvers, aggregates the results into routes, and writes the file your device understands. For someone maintaining rules for thirty services, that is the difference between a script and an afternoon of copying.
The second comparison is against a hosted domain-to-IP service. The difference is control and cost. A hosted service has the lists and keeps them updated, but it is somebody else's list, it may not cover the services you need, and your traffic and your queries go through an infrastructure you did not choose. DomainMapper is a local script with lists pulled from public upstream repositories, which means you can see what it is resolving and adjust it.
There is also the option the tool itself offers, which is a custom DNS list for personal domains. That is the right escape hatch for anyone who needs a domain the shipped list does not have, and it turns the tool from a fixed catalogue into something you can extend.
The practical framing is that this is a maintenance tool for a specific job. If you need the address list for two services, doing it by hand is faster. If you need it for the services a router configuration carries, then a tool that keeps the lists current and writes the router's own syntax is worth running on a schedule.
Editorial conclusion
Adopt DomainMapper if you maintain router, VPN or firewall rules for blocked services and want the address lists maintained for you rather than hand-written. Do not expect the results to be stable, because a domain resolves to a different set of addresses over time and any static list will age. Verify first that the service you care about is in the supported list, that you run it periodically rather than once, and that your router's format is among the output formats, since the output is configuration you will be pushing into a device that will route real traffic.
Frequently asked questions
What does DomainMapper do?
It is a Python tool that resolves the domain names of popular web services into IP addresses and saves them as ready-made routes or lists for routers, VPNs and operating systems. It also aggregates neighbouring addresses into routes, optionally filters Cloudflare addresses, supports many output formats, and splits large files into parts for the Keenetic BAT format.
How does DomainMapper avoid breaking the DNS servers it queries?
The recent rework introduced a new request limiting mechanism: a global limit across all DNS servers called total_rate_limit, a per-server limit called rate_limit that automatically reduces its frequency when timeouts occur, and retries for requests a server did not answer. The release notes say failures are practically nonexistent as a result.
Which output formats and DNS servers does DomainMapper support?
Output formats include MikroTik, Keenetic CLI, Keenetic BAT, WireGuard and OVPN, with a separate route conversion utility and subdomain search utilities. The DNS servers are chosen by number in config.ini, ranging from the system resolver through Google Public DNS, Quad9, Cloudflare, OpenDNS, AdGuard DNS without filtering, Control D without filtering, CleanBrowsing with the security filter, UltraDNS Public, NextDNS and Yandex DNS. The service domain lists refresh twice a month from upstream community repositories.
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/ground-zerro-domainmapper)Was this useful?