← all posts

DNS 101 for self-hosters

beginnerdnsnetworkingcloudflare

If you’ve ever wondered how blog.debnerd.in finds your server, this post is for you. We’ll cover DNS concepts you need to understand to make your self-hosted services reachable by name — with real examples from my setup.

Update (Sep 2026): my stack has since moved (Azure VPS, Pangolin proxy, *.cloud.debnerd.in names) — the concepts below are unchanged, but treat the hostnames and IPs as examples, not my live config.

1. What DNS actually does

DNS (Domain Name System) is the internet’s phone book. It turns human-readable names into machine-readable IP addresses.

When you type blog.debnerd.in in your browser:

  1. Your device asks a DNS resolver: “what’s the IP for this name?”
  2. The resolver queries DNS servers to find the answer
  3. It gets back: 203.0.113.5 (my VPS’s IP)
  4. Your device connects to that IP

Without DNS, you’d have to remember and type IP addresses directly — impossible for daily use.

2. Common DNS record types

A record

Maps a name to an IPv4 address.

  • blog.debnerd.in. A 203.0.113.5
  • Used for IPv4-only services

AAAA record

Maps a name to an IPv6 address.

  • blog.debnerd.in. AAAA 2400:6180:100:d0:0:1:6d24:e001
  • Used for IPv6 (my VPS has both A and AAAA)

CNAME record

Creates an alias from one name to another.

  • blog.debnerd.in. CNAME d3b-0x0.github.io.
  • Says: “to find blog.debnerd.in, look up d3b-0x0.github.io instead”
  • Common for GitHub Pages, etc.

TXT record

Holds arbitrary text. Used for verification and configuration.

  • git.debnerd.in. TXT brevo-code:abc123 (email verification)
  • _dmarc.git.debnerd.in. TXT v=DMARC1; p=none (email security)

3. How subdomains reach your VPS

Here’s how searx.debnerd.in gets to my SearXNG container:

  1. You type searx.debnerd.in in your browser
  2. DNS query goes to Cloudflare (my DNS provider)
  3. Cloudflare returns:
    • A record: searx.debnerd.in. A 203.0.113.5
    • AAAA record: searx.debnerd.in. AAAA 2400:6180:100:d0:0:1:6d24:e001
  4. Your device connects to one of those IPs (usually tries IPv6 first)
  5. The packets arrive at my VPS’s public IP
  6. My firewall (DO Cloud Firewall) allows the connection (port 443 open)
  7. Caddy (listening on port 443) sees the hostname searx.debnerd.in
  8. Caddy forwards the request to searxng-core:8080 over the Docker network
  9. SearXNG processes the search and returns results
  10. Caddy sends the response back to your device

4. Cloudflare: registrar, CDN, and DNS

I use Cloudflare for three things:

Domain registrar

  • I bought debnerd.in through Cloudflare
  • They handle renewal and WHOIS privacy

Authoritative DNS

  • Cloudflare hosts the DNS records for debnerd.in
  • When the world asks “what’s the IP for searx.debnerd.in?”, Cloudflare answers

CDN (optional, per-record)

This is the proxy status — orange cloud vs grey cloud in Cloudflare DNS:

Proxied (orange cloud):

  • Traffic goes: visitor → Cloudflare edge → your VPS
  • Cloudflare hides your VPS’s real IP (shows Cloudflare IPs instead)
  • Provides DDoS protection, caching, SSL/TLS
  • Used for: my GitHub Pages sites (aboutme.debnerd.in, blog.debnerd.in)
  • Not used for: self-hosted services (would break CrowdSec IP detection)

DNS-only (grey cloud):

  • Traffic goes: visitor → Cloudflare DNS → your VPS (direct)
  • Cloudflare only answers DNS queries; doesn’t proxy traffic
  • Used for: all my self-hosted services (searx, tools, vault, git, etc.)
  • Required for: CrowdSec to see real visitor IPs (not Cloudflare IPs)

5. Real example: my DNS zone

Here are the actual records I use for self-hosted services (all DNS-only):

searx.debnerd.in.     A   203.0.113.5
searx.debnerd.in.     AAAA 2400:6180:100:d0:0:1:6d24:e001
tools.debnerd.in.     A   203.0.113.5
tools.debnerd.in.     AAAA 2400:6180:100:d0:0:1:6d24:e001
vault.debnerd.in.     A   203.0.113.5
vault.debnerd.in.     AAAA 2400:6180:100:d0:0:1:6d24:e001
git.debnerd.in.       A   203.0.113.5
git.debnerd.in.       AAAA 2400:6180:100:d0:0:1:6d24:e001
headscale.debnerd.in. A   203.0.113.5
headscale.debnerd.in. AAAA 2400:6180:100:d0:0:1:6d24:e001
console.debnerd.in.   A   203.0.113.5
console.debnerd.in.   AAAA 2400:6180:100:d0:0:1:6d24:e001
uptime.debnerd.in.    A   203.0.113.5
uptime.debnerd.in.    AAAA 2400:6180:100:d0:0:1:6d24:e001
dash.debnerd.in.      A   203.0.113.5
dash.debnerd.in.      AAAA 2400:6180:100:d0:0:1:6d24:e001
beszel.debnerd.in.    A   203.0.113.5
beszel.debnerd.in.    AAAA 2400:6180:100:d0:0:1:6d24:e001

And for my GitHub Pages sites (proxied):

aboutme.debnerd.in.   CNAME   d3b-0x0.github.io.
blog.debnerd.in.      CNAME   d3b-0x0.github.io.

6. How I verify DNS is working

# Check what Cloudflare serves for a name
dig @1.1.1.1 searx.debnerd.in +short
# Should return both A and AAAA records

# Check specifically for A record
dig @1.1.1.1 searx.debnerd.in A +short
# Should return: 203.0.113.5

# Check specifically for AAAA record
dig @1.1.1.1 searx.debnerd.in AAAA +short
# Should return: 2400:6180:100:d0:0:1:6d24:e001

# Check CNAME for GitHub Pages
dig @1.1.1.1 aboutme.debnerd.in CNAME +short
# Should return: d3b-0x0.github.io.

7. Common pitfalls

DNS changes aren’t instant

  • TTL (Time To Live) controls how long resolvers cache records
  • Lower TTL = faster changes but more DNS queries
  • I use 300 seconds (5 minutes) for most records

Proxied vs DNS-only matters for security

  • If I accidentally proxy searx.debnerd.in:
    • CrowdSec sees Cloudflare IPs, not real visitor IPs
    • Rate limiting and bans become ineffective
    • WebSockets (used by Headplane) can break
  • Always keep self-hosted services DNS-only unless you specifically need CDN features

Email needs special records

  • MX records for mail delivery
  • TXT records for SPF/DKIM/DMARC (anti-spoofing)
  • I use Brevo for email, so their verification records live in DNS

8. How this fits into self-hosting

When you see swap debnerd.in for your own domain in a guide:

  1. You need to create A/AAAA records pointing to your server’s IP
  2. For GitHub Pages, you’ll need CNAME records
  3. For email, you’ll need MX and TXT verification records
  4. Keep self-hosted service subdomains DNS-only (grey cloud)
  5. Only proxy sites that benefit from CDN (like static blogs)

Verify your DNS setup

  • Can you explain why searx.debnerd.in needs both A and AAAA records?
  • What’s the difference between an A record and a CNAME record?
  • Why would you choose DNS-only over proxied for a self-hosted service?
  • How does DNS let you use memorable names instead of IP addresses?

Next steps