First off, I LOVE openziti. It's remarkably easy to use and reason about, once you understand the use case. Currently I'm using it for mobile development, as it's an effective way to deal with all the dns caching and proxy inconsistencies across platforms. I can redirect backends from dev to staging to production with a few clicks. LOVE IT.
Now on to my question - it's become clear that the macos tunneler does not respect the hosts file when directing requests from a bind policy.
So how does the name resolving happen? Can I customize the nameserver, or name -> ip mappings that determine which ip addresses that the tunnel forwards traffic?
Hi @tempire, it's great you're enjoying OpenZiti, thanks for sharing!
This is true for any tunneler, not just macOS. The hosts file as you know, maps a hostname or FQDN to an IP address. So you COULD use the hosts file if you really want to but it should be entirely unnecessary. If you choose, you could create ip-based intercept config and then use the hosts file to map the IP to a name of your choosing...However, you can already do this sort of thing with just OpenZiti intercepts so I must admit I don't understand why this would be useful. Maybe you have a reason I just don't get.
As to how it works, when you turn on an OpenZiti tunneler on your computer, a network interface is created and an IP address assigned to the interface. The tunneller then runs a little DNS server and that server is responsible for answering requests for OpenZiti intercepts. This DNS server is located at the start of the in the configured range: 100 64.x.x. then, when you define an intercept for some address: my.test.address, when a user tries to connect to that address the tunneler DNS will assign an IP to that FQDN in the assigned range. So it'll be dynamic and something like 100 64.0.5 (or whatever). It's not guaranteed to always be the same address. When services come/go, they will possibly get different IP addresses.
You can configure OpenZiti intercepts in many flexible ways, including using whatever DNS entry you like. For example, I'm fond of using a TLD in my FQDNs that doesn't exist such as: db.ziti or server.ziti etc
I'm speaking of the hosts file on the recipient (the bind config), not the dial config. As in, traffic is intercepted, then routed to the edge specified in the bind config, then the hosts file on that edge is ignored, even though the edge itself does not ignore the hosts file.
Given that the OS of that edge respects the hosts file, I would have hoped the tunneler would respect it as well.
Here's a rudimentary diagram, as I'm only partially sure I'm using the correct terms.
identity -----> dial config ------> bind config ------> tunneler (hosts file is ignored on this tunneler)
Another thing I've noticed is that the macos tunneler will not route traffic to a macos vlan. For example, on my macbook, the primary interfaces (wifi and ethernet) are at 10.0.0.0/24, and there is a vlan created at an arbitrary ip like so:
I see. That would really surprise me. Sadly, it works fine for me. There's nothing that the tunnelers do to my knowledge that would behave like this. Can you give me an example scenario? For example in my hosts file I added
cat /etc/hosts | grep oz.he
127.0.0.1 oz.hello
And then I started our hello-world:
docker run --rm -p 2000:8000 openziti/hello-world
And made a service so I can curl there from my windows machine:
Same afaik for the MacOS issue but Apple makes decisions sometimes that are not intuitive. @scareything does the macos stuff ring any bells? I might just not quite understand the situation.
Hmm. It might be browser caching of dns on ios and android, then, which would be unfortunate. That's what I've been using to test on the dial side.
I've just done some testing assuming that hosts does work, and there is evidence that the mobile device, although recognizing the new entry in the ziti tunneler app, is still sending the https request to the previous ip after the dns entry has changed, even when the dns cache on the macos bound tunneler has been flushed.
I'm assuming you're using Ziti Desktop Edge for macOS from the App Store on your Mac for the bind side of the connection. Let us know if you're running a different tunneler, such as ziti-edge-tunnel. Note that both tunnelers should use /etc/hosts entries regardless... I'm just asking to make sure we were on the same page.
That said, Ziti Desktop Edge for macOS does respect entries in /etc/hosts when connecting to addresses from the host.v1 service configuration:
% grep .ziti /etc/hosts
127.0.0.1 foo.ziti
Prior to adding the above entry I would see this in the tunneler's log (apex.log):
INFO tunnel-cbs:ziti_hosting.c:642 on_hosted_client_connect() hosted_service[etchoststest] client[zet.fedora-41-vm] client_src_addr[tcp:100.64.1.1:36256] dst_addr[tcp:foo.ziti:22]: incoming connection
ERROR tunnel-cbs:ziti_hosting.c:689 on_hosted_client_connect_resolved() hosted_service[etchoststest] client[zet.fedora-41-vm] client_src_addr[tcp:100.64.1.1:36256] getaddrinfo(tcp:foo.ziti:22) failed: unknown node or service
Connections work after adding the host entry why trying to connect to "foo.ziti":
INFO tunnel-cbs:ziti_hosting.c:642 on_hosted_client_connect() hosted_service[etchoststest] client[zet.fedora-41-vm] client_src_addr[tcp:100.64.1.1:41084] dst_addr[tcp:foo.ziti:22]: incoming connection
DEBUG tunnel-cbs:ziti_hosting.c:714 on_hosted_client_connect_resolved() hosted_service[etchoststest] client[zet.fedora-41-vm] client_src_addr[tcp:100.64.1.1:41084] initiating connection to tcp:127.0.0.1:22
DEBUG tunnel-cbs:ziti_hosting.c:221 complete_hosted_tcp_connection() hosted_service[etchoststest], client[zet.fedora-41-vm] client_src_addr[tcp:100.64.1.1:41084]: connected to server tcp:127.0.0.1:22
Can you share your service configurations and logs from the tunnelers on both sides of your connection?