Step 8: Cold start without a fallback resolver
Step 6 kept 1.1.1.1 as a secondary so the tunneler can find the controller and routers
before the overlay is up. This step removes the secondary and shows why you need it. Then it fixes the problem a
stricter way: put the controller and router names in the hosts file, and send every other lookup to the Pi-hole.
Stay off your LAN for this step (same hotspot or VLAN as step 7).
1. Find the names the tunneler resolves at startup
The tunneler looks up two kinds of name before it can reach anything on the overlay:
-
The controller. Ziti Desktop Edge shows it on the identity's detail page (
Network). On Linux it's theztAPIin the identity file. Use the name from the identity, not the one you browse to. A controller can answer to several names. Here the browser usesctrl.example.com, but the identity usesec2-203-0-113-10.us-east-2.compute.amazonaws.com:8441. -
Every edge router the identity can use. In ZAC: Edge Routers, and read the hostname in each router's address. The CLI's table leaves the address out, so ask for JSON:
# normal PowerShellziti edge list edge-routers -j | ConvertFrom-Json | ForEach-Object data |Select-Object name, hostname, supportedProtocols | Format-ListHere:
ec2-203-0-113-10.us-east-2.compute.amazonaws.com.
Look up their IPs now, while the fallback still works, and write them down:
# normal PowerShell
Resolve-DnsName ctrl.example.com -Type A
Resolve-DnsName ec2-203-0-113-10.us-east-2.compute.amazonaws.com -Type A
2. Remove the fallback
Windows:
# ADMIN PowerShell
Set-DnsClientServerAddress -InterfaceAlias "Wi-Fi" -ServerAddresses 192.168.1.53
Clear-DnsClientCache
Linux:
sudo resolvectl dns enp0s3 192.168.1.53
sudo resolvectl flush-caches
3. Cold-start the tunneler and watch it fail
Turning OpenZiti off and on in the app isn't enough, because the running service can reuse addresses it already looked up. Restart the service so it starts from nothing:
# ADMIN PowerShell
Get-Service ziti*
Restart-Service ziti
# Linux
sudo resolvectl flush-caches
sudo systemctl restart --no-block ziti-edge-tunnel
On Linux, the restart itself can take 90 seconds while DNS is broken. The old tunneler doesn't exit on SIGTERM, so
systemd waits out its stop timeout and kills it (State 'stop-sigterm' timed out. Killing. in the journal).
--no-block gives you your shell back while that happens.
Give it a few seconds. Expect it to fail: the identity doesn't connect and no services show up. The tunneler asks the Pi-hole for the controller's address, but the Pi-hole is only reachable through the overlay, which isn't up yet.
Confirm the cause:
# normal PowerShell
nslookup ec2-203-0-113-10.us-east-2.compute.amazonaws.com
It times out against 192.168.1.53.
On Linux, the tunneler log shows it too:
sudo journalctl -u ziti-edge-tunnel --since -2min --no-pager -l | grep -E "ERROR|connected to controller"
Look for failed to configure OIDC[...] (no more URLs to try): -110/connection timed out. If you skipped the
cache flush, the tunneler can get one step further on a cached address and report connected to controller
before it fails anyway.
4. Fix it with the hosts file
Add the IPs from part 1. Windows, in an admin editor (notepad
from the admin PowerShell):
# ADMIN PowerShell
notepad C:\Windows\System32\drivers\etc\hosts
Linux: sudo nano /etc/hosts.
Add one line per name. Here the controller and the router share a name, so one line covers both:
203.0.113.10 ec2-203-0-113-10.us-east-2.compute.amazonaws.com
Then restart the tunneler again (the commands in part 3). This time
it connects, because the OS answers those names from the hosts file without asking any DNS server. On Linux, the log
shows authorization successful and router edge-router-1 connected within a couple of seconds.
On Linux, the first lookups after the restart can fail with REFUSED. Each link gets its own DNS server, and
ziti0 (the tunneler's resolver at 100.64.0.2) refuses every name it doesn't intercept, instantly. If
systemd-resolved is still re-checking the Pi-hole after the outage, the refusal is the only answer it gets in time.
Wait a few seconds and ask again. To see each path on its own:
resolvectl query -i enp0s3 doubleclick.net
resolvectl query -i ziti0 doubleclick.net
The first should return 0.0.0.0. The second returns REFUSED, and that's expected.
Check that everything else still goes through the Pi-hole:
nslookup doubleclick.net
nslookup pi.hole
Expect 0.0.0.0 for the first and a pi.hole answer for the second, both from 192.168.1.53.
The trade-off
Now every lookup goes to the Pi-hole, so nothing slips past the filter. The cost is that the hosts file is a hardcoded copy of the controller and router IPs. If they change (a new cloud VM, a dynamic IP, an added router), the client can't connect until you update the hosts file on every device. With a fallback resolver, that doesn't happen. In exchange, the fallback occasionally answers a lookup the Pi-hole should have filtered.
Pick one per device. On a laptop you manage yourself, the hosts file is easy to keep up to date. On a family member's phone, keep the fallback.
Undo
Put the step 6 setting back and remove the hosts lines if you're not keeping them:
# ADMIN PowerShell
Set-DnsClientServerAddress -InterfaceAlias "Wi-Fi" -ServerAddresses 192.168.1.53,1.1.1.1
Clear-DnsClientCache
# Linux
sudo resolvectl dns enp0s3 192.168.1.53 1.1.1.1
Done when
- With only
192.168.1.53as DNS and no hosts entries, a restarted tunneler fails to connect - With hosts entries for the controller and routers, a restarted tunneler connects
nslookup doubleclick.netreturns0.0.0.0from192.168.1.53