The App Connector
You live in New York. There's a library in Singapore that won't lend books to anyone outside the city. You don't want to move. You don't want to send all your mail through Singapore. You only want a Singapore address when you're talking to that one library.
This page builds up the contraption that makes that possible, one piece at a time. As we go, parts will be color-coded so you don't have to remember names: your laptop, the remote room you'll rent, the private tunnel between them, the public internet, and the service you're trying to reach. Each section ends with the problem the next one solves.
A library across the ocean
Some websites are picky about where their visitors are coming from. A streaming service hides certain shows outside the United States. A new model from an AI company is available in Singapore weeks before it lights up in Europe. A bank's login page refuses to load if it thinks you're abroad.
The first thing to notice is that the website is making a geographic decision before you've even told it your name. You haven't logged in. You haven't typed an address. It just looks at your incoming request and goes: nope.
Move the slider below to put yourself in different cities. The library in Singapore only checks out books to readers it can place in Singapore. Watch what happens when you ask from somewhere else.
So we have a goal: when you talk to this one library, you want to look like you live in Singapore. Everywhere else (your bank, your email, your streaming app) you want to look like yourself.
To get anywhere, we have to answer a simpler question first: how does the library even know where you are?
Your return address
When you write a paper letter, you put a return address on it so the recipient knows where to send the reply. The internet works the same way. Every time your laptop sends a request out, it stamps a small number on the outside of the envelope. That number is called an IP address, and it's how the rest of the internet sends replies back to you.
Your IP address isn't random. Your internet provider hands one out from a block of addresses they own, and those blocks are registered to specific countries and cities. There are public databases that map every IP back to a rough location: country, city, sometimes even neighborhood. Any website you talk to can look you up in milliseconds.
The packet below is heading to a server. Drag the slider to change which return address is on the front. Watch where the server thinks the packet came from.
So the library refuses you because the IP on your envelope is registered to New York, not Singapore. To trick the library into helping us, we need our envelope to leave from Singapore. Not look like Singapore. Actually depart from there, with a real Singapore address on it.
Which means we need a way to send our envelope from somewhere we are not. But before we can talk about how to do that, there's one more piece of the postal system to understand: how your computer figures out the destination address in the first place.
The phonebook
You don't usually type IP addresses. You type names: ai-service.com, news-site.com, your-bank.com. Names are easy for humans. But the network only routes by numbers. Something has to translate.
That something is called DNS, the phonebook of the internet. Before your laptop can send a single byte to ai-service.com, it asks the phonebook: "What's the number for this name?" Only after it gets a real IP back does it know where to actually send the envelope.
This sounds like one motion, but it's two: look up, then route. Keep that split in mind. We'll come back to it. Type a name into the box below and watch the lookup happen, then the routing.
This split matters because there are two different places we could try to intervene. We could lie to the phonebook (give a fake address). Or we could let the lookup happen honestly, and then change where envelopes for that address get sent. The clever trick we're building leans on the second option, with a small assist from the first; you'll see why in a few sections.
For now: every visit to a website is a phonebook lookup followed by a route to the resulting number. To get a Singapore-stamped envelope, we still don't have a way to depart from Singapore. The most obvious answer is also the worst one. Let's look at it.
The all-or-nothing VPN
The classic answer to "I want to look like I'm somewhere else" is a VPN: a virtual private network. You sign up for a service, install an app, click Connect, and from that moment until you click Disconnect, every single byte your computer sends goes through their server in another country first.
The advantage is obvious: that other server in Singapore now sends your envelopes for you, and they all come stamped with a Singapore address. The library is happy.
The disadvantage is also obvious: everything goes through Singapore. Your video calls. Your bank app, which now thinks you're traveling and locks the account. Your streaming service, which now serves a different catalogue. Your downloads, which now make a 12,000-mile detour. The toggle below shows the difference.
This is the wrong shape of tool. The library only cares about library envelopes. We don't need to fool our streaming service. We don't want to confuse our bank. What we want is something surgical: a way to redirect only the envelopes addressed to a small list of services, and leave everything else alone.
To build a surgical version, we'll need two pieces. First, a private path between our laptop and a small computer somewhere in Singapore. Second, a rule that says "only use the path for these specific destinations." The first piece is the tunnel. The second piece is the map. We'll start with the tunnel.
The private tunnel
We rent a tiny computer in Singapore. It costs a few dollars a month and runs a single program whose entire job is to forward traffic. We'll call it the remote room. We'll come back to where you actually rent it; for now, picture an empty room with one telephone in it.
Now we need a way to talk to the room. We don't want to talk over the public internet, because anyone listening would see our traffic. So we lay a private cable between our laptop and the room. Of course, we can't actually lay an undersea cable. The cable is virtual: every packet that travels between the two ends is wrapped inside an outer envelope, encrypted, and dropped onto the regular internet. To anyone in between, all they see is gibberish flowing between two random IPs.
The piece of software that builds and maintains this private cable for you is Tailscale. You install it on your laptop, you install it on the rented room, both ends register with the same account, and now they think they're sitting next to each other on a private network, even though physically they're 9,000 miles apart.
So far this just gets us a private link to a room in Singapore. By itself, that's nothing. We already had a way to send packets between two computers. What's interesting is what happens when we use the room as a launching pad. If the room is the one that talks to the library, then the envelope leaving the room has the room's Singapore address on the front, and the library is satisfied.
But that means we still have to teach our laptop the rule: "For library traffic only, send things down the tunnel; everything else, use the regular internet." Without that rule, we're back to either using the tunnel for everything (a slow VPN) or for nothing (no point in renting the room). We need the map.
The magic map
Imagine your laptop has a tiny notebook in its pocket. Whenever it's about to send a packet, it glances at the notebook to see if there's a special instruction for that destination. Most of the time the notebook is silent, and the packet goes out the front door onto the public highway. But for a few specific destinations, the notebook says: "This one. Use the tunnel."
That notebook is what we'll call the magic map. In the real product it's called an App Connector. It works like this:
- You write down a list of names, like
ai-service.com,code-helper.com. - The connector running in your Singapore room looks each name up in the phonebook to find its current IP addresses.
- It tells everyone in your account: "For these specific IPs, send the traffic to me. I'll handle it."
- Your laptop writes those instructions into its routing notebook automatically.
Now flip on a few domains in the demo below and watch how each destination gets routed. Domains on the magic map go down the tunnel. Everything else takes the public highway, just like before.
This is the move that makes the App Connector different from a regular VPN. The tunnel is the same kind of encrypted private link as a VPN's. The map is what changes: it lets you specify, by name, exactly which traffic uses the tunnel.
There's a subtlety worth pausing on, because back in section 03 we promised to come back to the split between looking a name up and routing to the resulting number. Big services don't have a single IP; they have many, and the phonebook usually hands back the ones closest to whoever's asking. The connector in Singapore looking up ai-service.com sees Singapore-side IPs. Your laptop in New York looking up the same name would see New York ones. If only the routing was rigged, your laptop would send envelopes to New York IPs that aren't on the map, and skip the tunnel entirely.
So the connector takes care of both halves. Tailscale also acts as your laptop's phonebook for the names on the map: when your laptop asks for ai-service.com, it's handed back the same Singapore-side IPs the connector knows about. The lookup and the route stay in sync. Names you didn't list go through the regular phonebook as before.
You might already be uneasy. If our packets all go through this room in Singapore now, can the room read them? Could it see passwords, login cookies, the prompts we send to AI services? Anything sensitive? It's a fair question, and it has a clean answer.
The locked envelope
Modern websites don't send their traffic in the open. Every time you visit a site whose URL starts with https:// (almost all of them now), your laptop and that site are using something called TLS to put their conversation inside a sealed envelope. The envelope has the to-and-from addresses written on the outside. The contents are scrambled with a key that only your laptop and the destination server share.
Anyone in between (your internet provider, a stranger on a coffee shop wifi, our Singapore room) can see the envelope going by. They can read the destination on the front. They cannot open it. The scramble is mathematically tied to keys they don't have.
This is why a tunnel is safe. The connector forwards the envelope along; it never opens it. Toggle the lock below to see what an outsider would see if there were no envelope, versus what they see in reality.
So the connector is doing one specific job: it's a courier for your sealed envelopes. It can tell that an envelope is going to the library. It cannot read what you're saying to the library. The same security guarantees you'd have on any modern website apply just as well when the envelope is being relayed through one extra computer.
That settles the trust question. The next question is structural: when our envelope arrives at the room, the return address on it is still our address: the New York one. If the room just shoves it out onto the public internet like that, the library will reject us all over again. Something has to rewrite the front of the envelope before it leaves the room.
The disguise and the ledger
Here's the maneuver. As your envelope passes through the room on the way out to the library, the room scratches out your New York return address and writes its own Singapore address in its place. The library, when it eventually replies, ships the response back to Singapore, because that's the only address it ever saw.
This trick has a name: NAT, short for network address translation. The specific flavor used here is called masquerade, which is exactly what it sounds like. Every household router on the planet does the same thing: dozens of devices in your house all share one public IP because the router rewrites their return addresses on the way out.
Of course, when the reply arrives back in Singapore, the room has to remember that the response was actually for your laptop. Otherwise it would have no idea where to forward it. So the room keeps a small ledger of every envelope it forwards: "Outbound request #45 was originally from the New York laptop, so when reply #45 comes back, send it down the tunnel to them."
The library never learns about the New York laptop. It only ever sees the Singapore room. From the library's perspective, it's having a perfectly normal conversation with a single computer in Singapore, exactly the kind of customer it was hoping for.
We now have all the conceptual machinery: a tunnel, a map of which destinations use it, a sealed envelope, and a disguise on the way out. One thing is still nagging, though. Why does our laptop choose the magic map for ai-service.com but not for see-movies.com? What stops the laptop from getting confused and routing everything through the room? That comes down to a quiet rule about how computers pick between conflicting directions.
The hierarchy of directions
Computers follow a strict rule when choosing a path for a packet: the most specific instruction wins. Always.
You can write a routing rule like "all traffic, anywhere". That's the very general fallback every laptop has, the one that says "if you don't know where to send something, send it to your home wifi router and hope for the best." You can also write rules that target a single, specific destination: "if the packet is going to this exact one IP, use the tunnel."
The connector pushes extremely specific rules into your laptop, one for each individual IP behind the domains on your map. The general "send everything via the home router" rule is still there, untouched. It just gets out-voted whenever a packet matches a more specific rule.
The little routing table below has rules of varying specificity. Move the slider to send a packet to a different destination and watch which rule wins.
/32 rule is shorthand for "this exact one address." It beats anything more general. That's why your bank traffic doesn't accidentally end up in Singapore.The notation /32 is just a way of writing how specific the rule is. It means: "match exactly this one IP and absolutely nothing else." Lower numbers, like /24, would catch a whole neighborhood of nearby IPs. The connector deliberately uses the most precise possible setting, so it picks up only the destinations on your list and not their friends.
One more piece of the puzzle. The map and routing rules don't appear out of nowhere on your laptop. Something has to deliver them. And once it has, you might wonder: does the same something also see your traffic? It doesn't, and the reason is the difference between two parts of the system that get conflated all the time.
The dispatcher and the driver
Networks like Tailscale separate the two jobs cleanly. There's a dispatcher sitting in the middle whose only job is paperwork: handing out keys to your laptop and your remote room, telling each one where the other is, distributing the magic map. And there's the driver: the encrypted private path between the two devices, where the actual envelopes flow.
The dispatcher and the driver are deliberately not the same thing. The dispatcher is a small Tailscale-run service. It learns metadata about your devices: their public IPs, their public keys. It does not learn your traffic. Once it has finished introducing your two devices to each other, it gets out of the way.
From that point on, your envelopes go between your laptop and the room without the dispatcher in the middle. Most of the time the path is direct, peer-to-peer over the regular internet. If a strict firewall or carrier-grade NAT in between refuses a direct connection, Tailscale silently falls back to an encrypted relay (one of its own, called DERP) that forwards your already-sealed packets without being able to read them. Either way, the dispatcher isn't in the path. If it disappeared mid-conversation, your existing tunnel would keep working until one of the two ends needed something new (a key rotation, a new peer). The toggle below shows the two layers separately.
So the trust picture is: you trust the dispatcher to introduce devices and to distribute the map. You don't have to trust the dispatcher to look at your traffic, because it doesn't.
That covers the runtime. But we still have to talk about the small computer in Singapore we rented. How does it prove to the dispatcher that it's allowed to do all this? In particular, how does it do it without us baking a permanent password into a server we left running on the internet?
The burner key
If you wanted to keep things simple, you could generate one permanent password (call it an auth key), paste it into a config file on the rented room, and let it use that key forever. It would work. It would also be a bad idea. If anyone ever got their hands on that file, they'd have a permanent ticket into your network.
The cleaner pattern, and the one we're going to set up, is more like a hotel key card. We give the rented room a pair of credentials, a client ID and a secret, that can do exactly one thing: request a fresh, single-use, short-lived auth key. Every time the room boots up, it does this little dance:
- Use the long-lived ID and secret to ask the dispatcher for a temporary access token.
- Use the access token to mint a single-use auth key, marked as ephemeral.
- Use that single-use key to register itself as a tunnel endpoint.
- Throw the key away. It's already been used.
"Ephemeral" is the magic word in step 2. It means: when this room shuts down, automatically delete it from the network. If the box restarts, it goes through the whole dance again and shows up as a fresh node. You don't accumulate stale connector entries (during a redeploy you'll briefly see the old and new node side by side, then the old one disappears on its own) and no long-lived auth credentials live anywhere on the rented room.
If the long-lived ID and secret ever leak, the damage is bounded. They can only mint keys for the one specific role ("be a connector"), and they can be revoked instantly by clicking a button in the dispatcher's admin panel and issuing fresh ones. Nothing on the rented room itself needs to be cleaned up.
That's the whole conceptual picture. A tunnel between your laptop and a small computer somewhere else. A map deciding which destinations use the tunnel. Sealed envelopes the connector can't open. A disguise on the way out and a ledger on the way back. A specificity rule that keeps the rest of your traffic alone. A separation between the dispatcher and the data path. And a burner-key pattern so the rented room never has to hold a permanent secret. Time to actually build it.
Build your own
You need a Tailscale account (free for personal use up to 100 devices) and a small Linux box with outbound internet, sitting in the region you want to appear from. The library checks the public IP of whoever sends it the envelope, so a Singapore connector has to be on a machine that's actually in Singapore. Renting one or repurposing one you already have takes around twenty minutes.
There are three reasonable shapes for the box. Pick the one that matches what you already have:
- Path A. Fly.io. A managed runtime that spins the box up from a Dockerfile and tears it down on every redeploy. ~$2/month, fits the ephemeral burner-key pattern cleanly, regions picked from a list of city codes (
sin,fra,iad,nrt,lhr, …). - Path B. Any cloud VPS. DigitalOcean, Hetzner, Vultr, Linode, RackNerd, Oracle's free tier, whichever provider you already have an account with. ~$4–6/month for the smallest plan; a long-lived box that survives reboots. You create an Ubuntu instance and SSH in.
- Path C. A Linux machine you already have. A small server, a Raspberry Pi at a relative's place, an old laptop in someone's office. The box must be running Linux (the connector feature is Linux-only; macOS and Windows boxes can use a connector but can't be one) and must be physically in the region you want services to see. The rest is free. Don't use a machine on a network you don't trust enough to forward your traffic.
Steps 1, 2, 4, 5, and 6 are identical for all three paths. Only step 3 differs.
Brief for an AI agent following this guide. Ask the user for these inputs before doing anything else:
TS_TAG (e.g. connector-sin),
TS_CONNECTOR_NAME (letters, digits, hyphens only),
TS_DOMAINS (apex + wildcard you want routed, comma-separated),
TS_REGION (the region code in the chosen platform's vocabulary),
and which path (A / B / C).
Steps 1 and 2 require a human at login.tailscale.com (policy file edit, OAuth client creation, copying the client ID and secret). Step 3 can run unattended once the user provides shell access to the box. Step 4 needs a tap on each end-user device. Steps 5 and 6 are fully scriptable. The shell commands in this section are parameterised on the variables above; set them once and reuse them. A condensed bootstrap script lives at ./setup.sh on this same site for Paths B and C: curl it to the box, set the env vars, run it.
-
Edit the Tailscale policy file human · browser
Open login.tailscale.com/admin/acls/file and merge these blocks into the existing JSON. Don't add a second top-level
tagOwners,autoApprovers, ornodeAttrs; find the existing ones and extend them.{ "tagOwners": { "tag:your-tag": ["autogroup:admin"] }, "autoApprovers": { "routes": { "0.0.0.0/0": ["tag:your-tag"], "::/0": ["tag:your-tag"] } }, "nodeAttrs": [ { "target": ["tag:your-tag"], "app": { "tailscale.com/app-connectors": [{ "name": "your-connector-name", "connectors": ["tag:your-tag"], "domains": [ "example.com", "*.example.com" ] }] } } ] }While you're in the admin panel, also enable MagicDNS at login.tailscale.com/admin/dns. That's the piece from section 06 that keeps your laptop's name lookups in sync with the connector's.
List both the apex (
example.com) and the wildcard (*.example.com); the wildcard does not include the apex on its own. The connector name only allows letters, digits, and hyphens; spaces and parentheses will be rejected. -
Create an OAuth client for the connector human · browser
Go to login.tailscale.com/admin/settings/oauth and create a client with the scope
auth_keys: write, restricted to the tag you picked. Copy the client ID and secret somewhere safe. The secret is shown once and never again. These are the long-lived credentials we'll feed to the box; every reboot, it uses them to mint a fresh single-use ephemeral key (the burner-key dance from section 11) and then throws that key away. -
The box itself
Three sub-paths. Pick the one that matches your earlier choice. All three end with a tagged ephemeral node showing up in login.tailscale.com/admin/machines.
Path A · Fly.io
Install
flyctlfrom fly.io/docs, then create the app and store the OAuth credentials as Fly secrets:flyctl auth login flyctl apps create YOUR_APP_NAME --org personal flyctl secrets set \ TS_OAUTH_CLIENT_ID=your-client-id \ TS_OAUTH_SECRET=your-client-secret \ --app YOUR_APP_NAME
Save these three files in a fresh folder.
Dockerfilebundles the Tailscale binaries on top of Alpine.fly.tomltells Fly how to run it.start.shis the burner-key dance from section 11.Dockerfile:
FROM alpine:3.20 RUN apk add --no-cache ca-certificates iptables ip6tables iproute2 curl jq COPY --from=docker.io/tailscale/tailscale:stable /usr/local/bin/tailscaled /usr/local/bin/tailscaled COPY --from=docker.io/tailscale/tailscale:stable /usr/local/bin/tailscale /usr/local/bin/tailscale RUN mkdir -p /var/run/tailscale /var/cache/tailscale /var/lib/tailscale COPY start.sh /start.sh RUN chmod +x /start.sh CMD ["/start.sh"]
fly.toml:
app = "YOUR_APP_NAME" primary_region = "YOUR_REGION" [build] [env] TS_HOSTNAME = "your-connector-name" TS_TAGS = "tag:your-tag" [[vm]] size = "shared-cpu-1x" memory = "256mb"
start.sh:
#!/bin/sh set -eu # IP forwarding lets the kernel hand packets between interfaces echo 'net.ipv4.ip_forward = 1' > /etc/sysctl.d/99-tailscale.conf echo 'net.ipv6.conf.all.forwarding = 1' >> /etc/sysctl.d/99-tailscale.conf sysctl -p /etc/sysctl.d/99-tailscale.conf || true # burner-key dance: client_id + secret -> access token -> one-shot auth key ACCESS_TOKEN=$(curl -fsS \ -d "client_id=$TS_OAUTH_CLIENT_ID" \ -d "client_secret=$TS_OAUTH_SECRET" \ https://api.tailscale.com/api/v2/oauth/token | jq -r .access_token) TS_AUTHKEY=$(curl -fsS -X POST \ -H "Authorization: Bearer $ACCESS_TOKEN" \ -H "Content-Type: application/json" \ -d "{\"capabilities\":{\"devices\":{\"create\":{\"reusable\":false,\"ephemeral\":true,\"preauthorized\":true,\"tags\":[\"$TS_TAGS\"]}}}}" \ https://api.tailscale.com/api/v2/tailnet/-/keys | jq -r .key) /usr/local/bin/tailscaled --state=/var/lib/tailscale/tailscaled.state \ --socket=/var/run/tailscale/tailscaled.sock --port=41641 & /usr/local/bin/tailscale up \ --auth-key="$TS_AUTHKEY" \ --advertise-connector \ --advertise-tags="$TS_TAGS" \ --hostname="$TS_HOSTNAME" \ --accept-routes wait
Then, from that folder:
flyctl deploy --app YOUR_APP_NAMEThe first build downloads Alpine and the Tailscale binaries; subsequent ones are tiny. When the boot finishes, the connector should appear in the Tailscale admin's machines list.
Path B · Any cloud VPS
Create the smallest Ubuntu 24.04 instance available in your target region. The click-path is the same across providers: pick OS, pick region, pick size, get an SSH command back. A few translations:
- DigitalOcean. "Basic" Droplet, $4/month, regions include
sgp1Singapore,fra1Frankfurt,nyc3NYC. - Hetzner Cloud.
CPX11or the smallerCX22; Singapore region issin, US east isash. - Vultr. "Cloud Compute", $3.50–$5/month; Singapore is available.
- Linode (Akamai), RackNerd, OVHcloud. Same shape; pick the cheapest plan that gives you a public IPv4 in the region you want.
SSH in as root, set the four env vars below, then paste the install block. It installs Tailscale, enables IP forwarding, persists your OAuth credentials at
/etc/tailscale-connector.env, installs a systemd service that re-runs the burner-key dance on every boot, and brings the connector up.# set these first export TS_OAUTH_CLIENT_ID=your-client-id export TS_OAUTH_SECRET=your-client-secret export TS_TAGS=tag:your-tag export TS_HOSTNAME=your-connector-name # one shot: fetch and run the bootstrap script from this page curl -fsSL https://tailscale-connector.pages.dev/setup.sh | sudo -E sh
If you'd rather paste the script inline instead of
curl | sh'ing it, the contents ofsetup.share short. Open it in a browser, read it, copy it to the box, run it.Path C · A Linux machine you already have
Identical to Path B, just without the "create an instance" step. Set the same four env vars, then either curl-pipe
setup.shas above, or copy it to the box and run it undersudo. The box must be running Linux. The App Connector feature relies on kernel IP forwarding andiptablesNAT, and Tailscale's--advertise-connectoris only supported on Linux (and FreeBSD). A macOS or Windows machine can be a client of the connector, but it can't host one; if all you have in the target region is a Mac, either install Linux on it, run a Linux VM with bridged networking, or fall back to Path A or B. The box also needs unrestricted outbound internet and ideally shouldn't be running another Tailscale identity you care about, since bringing it up as a connector replaces the existing Tailscale state on that machine.If the box also serves other Tailscale-using roles you want to keep, either run the connector in a separate network namespace or use a separate dedicated machine. The connector wants to be the Tailscale identity on that host.
- DigitalOcean. "Basic" Droplet, $4/month, regions include
-
Accept routes on every device that should use the connector
The connector won't do anything for a client until that client agrees to accept the routes it advertises. On macOS and iOS, open the Tailscale menu and toggle on Use Tailscale subnets and Use Tailscale DNS. On Linux:
sudo tailscale set --accept-routes --accept-dns
You only have to do this once per device.
-
Verify
From your laptop:
# the system thinks the route to a configured domain goes via Tailscale route get example.com # macOS ip route get example.com # Linux # the destination service thinks you're in your chosen region curl -s https://www.cloudflare.com/cdn-cgi/trace | grep -E '^(ip|colo)='
If you targeted Singapore, expect
colo=SINand a Singapore-range IP. From the connector itself (flyctl ssh consoleon Path A, plainsshon Paths B and C),tailscale status --jsonshould list/32routes for the resolved IPs of your domains. -
Change the list of domains later
Edit the
domainsarray in the policy file (step 1) and save. The connector picks up the change within a minute, resolves the new names, and pushes new/32routes to your devices automatically. No need to redeploy or touch the box for a domain change. A redeploy is only required when you change the image (Path A) or the system itself (Paths B and C).
If something leaks. If the OAuth client secret ends up somewhere it shouldn't, regenerate it in the admin panel. The old secret stops minting keys the moment you regenerate it. To roll the new value onto the box:
# Path A: flyctl secrets set TS_OAUTH_SECRET=new-secret --app YOUR_APP_NAME flyctl deploy --app YOUR_APP_NAME # Paths B and C: sudo sed -i "s/^TS_OAUTH_SECRET=.*/TS_OAUTH_SECRET=new-secret/" /etc/tailscale-connector.env sudo systemctl restart tailscale-connector
That's the entire setup. From here you can change the region, add or remove domains, or run multiple connectors at once and route different domain lists through different cities. The conceptual stack (tunnel, map, envelope, disguise, ledger, specificity, dispatcher, burner key) does not change. Only the list of names you put in the policy file does.
Closing
Look back at where we started. A library across the ocean. A public IP that gave away your city before you'd said anything. Two ways to fix it that were both wrong: pretend you live in Singapore by sending every byte through Singapore, or pretend you live in Singapore by lying to your own laptop about where it is.
The contraption we ended up with is small: one rented Linux box in the right region, an encrypted tunnel, a short list of names, and a quiet rule about which traffic uses it. What makes it work isn't the cleverness of any one piece. It's that the pieces compose. The tunnel keeps the path private. The map decides which destinations use it. TLS keeps the connector from being able to read anything sensitive. NAT lets the box pretend to be the origin. The specificity rule keeps the rest of your traffic untouched. The separation between dispatcher and data plane keeps the company that runs the network out of your packets. And the burner-key pattern keeps long-lived secrets off the rented room.
The same shape works for anything that cares about geography. A news site that won't load abroad. An AI service that rolls out region by region. A bank that gets nervous when you travel. Different list of domains in the policy file, same contraption around it.
If you got this far, the thing actually worth having isn't the connector itself; it's the picture in your head of how the pieces interact. Connectors come and go. The picture lets you debug it when it breaks, extend it for new domains, and explain it to someone else without waving your hands. Go build something with it.