Free nip.io and sslip.io subdomains – 2026 - EN
Published: 2026-09-18
Introduction
Almost every developer has hit the same wall: you have a machine with an IP address, but no domain name. It might be a laptop running a web app you want to debug locally, a test server floating behind a plain IPv4 address, or a cloud VM that never got a friendly hostname. Without a domain name you cannot obtain a valid TLS certificate, you cannot reach your service by a memorable name, and you end up fighting cookies, mixed content and environment configuration.
nip.io and its successor sslip.io solve the problem in a deceptively simple way: the IP address is embedded straight into the hostname. Query 64.176.22.9.nip.io and the DNS reply contains exactly 64.176.22.9. No registration, no control panel, no per-host limits. The service behaves like a wildcard DNS and answers any name that contains a well-formed IP address.
Over more than a decade, this trick became an industry standard for development and testing. Official documentation from Google Cloud Platform (Knative Serving), Amazon Web Services (EKS and Teleport), Microsoft Azure (AKS autoscaling), IBM Redbooks and AMD Enterprise AI all reference nip.io. The service reports roughly 29,000 DNS queries per second across its three public nameservers in 2026, and the total number of answers served is measured in tens of billions.
This article is a practical, hands-on walkthrough: how nip.io and sslip.io work internally, which hostname formats are supported, how to use them with real projects, how to get free TLS certificates, how to bring the same behavior to your own domain (white-label), how to run the open-source DNS server yourself, and how the service compares with alternatives such as traefik.me, backname.io and xip.io.
How the trick works
DNS in a nutshell
The Domain Name System translates human-friendly names such as google.com into IP addresses. When you open a website, your browser asks a recursive resolver (usually your ISP's DNS or a public one like 8.8.8.8), and the resolver in turn contacts the authoritative nameservers that own the zone. Those authoritative servers are the source of truth for their domain: they answer A (IPv4), AAAA (IPv6), NS, SOA, MX, TXT, CNAME and other record queries.
nip.io acts exactly as such an authoritative nameserver — but only for the zones nip.io and sslip.io. It is not a recursive resolver. It will not resolve google.com for you. Its only job is to accept a query for a hostname that carries an IP address, extract the address from the name, and return it.
The core trick: an IP inside a hostname
DNS names can contain letters, digits, hyphens and dots. The dot is the delimiter between labels, which is exactly why the original "127.0.0.1" style encoding is awkward: dotted names create extra suffix lookups. The hyphenated form 192-168-0-1.nip.io reads like an ordinary hostname, yet the server recognizes 192-168-0-1 as the encoded IPv4 address 192.168.0.1.
IPv6 uses the same idea: colons are not allowed inside DNS labels, so they are replaced with hyphens, and the group of zeros :: becomes a double hyphen --. Loopback ::1 is written --1, and Google's public DNS 2001:4860:4860::8888 becomes 2001-4860-4860--8888.
Inside the Go server
The current sslip.io server is written in Go (module xip, Go 1.25) and is remarkably compact. All real logic lives in two files:
main.go— the network layer: reading UDP and TCP packets on port 53, reading queries, writing responses, dnstap integration.xip/xip.go— the DNS logic: name parsing, IP extraction, blocklist, response building, customizations, metrics.
The server has exactly one external runtime dependency — golang.org/x/net's dns/dnsmessage package, used to parse and build DNS packets in wire format. Everything else comes from the Go standard library. Even dnstap (a protobuf-based DNS telemetry streaming protocol) is implemented by hand, with custom varint encoding and no external protobuf library.
The request path looks like this:
UDP/TCP packet → dnsmessage parser → processQuestion() ├── A → String2IPv4() + blocklist check + A record ├── AAAA → NameToAAAA() + blocklist check + AAAA record ├── NS → rotating nameserver list + glue records ├── SOA → MNAME = name from the request ├── TXT → only from customizations (SPF, DMARC, version, metrics) ├── PTR → in-addr.arpa / ip6.arpa parsing ├── MX → ProtonMail (for nip.io/sslip.io) or the name itself ├── CNAME → static customizations only (DKIM) └── ANY → NOTIMP reply (RFC 8482) → response assembled with dnsmessage.Builder → sent back to client
How IPv4 is extracted
The function String2IPv4 tries three regular expressions in strict priority order:
- Hyphenated form: four decimal octets separated by hyphens, e.g.
192-168-1-1. Hyphens are replaced with dots to produce a valid IPv4 address. - Dotted form: the classic
127.0.0.1style. Fully supported but treated as the less preferable encoding. - Hex form: exactly eight hexadecimal digits, e.g.
7f000001, decoded into four bytes. So7f000001.nip.iois 127.0.0.1 and40B01609.nip.iois 64.176.22.9. Hex notation is case-insensitive:ffffFFFF.nip.ioyields 255.255.255.255.
The priority rule is "hyphens beat dots, dots beat hex". If a name contains several IP-looking strings, the one chosen by this order wins — the unit tests explicitly assert all three pairwise priorities.
There are also strict formatting rules. Octets above 255 are rejected. Octets with leading zeros (such as 09) are rejected. And service names like ns-01.nip.io, which contain a hyphen but not four octets, are correctly distinguished from embedded IP addresses.
How IPv6 is extracted
Two notations are supported for IPv6:
- Hyphenated notation: one large regular expression covering all nine possible
::compression variants, IPv4-mapped addresses (::ffff:1.2.3.4) and link-local addresses with zone IDs (like fe80--...%en0). Hyphens become colons, then the address is normalized through net.ParseIP. - Hex-dot notation: exactly 32 hexadecimal digits separated by dots, e.g.
2001.0db8.0000.0000.0000.0000.0000.0001. Only dot separators are allowed in the hex form.
The server also provides reverse DNS. Querying 1.0.0.127.in-addr.arpa returns 127-0-0-1.nip.io (or whichever domain is configured via -ptr-domain), and IPv6 reverse lookups in ip6.arpa are supported the same way.
Edge-case behavior
The authors paid attention to corner cases:
- When a packet carries multiple questions, only the first is answered — the de-facto standard and fully compatible with how DNS clients behave.
- Replies always carry RecursionAvailable = false. The server deliberately refuses to work as an open resolver.
- Authoritative answers are flagged Authoritative. The only exception is delegation (DNS-01 challenges), where the response is built in the AUTHORITY section.
- NS records rotate every second: the order of nameservers in the reply changes to spread load across the three nodes without any load balancer.
- Glue A and AAAA records for every nameserver are added to the ADDITIONAL section so clients can connect immediately.
Supported DNS record types
The behavior for every query type is strictly defined and covered by tests.
| Record type | Supported | Behavior |
|---|---|---|
| A | Yes | Extract IPv4 from the name: hyphens, dots or hex; blocklist check; TTL 3600 for dynamic names |
| AAAA | Yes | Extract IPv6 in hyphen or hex-dot notation; blocklist check; TTL 3600 |
| NS | Yes | Returns the three nameservers, rotating order every second; A/AAAA glue added in ADDITIONAL |
| SOA | Yes | MNAME equals the queried name, serial 20260704; used both as a direct answer and as a negative answer in AUTHORITY |
| TXT | Partially | Only from customizations: SPF, DMARC, server version, metrics, requester IP detection; TTL 180 |
| PTR | Yes | Reverse DNS for IPv4 (in-addr.arpa) and IPv6 (ip6.arpa) — returns the hyphenated name under the PTR domain |
| MX | Yes | For nip.io and sslip.io — ProtonMail records (10 mail.protonmail.ch, 20 mailsec.protonmail.ch); for everything else — the name itself with preference 0 |
| CNAME | Partially | Static customizations only (protonmail._domainkey DKIM records for ProtonMail) |
| ANY | No | NOTIMP reply per RFC 8482 — the same approach Cloudflare uses |
| SRV | No | Missing; unknown types get an empty answer with SOA in AUTHORITY |
The TTL strategy is deliberate:
- Dynamic A/AAAA records for embedded-IP names use a short TTL of 3600 seconds (one hour). If an address needs to be added to the blocklist, old cached records expire quickly.
- Static and customized records (NS, SOA, MX, CNAME) use a long TTL of 604800 seconds (one week).
- TXT records use a short TTL of 180 seconds so SPF, DKIM and DMARC changes propagate fast.
- Sinkhole replies for blocked names use a long TTL of 604800 seconds: a blocked address should stay unreachable.
Built-in customizations
Some answers are hard-coded and matter for email delivery and housekeeping:
- The zones nip.io and sslip.io carry ProtonMail MX records, so mail to those domains cannot be redirected elsewhere.
- SPF is
v=spf1 include:_spf.protonmail.ch mx -all. - DMARC is
v=DMARC1; p=reject— mail failing SPF is rejected by design. - DKIM records for protonmail._domainkey are CNAMEs to ProtonMail.
- The service TXT records version.status and metrics.status expose telemetry.
- The record ip.nip.io (or ip.sslip.io) returns the IP address of whoever asked the question.
- The name blocked.nip.io maps to dedicated A and AAAA records — the sinkhole used for blocked names.
Hostname formats: the full table
The official site documents the following examples. nip.io and sslip.io are fully interchangeable.
| Hostname | Resolves to | Note |
|---|---|---|
| https://64.176.22.9.nip.io | 64.176.22.9 | Dotted form, IPv4 |
| https://64-176-22-9.nip.io | 64.176.22.9 | Hyphenated form, IPv4 |
| www.192.168.0.1.nip.io | 192.168.0.1 | Subdomain before the IP |
| www.192-168-0-1.nip.io | 192.168.0.1 | Subdomain + hyphens |
| https://www-78-46-204-247.nip.io | 78.46.204.247 | Hyphenated prefix before the address |
| --1.nip.io | ::1 | IPv6 — hyphens only, never dots |
| https://2a01-4f8-c17-b8f--2.nip.io | 2a01:4f8:c17:b8f::2 | IPv6 with a zero group |
| https://40B01609.nip.io | 64.176.22.9 | Hex form, IPv4 |
| 7f000001.nip.io | 127.0.0.1 | Hex form of loopback |
| 2001-0db8-0000-0000-0000-0000-0000-0001.nip.io | 2001:db8::1 | Full hyphenated IPv6 |
| fe80--...%zone.nip.io | link-local with zone ID | Special IPv6 case |
The simplest way to test the service is with dig (part of dnsutils / bind-utils):
# Direct query against the public nameserver dig @ns.nip.io 192-168-0-1.nip.io +short # → 192.168.0.1 # The dotted format works too dig @ns.nip.io 192.168.0.1.nip.io +short # → 192.168.0.1 # IPv6 (double hyphen = ::) dig @ns.nip.io --1.nip.io aaaa +short # → ::1 # Reverse DNS dig @ns.nip.io -x 127.0.0.1 # → 127-0-0-1.nip.io # Both zones at once for ip in 10 192-168-0-1; do echo "$ip.nip.io = $(dig +short $ip.nip.io @ns.nip.io)" echo "$ip.sslip.io = $(dig +short $ip.sslip.io @ns.nip.io)" done
One quirk worth knowing: leading hyphens confuse dig, which reads --1.nip.io as a command flag. Use -q to get around it:
dig +noidnout +noidnin -q --1.nip.io aaaa
Another practical recommendation: for IPv4 prefer hyphens (10-9-9-30.nip.io) over dots (10.9.9.30.nip.io). A dotted name forces the resolver to walk the suffix chain (30.nip.io, 9.30.nip.io, 9.9.30.nip.io and so on) before finding the best matching label. The result is roughly twice as many queries to the server. At 29,000 queries per second, that is real traffic, so the authors explicitly recommend hyphens.
Use cases
Local development
The most common scenario is local web development. A classic pain point: the frontend on port 8080 calls an API on another port, and the mixed-content policy makes the browser refuse requests to non-HTTPS resources. localhost-based solutions are limited: the Host header is always "localhost" and some frameworks push back on non-standard names.
nip.io removes the friction: 127.0.0.1.nip.io resolves instantly to 127.0.0.1, and your web server can obtain a real Let's Encrypt certificate for it. You can run many virtual hosts on one machine — app1.127.0.0.1.nip.io, app2.127.0.0.1.nip.io and so on — and each gets its own certificate.
Keep DNS-rebinding protection in mind: some browsers and resolvers refuse names that resolve to private ranges for security reasons. In most environments nip.io with private addresses (127.x, 10.x, 192.168.x) works fine, but if your ISP or corporate DNS blocks it, run your own instance of the server (see below). This is a limitation of the ecosystem, not a bug in the service — it is even documented in the original nip.io repository.
Kubernetes, Knative and clouds
nip.io has become a de-facto standard for dynamic domains in Kubernetes clusters thanks to integration with ingress controllers and services like Knative Serving. Google Cloud's official Knative Serving documentation uses subdomains of the form 10-10-10-10.nip.io as the default domain example. The service also shows up in AWS material (EKS authentication with GitHub credentials via Teleport), Microsoft Azure (autoscaling AKS microservices), IBM Redbooks and AMD Enterprise AI. The pattern is always the same: a cluster that creates services dynamically needs a generic hostname template, and embedding the node's IP is the cheapest universal option.
In Kubernetes it is convenient because service-to-service traffic and ingress access both require stable names. When environments are created dynamically (review apps, feature branches, preview environments), names such as [branch].127-0-0-1.nip.io are generated automatically: unique, and the IP comes from the actual node.
For production dynamic environments, prefer delegating a dedicated zone on your own domain (white-label) and keep nip.io for development, staging and tests.
Reverse proxies
Traefik or Caddy as a local reverse proxy is essentially the service's second native habitat. Here is the canonical Traefik + Docker Compose setup: two test apps reachable as app1.traefik.me and app2.traefik.me from your machine, and app1.10.0.0.1.traefik.me from any device on your LAN:
version: '3'
services:
traefik:
restart: unless-stopped
image: traefik:v2.0.2
command: --providers.docker=true
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/var/run/docker.sock
app1:
image: containous/whoami
labels:
- "traefik.http.routers.app1.rule=Host(`app1.traefik.me`)"
app2:
image: containous/whoami
labels:
- "traefik.http.routers.app2.rule=Host(`app2.traefik.me`)"
Run docker-compose up, open app1.traefik.me in the browser — it just works, with no /etc/hosts editing. To reach a container from your phone or tablet on the same network, add a HostRegexp rule with an IP mask:
- "traefik.http.routers.app1.rule=HostRegexp(`app1.{ip:.*}.traefik.me`)"
Now http://app1.10.0.0.1.traefik.me from any LAN device reaches app1. The identical logic works with the nip.io domain.
Automatic TLS certificates
The main selling point for the modern web is automatic TLS: Let's Encrypt and ZeroSSL both support the HTTP-01 challenge. The web server exposes a temporary file at http://hostname/.well-known/acme-challenge/..., the CA verifies that the hostname actually reaches your server, and issues a certificate. Because 64.176.22.9.nip.io resolves exactly to your IP, everything happens without manual steps.
The most popular tool for this is Caddy, which obtains and renews certificates automatically:
# Caddyfile example for a host with IP 64.176.22.9
64.176.22.9.nip.io {
reverse_proxy 127.0.0.1:8080
}
Caddy will issue a valid Let's Encrypt certificate for 64.176.22.9.nip.io and renew it forever. The same applies to www.64.176.22.9.nip.io, prod.www-64-176-22-9.nip.io and any other combination. Caddy even supports On-Demand TLS — certificates fetched at handshake time — which pairs perfectly with the wildcard-shaped nip.io names.
Reverse DNS for debugging
PTR records are handy when debugging network issues. Querying 1.0.168.192.in-addr.arpa through nip.io nameservers returns 192-168-0-1.nip.io. This enables testing configurations that need a predictable forward/reverse pairing, such as mail servers or test labs. IPv6 reverse lookups in ip6.arpa work the same way.
"Free dynamic DNS"
Because the name literally contains the address, nip.io needs no dynamic DNS update mechanism. Address changes? Rewrite the hostname. This makes it a great way to test host-changing setups without managing DNS zones. For a stable subdomain that must follow a changing IP without renaming it, use afraid.org or ipq.co instead (see Alternatives).
SSH tunnels and VPNs
A less obvious scenario: exposing internal services through a tunnel. Suppose you have a public server and a tunnel to an internal network. Colleagues need a memorable HTTPS URL for an internal web interface, but you do not control the internal DNS zone. On the gateway, run Caddy or nginx that resolves wiki.10-0-0-44.nip.io to the internal 10.0.0.44 and proxies traffic. Internal clients reach the resource through the secured channel, and the certificate is obtained automatically.
CI and test beds
In continuous integration, nip.io domains are commonly used to validate TLS configuration. A pipeline spins up a temporary environment, generates a name from the machine's IP, and runs load or integration tests expecting valid HTTPS. With automatic certificates and no registration, such a bed is up in minutes and leaves no garbage in your organization's DNS.
TLS certificates and Let's Encrypt
Certificates for nip.io/sslip.io hostnames are obtained through the standard Let's Encrypt HTTP-01 flow. The only practical concern is rate limits. The Let's Encrypt history is telling: the CA raised the limit for the service from 50 to 250,000 certificates over the years, but declined 500,000 with the words "This is too large for us to support". For ordinary users, the public per-domain and per-week limits are rarely reached during development.
If a nip.io certificate request hits a rate limit:
- try an IP address certificate (since January 15, 2026 Let's Encrypt offers public IP certificates and shorter-lived six-day certificates);
- try the other domain — if nip.io is rate-limited, use sslip.io;
- use related services (traefik.me, backname.io).
Current IP-address certificates are short-lived (160 hours, just over six days), which fits the transient nature of IP addresses: validation happens more often, reducing the risk of using revoked keys.
Important: nip.io and sslip.io do not support wildcard certificates — you cannot obtain *.nip.io. Every individual hostname is covered by its own certificate. This is a deliberate architectural decision that hardens the ecosystem.
White-label: bring nip.io logic to your own domain
The killer feature of sslip.io is white-labeling: you can "borrow" the technology for your own domain. You do not need the nip.io or sslip.io zones at all — any subdomain, such as xip.mydomain.com, can behave exactly the same way.
The procedure:
- Pick a subdomain, e.g.
nip.mydomain.com. - In your registrar's DNS panel, delegate that subdomain to the service's three public nameservers by setting NS records.
- From then on, requests to
127-0-0-1.nip.mydomain.comautomatically reach the sslip.io servers, which answer 127.0.0.1.
The required nameservers (current as of June 2026; two of the earlier addresses changed, and outdated NS records cause SERVFAIL):
| Hostname | IPv4 | IPv6 | Location |
|---|---|---|---|
| ns-00.nip.io | 167.172.4.236 | 2400:6180:0:d2:0:2:e3e7:0 | Singapore |
| ns-01.nip.io | 5.78.28.211 | 2a01:4ff:1f2:10d:: | USA |
| ns-ovh.sslip.io | 51.75.53.19 | 2001:41d0:602:2313::1 | Poland |
Verify delegation with dig, explicitly naming the nameserver:
dig @ns-ovh.nip.io. 169-254-169-254.nip.example.com +short # → 169.254.169.254
A loud warning from the operators (June 2026): white-label users must update their nameservers. Two nameserver hostnames and addresses changed, and anyone who has not updated gets SERVFAIL responses.
Also note: these nameservers are not recursive resolvers. Never point your OS DNS at them — they only serve zones with embedded IP addresses.
Organizations wanting full control should run their own server instance with -public=false, which eliminates the phishing risk of public IP addresses on their own domain.
Running your own DNS server
The open architecture means you can run your own instance — useful for air-gapped networks, testing, and organizations that do not want external dependencies. The tool is fully standalone: it needs no internet access, and its addresses, NS records and PTR domain are set via flags.
Quick start from source
git clone https://github.com/cunnie/sslip.io.git cd sslip.io go mod tidy sudo go run . # sudo is required for port 53
In another terminal:
dig @localhost 192.168.0.1.sslip.io +short # → 192.168.0.1
Docker
The official image is cunnie/sslip.io-dns-server. It is multi-platform (linux/amd64 and linux/arm64 — AWS Graviton, Apple M1/M2) and roughly 141 MB. To run without root, remap the port:
docker run -d --rm -p 3353:53/udp cunnie/sslip.io-dns-server # test: dig @localhost 127-0-0-1.sslip.io -p 3353 +short
Pre-built binaries
The project publishes precompiled binaries for darwin, linux and freebsd (amd64 and arm64) plus windows (amd64) on the releases page. Even the production infrastructure uses them: cloud servers download the 5.1.5 binary from GitHub Releases at deploy time.
Flags at a glance
The complete flag reference lives in the README. The most useful ones:
| Flag | Default | Description |
|---|---|---|
| -port | 53 | UDP/TCP port. Low ports require root |
| -nameservers | ns-00.nip.io, ns-01.nip.io, ns-ovh.sslip.io | FQDN list for NS records |
| -addresses | empty | "host=IP" pairs for custom A/AAAA records (multiple addresses per host allowed) |
| -blocklistURL | https://raw.githubusercontent.com/cunnie/sslip.io-blocklist/main/blocklist.txt | Blocklist URL; file:// protocol supported |
| -delegates | empty | Delegate subdomains to external nameservers (e.g. for DNS-01 challenges) |
| -ptr-domain | nip.io. | Domain used for PTR answers |
| -public | true | Resolve public addresses. With -public=false only private addresses resolve |
| -quiet | false | Disable per-request logging (saves money on Cloud Logging in GKE) |
| -dnstap | empty | Unix or TCP socket address for dnstap telemetry streaming |
Running your own nameservers for a subdomain xip.pivotal.io with custom NS and address records:
go run main.go \ -nameservers=ns-ip-0.pivotal.io,ns-ip-1.pivotal.io \ -addresses ns-ip-0.pivotal.io=10.8.8.8,ns-ip-1.pivotal.io=fc88:: \ -ptr-domain=xip.pivotal.io
A query for the zone xip.pivotal.io (dig ns 127.0.0.1.com @localhost -p 5553) then returns the NS records ns-ip-0.pivotal.io and ns-ip-1.pivotal.io together with glue records.
systemd deployment
A ready-made unit file etc/sslip.io-dns.service ships in the repository. In production, every machine gets a service with unique -nameservers and -addresses flags baked into cloud-init:
[Unit] Description=sslip.io DNS Server After=network.target [Service] ExecStart=/usr/bin/sslip.io-dns-server \ -nameservers=ns-00.nip.io.,ns-01.nip.io.,ns-ovh.sslip.io. \ -addresses=nip.io=78.46.204.247,sslip.io=78.46.204.247,... Restart=on-failure RestartSec=5 [Install] WantedBy=multi-user.target
How the production service is run
Three continents, five providers
The production architecture is deliberately resilient: the three authoritative nameservers run on different cloud providers on different continents. If one cloud vanishes, the other two keep serving the zone. A separate "blocked" server serves the shadow page for blocked domains, and a dedicated VM collects dnstap telemetry.
| Server | Provider | Location | Notes |
|---|---|---|---|
| ns-00.nip.io | DigitalOcean | Singapore | Droplet s-2vcpu-4gb, Fedora |
| ns-01.nip.io | Hetzner Cloud | Oregon, USA | cpx31 |
| ns-ovh.sslip.io | OVH | Warsaw, Poland | Dedicated server |
| blocked.nip.io | Vultr | São Paulo, Brazil | Serves the shadow page for blocked domains |
| dnstap.nono.io | Proxmox (homelab) | USA | dnstap collector, ClickHouse analytics |
Provider choices are pragmatic: DigitalOcean covers Asia, Hetzner offers a sane US price, OVH gives cheap and powerful Europe, and Vultr is the cheapest option for "rough" infrastructure. Every PoP has IPv4 and IPv6.
The blocked server's history is instructive: it lived on AWS for $139.16/month, and after moving to Vultr in July 2026 costs dropped to $10/month while bandwidth grew from 2 to 3 TB and disk from 55 to 150 GB.
Infrastructure as code
Everything is described as code with OpenTofu (the open-source Terraform fork) and cloud-init. Each provider has its own directory — terraform/ns-00, terraform/ns-01, terraform/ns-ovh, terraform/blocked, terraform/dnstap — with its own state. Cloud-init installs the packages (~30: Go toolchain, dig, editors), creates the user, writes the systemd unit and downloads the binary.
The per-provider READMEs honestly document the "gotchas": DigitalOcean Terraform is "a mess" (no Fedora 44 image, backup IPs must be assigned by hand), Hetzner floating IPs do not disappear on tofu destroy, OVH consumer keys live only 30 days. Such candid documentation is rare and valuable for anyone repeating the exercise.
Zero-downtime updates
Releases are semi-automatic and careful. Binaries are built for eight platforms, a full regression suite runs against a local server, and then the binary is uploaded to the servers one at a time, each restarting individually. After every restart, the version is verified via a TXT query to version.status.sslip.io. This rolling deploy avoids a single second of downtime. Every six hours an automated smoke test (GitHub Actions) checks the live nameservers: RDAP consistency, IPv4/IPv6 reachability, UDP and TCP operation, and key answers.
Live performance numbers
The live metrics published through DNS give precise load figures. A typical snapshot from one node:
- 58,116,774 total queries processed since startup, about 4169 queries per second on that node.
- 58,259,316 queries over UDP and only 457 over TCP — UDP dominates.
- About 18.2 million replies containing A/AAAA and other records (~1308/s), roughly a quarter of all queries.
- 15.6 million A records and 120 thousand AAAA records issued.
- Exactly 13,421 replies were sinkholed (blocked).
- The blocklist was auto-updated and contained 3773 CIDR ranges, 2 single IPs and string masks.
The quarter-of-traffic spent on "empty" answers comes from duplicated A/AAAA queries and dotted-suffix chains mentioned earlier.
Scale and live metrics
What "big" means here
As of 2026 the public service handles roughly 29,000 queries per second across the three nodes. The Queries/sec badge on the front page refreshes automatically every six hours from live metrics. Traffic is almost entirely UDP; the TCP share is a fraction of a percent.
Metrics over DNS
A unique feature is dogfooding telemetry into DNS itself. The server exposes service TXT records anyone can query:
- server version: version.status.nip.io — semantic version (e.g. 5.1.5), build date and git hash;
- requester IP: ip.nip.io — returns the IP of whoever asked;
- server metrics: metrics.status.nip.io — uptime, blocklist update time and size, total requests and QPS, UDP/TCP split, answers-with-records count, per-type counters, blocked-query count and DNS-01 delegation count.
Query metrics with:
dig @ns-ovh.nip.io metrics.status.nip.io txt +short
To prevent metrics being abused to amplify DNS (the metrics reply is much larger than the query), the server caps metric responses at roughly four per second.
Performance engineering
One of the neatest code-level optimizations concerns the blocklist. Of 746 incoming CIDR records, 744 were single /32 addresses. The developers converted them into a plain string-keyed map, cutting per-query processing time by about 11% (replace ~0.25 seconds with something negligible).
Experimental features
Three experimental features are documented at https://nip.io/experimental.html. The authors warn: experimental features may change; do not depend on them.
Look up your external IP over DNS
The service can tell you your own public IP with a DNS query, modeled on Google's o-o.myaddr.l.google.com:
dig @ns.nip.io txt ip.nip.io +short # returns your public IP dig @ns.nip.io txt ip.nip.io +short -4 # force IPv4 dig @ns.nip.io txt ip.nip.io +short -6 # force IPv6
The catch: you must specify @ns.nip.io; otherwise your resolver answers and you get the resolver's IP, not yours. The advantage over HTTP services like icanhazip.com is drastically less traffic: a DNS query costs about 594 bytes over two packets, while an HTTP request to icanhazip.com costs ~8692 bytes over 34 packets — more than 14 times worse. For mobile users and scripts polling their IP regularly, that is a real saving.
Server version
dig @ns-ovh.nip.io version.status.nip.io txt +short # "5.1.5" # "build date" # "git hash"
Fun detail: build date and git hash can differ between nodes — a normal artifact of the rolling deploy.
Metrics
dig @ns-ovh.nip.io metrics.status.nip.io txt +short
Returns a list of TXT records: uptime, blocklist state, cumulative counters and processing rate.
Telemetry and dnstap
Beyond public TXT metrics, the server can stream full DNS telemetry via dnstap. Enable it with the -dnstap flag pointing at a Unix or TCP socket. Production runs a dedicated VM, dnstap.nono.io, on a home Proxmox server running:
- DNS-collector (go-dnscollector v2.5.0) — accepts the dnstap stream over TCP 6000;
- ClickHouse — the columnar database accumulating a record per query (identity, queryip, qname, operation, family, protocol, qtype, rcode, timestamps);
- ZFS-backed storage for analytic data.
This lets operators answer questions like "which domains are requested most", "who asks about ip.sslip.io" and "which clients generate the most queries". The team even publishes public documents on analyzing journald logs with simple cut/awk pipelines.
Security: blocklist, sinkhole and amplification protection
A layered blocklist
To fight phishing sites living on nip.io domains, the service uses an automatically updated blocklist, downloaded from GitHub every 60 minutes. If the download fails, the server logs an error and keeps serving. The blocklist has three levels:
- CIDR ranges: whole subnets, including providers with poorly protected servers.
- Individual IP addresses: singles held in a fast map structure.
- Substring masks: block by substring inside the hostname (e.g. the bank name "raiffeisen" in
raiffeisen.94.228.116.140.nip.io).
The blocking logic is subtle: only names containing a valid IP are ever blocked. Private addresses (RFC 1918/4193) are never blocked. If a record hits the blocklist, the server replies with the "shadow" address blocked.nip.io (64.176.22.9), and the name resolves to a warning page saying the site was disabled for abuse.
blocked.nip.io and abuse reporting
Anyone opening a blocked domain in a browser lands on the mobile-friendly blocked.nip.io page explaining the site was taken down for phishing or abuse. The page server lives in São Paulo and was scaled several times in 2026: bandwidth went from 2 to 3 TB, disk grew to 150 GB.
The front page carries an abuse section: send reports to abuse@nip.io, and the operators commit to responding within 24 hours. This matters — free wildcard domains attract abusers, and a transparent reporting process lets the community keep the service clean.
The -public=false mode
Owners of their own zones are advised to run the server with -public=false. In this mode only private addresses resolve: 10/8, 172.16/12, 192.168/16, 127/8, 169.254/16, CGNAT 100.64/10, IPv6 fd00::/8 (fc00::/7), loopback ::1, link-local fe80::/10 and other service ranges. Public IPs do not resolve at all. Why does this matter? A phisher can rent a VM with a public IP, get a hostname like 52-0-56-137.ip.wellsfargo.com (if your subdomain is ip.wellsfargo.com) and use it to phish your customers. With -public=false that scenario is impossible. As a bonus, private addresses never enter the blocklist and always resolve.
DNS amplification protection
The server always answers with RecursionAvailable=false and refuses to act as an open resolver, so it cannot be used to amplify DDoS attacks. Heavy TXT answers (metrics) are additionally rate-limited: a buffered channel of 200 tokens with a 250 ms pause keeps throughput near four requests per second.
DNS-01 challenges and delegation
The server handles _acme-challenge.name.nip.io queries by answering with an NS delegation to the embedded IP. This lets automated tools obtain certificates via the DNS-01 challenge — but only when you run your own instance (the mechanism is enabled with the -delegates flag). Wildcard subdomains are not supported on the nip.io/sslip.io zones, though the architecture leaves room for them.
Alternatives and comparison
Let us line nip.io/sslip.io up against the rest of its class.
| Service | Technology | Status | Highlights |
|---|---|---|---|
| nip.io / sslip.io | Go, since 2012/2015 | Active | 29,000 q/s, IPv4/IPv6/PTR, white-label, open DNS server |
| xip.io | bash | Defunct | The historical origin of the idea |
| traefik.me | Python + PowerDNS | Active | Direct descendant of the original nip.io backend; IP-in-name and hyphens supported |
| backname.io | Go (Miek Gieben's DNS library) | Active | Modern Go implementation; IPv6 with dots and dashes |
| afraid.org | Proprietary | Active | Full dynamic DNS, subdomain and domain hosting, no IP embedding |
| ipq.co | Proprietary | Active | "The tinyurl of the DNS world" — short redirect links without IP embedding |
Which one to pick:
- Embed an IP, get TLS, do local development — nip.io/sslip.io.
- A stable subdomain that survives IP changes — afraid.org or ipq.co.
- Your own server, full control, air-gapped — a private sslip.io instance or traefik.me on your own hardware.
- Minimal friction on a Python stack — traefik.me, or the original nip.io backend.
Let's Encrypt deserves an honorable mention as the enabler: it is the reason nip.io is nearly indispensable for instant TLS. You can support it with a donation at abetterinternet.org.
FAQ
Can I use nip.io in production?
Yes — big companies like Google, AWS and Azure reference these domains in documentation and infrastructure. But if you need maximum stability and control over security policy, delegate your own subdomain (white-label) or run your own server instance.
Why does 192.168.0.1.nip.io not resolve for me?
Most likely DNS-rebinding protection in your resolver or browser, or blocking by your ISP. Query directly — dig @ns.nip.io 192-168-0-1.nip.io +short — and if needed run a local server instance.
Which format is better for IPv4 — dots or hyphens?
Hyphens. The dotted format generates roughly twice the queries because of suffix lookups.
Can I get a wildcard certificate for *.nip.io?
No. Neither nip.io nor sslip.io issues wildcard certificates. Every hostname gets its own valid certificate.
How do I find my external IP over DNS?
dig @ns.nip.io txt ip.nip.io +short — the service returns your public IP. Do not forget @ns.nip.io.
Is it free?
Yes, the service is entirely free and funded out of the operators' pockets. Donations to Let's Encrypt and abuse reports are the best form of support.
What is the difference between nip.io and traefik.me?
Functionally almost none — both support IPv4 embedding with dots and hyphens. The differences are the stack (Go vs Python/PowerDNS) and that sslip.io additionally handles PTR, white-label and ships an open Go core for self-hosting.
What is DNS-rebinding protection and does it break nip.io?
It is a protective mechanism in resolvers and browsers that blocks names resolving to private ranges, so an attacker cannot attack a victim's internal services through shared DNS. For private addresses (127.x, 10.x, 192.168.x) it can interfere with local development: some providers answer such queries with an error. The solution is your own server instance or a public resolver without such filters. This limitation is documented in both projects and is not a bug in the service.
Where do the 29,000 queries per second come from?
From the service's open metrics. Every six hours an automated script queries metrics.status.sslip.io on all three nameservers, sums the reply rates and updates the badge on the front page. You can verify the numbers yourself with the dig commands above.
Summary
Fourteen years of nip.io and sslip.io prove that a simple idea can become an industry standard. Embed an IP address in a DNS name and return it in the answer — that mechanic quietly powers thousands of Kubernetes clusters, local setups and CI pipelines worldwide. The project's history is equally instructive: created solo in 2012, outliving its founder, the nip.io domain passed to the community and today, together with sslip.io, serves over 29,000 queries per second from three continents.
Key takeaways:
- The service is free, needs no registration, and supports hyphen, dot and hex formats for IPv4 plus hyphen and hex-dot formats for IPv6.
- The killer scenario: automatic Let's Encrypt TLS for IP-embedded hostnames (Caddy does it in one line of config).
- White-label works: delegate a subdomain to the three public nameservers and get nip.io behavior on your own domain.
- A fully open Go implementation (Apache 2.0) can run locally, in Docker or in an air-gapped network, with PTR, blocklist, security modes and dnstap telemetry.
- Prefer hyphenated IPv4 — the dotted form costs twice the queries.
- Wildcard certificates are not supported, but every individual hostname gets a valid certificate.
- The economics are impressive: a service doing tens of thousands of queries per second costs operators pocket change thanks to clever provider choices and IaC.
If you develop locally, run Kubernetes, or use Caddy — nip.io/sslip.io is probably already inside your toolchain, possibly without you noticing. Now you know how it works under the hood, how to tame it, and how to run your own instance.
References
- Official nip.io / sslip.io website
- sslip.io source code on GitHub
- Original nip.io backend (Python + PowerDNS)
- Releases and pre-built DNS server binaries
- Docker image cunnie/sslip.io-dns-server
- Google Cloud docs: default domain in Knative
- AWS blog: EKS authentication with Teleport
- Microsoft Azure blog: autoscaling AKS microservices
- IBM Redbooks: cloud infrastructure deployment
- Let's Encrypt documentation: rate limits
- Let's Encrypt: IP address certificates announcement
- Caddy web server with automatic TLS
- Related service traefik.me
- Related service backname.io
- Free DNS hosting afraid.org
- Short DNS links ipq.co
- Support Let's Encrypt
