Open-Domain
Wildcard DNS for IP addresses. Free, stateless, open source.
Serving since 1 August 2026. Both suffixes resolve through the public DNS hierarchy. One caveat, stated plainly: they are answered by one resolver on one machine, so a failure there takes both down at once. A second nameserver in a separate location is the next piece of work.
If your use is production-critical today, nip.io and sslip.io have run this for over a decade on more machines than we have.
Open-Domain is a DNS service that, when queried with a hostname that has an IP address embedded in it, returns that IP address. Append .a-i.st to an IP and you have a working hostname — no signup, no API key, no dashboard, and nothing to wait for.
Every answer is computed from the query name itself. There is no database and no stored record: 203.0.113.10.a-i.st resolves to 203.0.113.10 because the name says so.
The service is designed around two domains, a-i.st and a-i.sh, which are interchangeable — the same name works under either. They are separate registrations, so a problem at one registry or registrar does not reach the other.
That protects against a registry problem and nothing else. Both suffixes are answered by one resolver on one machine today, so they fail together. Independent nameservers in separate locations are the next piece of work, and until they exist this is a single point of failure — which is the honest reason for the notice at the top.
The two names are also how the delegation holds itself up: a-i.st is served by ns1.a-i.sh and ns2.a-i.st, and so is a-i.sh. Each zone keeps one nameserver inside itself (resolved by a glue record at the registry) and one in the other zone, which satisfies the two-nameserver rule both registries impose without inventing a third domain.
Examples #
| Hostname | Resolves to | Notes |
|---|---|---|
| 203.0.113.10.a-i.st | 203.0.113.10 | dot separators (IPv4) |
| 203-0-113-10.a-i.st | 203.0.113.10 | dash separators — one label instead of four |
| 203.0.113.10.a-i.sh | 203.0.113.10 | the other domain, same answer |
| www.192.168.0.1.a-i.st | 192.168.0.1 | any prefix is ignored |
| www-192-168-0-1.a-i.st | 192.168.0.1 | prefix + dashes |
| 0a000001.a-i.st | 10.0.0.1 | hexadecimal notation (8 digits) |
| 2001-db8--1.a-i.st | 2001:db8::1 | IPv6 — always dashes, never dots |
| foo.bar.a-i.st | NXDOMAIN | no IP address in the name |
| example.com | REFUSED | outside our zones |
Try it:
dig +short 203.0.113.10.a-i.st
dig +short 203.0.113.10.a-i.sh
HTTPS #
Both forms work. A certificate for 5.78.141.213.a-i.st issues exactly as easily as one for 5-78-141-213.a-i.st — verified by issuing a real Let's Encrypt certificate covering both names at once. Use whichever you prefer.
We do not provide a wildcard certificate, and neither do nip.io or sslip.io. You cannot obtain one for *.a-i.st yourself either: Let's Encrypt only issues wildcards through the DNS-01 challenge, and that requires adding a TXT record to a-i.st — which nobody but us can do. So the dashed form buys you nothing on its own. It matters only if someone hands you a wildcard certificate, and nobody does.
Isolation #
Names under a-i.st are not isolated from one another in the browser. The suffix is not on the Public Suffix List, so a browser treats every *.a-i.st name as one site for cookies and same-site checks: a page served at one name can set a cookie scoped to a-i.st that a different name will then send. Use these names for development, previews, CI, and reaching a box by its IP — not for separating untrusted tenants that must never share a cookie jar.
What you get instead is an ordinary certificate for your exact hostname, which is all most people needed anyway. Let's Encrypt will not issue for a bare IP address, but it will for a hostname — and that is what this gives you.
Two practical consequences, both learned the hard way:
- Port 80 or 443 must be reachable from the internet. DNS-01 is impossible for these names, so HTTP-01 or TLS-ALPN-01 is your only route. If something else already owns those ports, that has to be sorted out first.
- Do not proxy
/.well-known/acme-challenge/to your app. A catch-all proxy rule sends the challenge to your application, your application answers with its own page, and issuance fails withunauthorized. Serve that path from disk.
A working nginx fragment:
server {
listen 80;
server_name 5-78-141-213.a-i.st;
location /.well-known/acme-challenge/ { root /var/www/acme; }
location / { proxy_pass http://127.0.0.1:8090; }
}
certbot certonly --webroot -w /var/www/acme -d 5-78-141-213.a-i.st
Certificates are rate-limited per suffix, not per user. Let's Encrypt allows 50 new certificates per registered domain every 7 days, and a-i.st counts as one registered domain for everybody using it. Renewals are exempt, so this bites new names, not existing ones. If you hit the limit, try a-i.sh — it has its own separate allowance.
For agents and automated tools #
The hostname is a pure function of the IP: no lookup, no state, no registration step. An agent that has just been handed a public IP can construct its own address without asking anyone.
Machine-readable copies of everything here, cheaper to parse than this page: /llms-full.txt is a complete self-contained reference, /llms.txt is the short index, and every page has a Markdown mirror — /index.md and /abuse.md.
One caution that matters: do not put secrets in a hostname — every resolver along the path can log the names it sees. Trying the other suffix is worth a retry, but do not treat it as failover: one resolver answers both today, so when one is down the other is down with it.
Run your own #
Most people should use the hosted service — append the suffix and you are done. Running your own is a standing commitment: a domain you own, a host with a static public IPv4, UDP and TCP port 53 reachable, NS delegation with glue records, and someone keeping all of it alive. It is the right choice when your environment cannot depend on a third party, or when you need your own domain in the name. Otherwise the hosted service saves you the job — and the source below is here so that staying with it is a choice, not a trap.
The resolver is a zero-dependency Node program. One process can be authoritative for any number of zones:
git clone https://github.com/kwkuh/open-domain
cd open-domain
npm test
ZONES=example.dev,example.test \
NS_HOSTS=ns1.example.dev,ns2.example.dev \
PORT=15353 BIND=127.0.0.1 BIND6=::1 \
node src/server.js
dig +short -p 15353 @127.0.0.1 1.2.3.4.example.dev
Each zone gets its own SOA and apex, and the longest matching zone wins. Always set NS_HOSTS to your own nameservers — it defaults to ours, so a zone left without it will tell the world to ask ns1.a-i.sh. BIND controls IPv4 only; set BIND6 as well (or BIND6="" to switch IPv6 off), since it otherwise listens on every IPv6 interface. To serve the public internet you need a host with a static IPv4 address and UDP and TCP port 53 reachable, then delegate NS and glue records to it. Configuration is all environment variables: ZONES, PORT, BIND, BIND6, NS_HOSTS, APEX_IP, TTL, DEBUG.
If a name does not resolve #
NXDOMAIN looks the same for three very different causes. Tell them apart in one step: run dig a-i.st SOA. If the SOA answers, the service is up and the problem is the name; if it does not, the problem is us.
- The name is not a valid IP encoding.
hello.a-i.sthas no address in it and is NXDOMAIN by design. Check the form: dotted (1.2.3.4.a-i.st), dashed (1-2-3-4.a-i.st), or eight hex digits. - Your resolver blocks private IPs. Many resolvers and routers have DNS-rebinding protection and refuse to return
10.x,192.168.x, or127.x. That is your resolver, not this service — nip.io and sslip.io hit the same wall. - The service is down. The one case the
SOAcheck above confirms.
Reliability #
This is community-run infrastructure offered as a public good, with no SLA. It is meant for development, previews, demos, CI, and giving ephemeral machines an address. It is not meant to sit in the critical path of a production system that depends on a free third party — for that, run your own from the source above, on a domain you control. That the code is MIT-licensed and trivially self-hostable is the point: there is nothing to be locked into.
Abuse #
A free wildcard DNS service gets misused, and we would rather hear about it. Report a hostname to abuse@open-domain.com and we will act on phishing, malware, and command-and-control. What we can do is stop an address from resolving under our suffixes; what we cannot do is remove content we never hosted, or tell you who used a name, because query logs truncate the client address before writing it (see privacy). The abuse page explains both sides plainly, including how to reach the host directly — which is usually faster than reaching us.
Sponsor #
Open-Domain is free and intends to stay free. Running authoritative nameservers costs something; keeping the service stateless keeps that cost small, and sponsors cover the rest.