Publishing a Subdomain With One Database Row — and the Wildcard DNS Trap

Lay down wildcard DNS and host-based routing once, and spinning up a new subdomain becomes a single database row. But DNS wildcards and TLS wildcards play by different rules, and missing that boundary is how outages happen.
← 목록으로
박
박지훈
2026년 10월 02일 Updated 2026.10.17 29 min read views 2

Opening a single new subdomain means creating a DNS record, getting a certificate, adding a server block, and restarting. With hundreds of projects, you do this hundreds of times. But most of that work only needs to happen once. Lay down wildcard DNS and host-based routing up front, and opening a new subdomain comes down to adding one row to a database.

So far, so clean. The real story starts after that. "Wildcard DNS" and "wildcard certificates (TLS)" share a name but follow different rules. The moment you treat them as the same rule, you walk straight into the failure where "DNS clearly answers, but the site won't open because of the certificate." So the central question of this post isn't "how many levels deep can you go" — it's "when does it stop working?"

One Front Door, One Reception Desk

A building has one street address (the domain), but you can carve out as many rooms (subdomains) inside it as you like. You don't knock a hole in the exterior wall every time you add a room. Every visitor comes in through the one front door, and the reception desk in the lobby hears "which room are you looking for?" and points them to the right number. Keep this picture in your head and everything that follows slots into it.

  • Front door = wildcard DNS. The single entry point that takes every visitor.
  • Reception desk = host-based routing. It hears the name and finds the room.
  • Directory = the routing table (the DB).

Opening one more room isn't plumbing work — it's writing one more name in the directory.

The Foundation You Lay Once: Wildcard DNS

You register a wildcard record of the form *.ontle.kr in DNS. Here, a zone is the bundle that holds a domain's DNS records, and a label is each chunk of the domain split by dots (report-2026, ontle, kr). When a query arrives for a name that isn't otherwise defined in the zone, this wildcard synthesizes a response and sends it back. Whether it's report-2026.ontle.kr or dashboard-abc.ontle.kr, it goes to the same destination without being registered ahead of time.

; Wildcard A record (straight to an IP)
*.ontle.kr.    3600   IN   A       203.0.113.10

; Or a CNAME if you route through a CDN/tunnel
*.ontle.kr.    3600   IN   CNAME   edge.example-cdn.net.

People often say "a wildcard only covers one level down," but that's not a DNS rule. Exactly which layer that rule belongs to is something I'll pin down later. For now it's enough to remember that you've laid the foundation once.

The Moment a Request Arrives: The Entry Point Reads the Name Tag

Every request comes into a single entry point. That entry point is a reverse proxy (a relay that receives incoming requests out front and hands them off to backend servers), a CDN edge, or an outbound tunnel. The entry point reads the Host header carried in the HTTP request — the domain name the browser put in the address bar. When TLS is in use, SNI (the value that announces up front which name you're trying to reach) plays the same role. Which door you came through is decided not by IP but by the name tag.

GET / HTTP/1.1
Host: report-2026.ontle.kr

Publishing: One Line in the Directory

The application behind the entry point takes the Host value and looks up "is this name registered?" If it is, it serves the linked content; if not, it shows a 404 or a landing page. Conceptually, the directory looks like this.

Subdomain Content type Owner Status
report-2026 Analytics dashboard Project A Published
jihoon-blog Personal blog User B Published
team-x Team landing page Team X Suspended

Opening a new subdomain shrinks from "add DNS → issue certificate → configure server → restart" to adding one row to this table. DNS and the certificate are already in place, so all that's left is a single database transaction. There's no reason to wait for DNS propagation, either. The wildcard record propagated long ago and is done; the only thing changing is the directory inside the application, which usually takes effect within a few seconds.

Serving: A Standalone Website, Not Trapped in a Viewer

Say you've published an analytics dashboard for a client under the name report-2026. When someone visits report-2026.ontle.kr, it isn't wrapped in ONTLE's header or navigation — the dashboard's original HTML is served as-is, as the top-level document.

The difference shows up in how it feels. Send this URL in a chat app and you'll see the dashboard's own title, description, and thumbnail, not the ONTLE logo. In Google search, it's that site itself that gets indexed, not "ONTLE." Hand it out like a business card or let a search engine crawl it, and it reads as entirely the client's own. This is why, when you publish a deliverable on ONTLE, name.ontle.kr looks like a standalone website rather than something trapped in a viewer.

The Two Wildcards Are Different Rules

This is where I've seen things go wrong most often in practice. The two "wildcards" share a name but differ in the rules governing their scope. Blur them together and you hit the situation where "DNS answers but the site won't open because of a certificate error."

  • DNS wildcard (the *.ontle.kr record): not limited by the number of labels. As long as no node stands in the way, it synthesizes a response even for names several levels down, like a.b.ontle.kr. However, it does not apply to names that already exist (per RFC 4592).
  • TLS wildcard certificate (*.ontle.kr): matches exactly one leftmost label. It covers report-2026.ontle.kr, but it does not cover a.b.ontle.kr or ontle.kr (the apex name itself). This "one level" restriction is the rule set by RFC 6125 §6.4.3 and the CA/Browser Forum Baseline Requirements, and the successor standard RFC 9525 keeps it unchanged.

So the real question is "when does it stop working?" As long as you only publish single-level names like name.ontle.kr, a single wildcard certificate is enough — this is ONTLE's default publishing form. But if you want to open a name that goes two levels deep, like team.client.ontle.kr, DNS will answer (as long as there's no intermediate node), yet a single *.ontle.kr TLS certificate won't cover it. To use that depth, you'd issue a separate *.client.ontle.kr certificate, or put that name directly in the certificate's SAN (the list of names a single certificate covers). "DNS answers" and "TLS is trusted" live on separate layers.

[Deep dive] The one place a wildcard doesn't apply — empty non-terminals

Let's bring back the reception-desk analogy. Even if a name isn't in the directory, if there's already a tenant in a more specific room below it, the desk doesn't treat that area as an "empty name." DNS works the same way. A name exists along one of two paths — (1) it has a record directly attached to it, or (2) it has no record of its own but there's a lower name with a record beneath it. The second case is an empty non-terminal (ENT). A wildcard only takes in "undefined names," so it won't touch names that exist this way.

The safe case — you leave *.ontle.kr as is in DNS and publish only in the DB directory. No new DNS record is created, so no ENT is created either. Even if you publish x.team.ontle.kr, team.ontle.kr keeps its wildcard response intact.

The trap — if you put an actual DNS record directly on x.team.ontle.kr and leave nothing on the parent team.ontle.kr, then team.ontle.kr becomes an ENT. Now the wildcard no longer stands in for team.ontle.kr. A query returns not NXDOMAIN ("the name itself doesn't exist") but NODATA ("the name exists, but has no record of that type"), and in the end it won't open.

In short, as long as you only add rows to the DB, no ENT is created. You only need to be careful once you start putting individual DNS records on deeper names (RFC 4592).

Where Operations Slip

The simpler the structure, the bigger the blowup when operational rules are loose. If you're handing out subdomains in bulk, the following are worth baking in from the start.

What Happens When a Reserved Name Gets Through

If a user grabs names like www, api, admin, mail, blog, app, cdn, or status at will, user content can masquerade as a system admin page — or, the other way around, an actual system service gets pushed aside. Block them with a reserved list from the start, and normalize input for case and whitespace before comparing.

RESERVED_SUBDOMAINS = frozenset({
    "www", "api", "admin", "mail", "ftp", "blog",
    "app", "cdn", "status", "docs", "help", "support",
})

def is_reserved(name: str) -> bool:
    normalized = name.strip().lower()
    return normalized in RESERVED_SUBDOMAINS

Blocking the Race When the Same Name Is Requested at Once

Don't leave name assignment to a "check-then-create" in application logic. If two transactions request the same name at the same moment and both decide "it's free" and both insert it, you end up with two deliverables hanging off one name. The safe approach is a database UNIQUE constraint on the normalized name column, with the application mapping the DB's duplicate-insert error to "already in use."

When One Account Churns Out Thousands

Issue names without limit and you're wide open to spammy mass creation and resource exhaustion. Cap the "number of subdomains that can be live at once" per plan or account tier, and when the cap is exceeded, block it with a clear message.

How Caches Betray You

With a CDN or edge cache in play, a freshly published name may not be in the cache yet, making the first request slow — or, conversely, a name you've reclaimed stays in the cache and keeps serving the old content. When a publish or reclaim event fires, it's best to tie that name's cache invalidation (purge) to the routing-table update as if they were one transaction.

The Finish Line Is the Browser, Not the DB

The log shows success, but the customer sees a 404. A row landing in the routing table is no guarantee that the address actually opens. The common causes are these — the cache didn't refresh, there's a typo in the routing condition, (if you put in individual DNS records) the ENT seen earlier already blocked it at the DNS stage, or the certificate doesn't cover that depth.

So publishing a subdomain can't end at "successfully recorded in the DB." The set isn't complete until you've confirmed the actual URL returns HTTP 200 and seen the screen genuinely render in a browser. Logs and DB counts are evidence that you tried, not evidence that it worked.

"I added report-2026.ontle.kr to the routing table." — this is still an attempt. Whether the screen comes up when you visit the address, nobody knows yet.

"I added it to the routing table, confirmed HTTP 200 and a valid TLS handshake with curl -sI https://report-2026.ontle.kr, and opened it in a browser to watch the dashboard render." — now you can say it worked.

Getting Started With ONTLE

You don't have to touch DNS, certificates, and deployment servers again every time you create a deliverable. On top of this structure, ONTLE publishes whatever you've built as a standalone website at name.ontle.kr, right where you made it. If you want to try it yourself, start at https://ontle.kr .

FAQ

If a single wildcard certificate is shared by every subdomain, is that okay security-wise?

Having one `*.ontle.kr` certificate cover every single-level name is both the heart of the convenience and its price. Because all subdomains are bound to the same certificate and private key, if that key leaks, the blast radius spreads to everything. That's why key storage (least-privilege access) and periodic rotation have to be operational basics. If you want stronger protection for a particular subdomain, you can issue a dedicated certificate for that name so that server presents only the dedicated cert. That said, issuing a dedicated certificate doesn't make the existing `*.ontle.kr` wildcard invalid for that name — the wildcard certificate is still valid for it, so if the wildcard private key leaks, the risk of someone impersonating that name remains. In other words, issuing a dedicated certificate alone doesn't remove that name from the wildcard's scope or "fully isolate" it (see RFC 9525 §7.1).

Since it's a wildcard and DNS answers for any name, could unregistered names be abused?

DNS answering doesn't mean there's content. When a request comes in on an unregistered name, the application decides it's not in the directory and sends it back with a 404 or a landing page. Add a reserved-name list and a per-account publishing cap on top of that, and you can stop an entrance that "takes any name" from turning into actual abuse at the front gate.

Can I move services I've already set up per-subdomain into this structure?

DNS is already being handled by the `*.ontle.kr` wildcard, so new names are absorbed by adding them to the directory (the DB). The caveat: if there are names where you put in individual DNS records directly in the past, when you clean those up you need to first check that the parent name doesn't become an ENT. If you still need to serve that name itself, keep an explicit record, or proceed by moving routing into the directory while removing the unnecessary individual records.

References


Written by Jihoon Park