macOS ziti-edge-tunnel DNS Hijacking and Config Path Modification

I’m attempting to use the ziti-edge-tunnel on macOS, but it’s not fully working as expected. Specifically, its DNS hijacking is not effective, and I can’t specify the config.json configuration file path, which defaults to /tmp/config.json.

My installation and testing steps were as follows:

$ mkdir ~/ziti-tunnel -p
$ cd ~/ziti-tunnel
$ sudo dseditgroup -o create ziti; sudo dscl ~/ziti-tunnel -append /groups/ziti GroupMembership <USER>
$ wget https://github.com/openziti/ziti-tunnel-sdk-c/releases/download/v1.2.5/ziti-edge-tunnel-Darwin_x86_64.zip
$ unzip ziti-edge-tunnel-Darwin_x86_64.zip
$ sudo chown -R <USER>:ziti ~/ziti-tunnel
$ sudo ./ziti-edge-tunnel run -I ~/ziti-tunnel

$ sudo ./ziti-edge-tunnel add --jwt "$(< ./xxx.jwt)" --identity xx

The relevant runtime log:

$ sudo ziti-edge-tunnel run -I ~/ziti-tunnel
Password:
About to run tunnel service... ziti-edge-tunnel
(57689)[        0.000]    INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO
(57689)[        0.000]    INFO ziti-sdk:utils.c:169 ziti_log_init() Ziti C SDK version 1.1.5 @g2120296(HEAD) starting at (2024-10-28T03:17:18.457)
(57689)[        0.000]    INFO ziti-edge-tunnel:instance-config.c:85 load_tunnel_status_from_file() Loading config file from /tmp/config.json
(57689)[        0.000]    INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO
add net 100.64.0.1: gateway utun2
(57689)[        0.000]    INFO tunnel-sdk:ziti_tunnel.c:60 create_tunneler_ctx() Ziti Tunneler SDK (v1.2.5)
(57689)[        0.000]    INFO tunnel-cbs:ziti_dns.c:176 seed_dns() DNS configured with range 100.64.0.0 - 100.127.255.255 (4194302 ips)
add net 100.64.0.2: gateway utun2
(57689)[        0.000]    INFO ziti-edge-tunnel:ziti-edge-tunnel.c:1726 run_tunneler_loop() Loading identity files from /Users/<USER>/ziti-tunnel
(57689)[        0.000]    INFO ziti-edge-tunnel:ziti-edge-tunnel.c:1127 load_identities() loading identity file: xx.json
(57689)[        0.000]    WARN ziti-edge-tunnel:instance.c:39 find_tunnel_identity() Identity ztx[/Users/<USER>/ziti-tunnel/xx.json] is not loaded yet or already removed.
(57689)[        0.000]    INFO ziti-edge-tunnel:ziti-edge-tunnel.c:1628 make_socket_path() effective group set to 'ziti' (gid=501)
(57689)[        0.025]    INFO tunnel-cbs:ziti_tunnel_ctrl.c:1121 load_ziti_async() attempting to load ziti instance[/Users/<USER>/ziti-tunnel/xx.json]
(57689)[        0.025]    INFO tunnel-cbs:ziti_tunnel_ctrl.c:1128 load_ziti_async() loading ziti instance[/Users/<USER>/ziti-tunnel/xx.json]
(57689)[        0.025]    INFO ziti-edge-tunnel:ziti-edge-tunnel.c:1143 load_id_cb() identity[/Users/<USER>/ziti-tunnel/xx.json] loaded
(57689)[        0.027]    INFO ziti-sdk:ziti.c:438 ziti_start_internal() ztx[0] using tlsuv[v0.32.6/OpenSSL 3.3.1 4 Jun 2024]
(57689)[        0.027]    INFO ziti-sdk:ziti_ctrl.c:593 ziti_ctrl_init() ctrl[(null):] using https://zt.abc.com:8441
(57689)[        0.027]    INFO ziti-sdk:ziti.c:507 ztx_init_controller() ztx[0] Loading ziti context with controller[https://zt.abc.com:8441]
(57689)[        0.355]    INFO ziti-sdk:ziti.c:1761 version_pre_auth_cb() ztx[0] connected to Legacy controller https://zt.abc.com:8441 version v1.1.15(0eec47ce3c80 2024-10-02T12:59:41Z)
(57689)[        0.652]    INFO tunnel-cbs:ziti_tunnel_ctrl.c:968 on_ziti_event() ziti_ctx[xx] connected to controller
add host X.X.X.X: gateway 10.49.64.1
route: writing to routing socket: File exists
add host X.X.X.X: gateway 10.49.64.1: File exists
(57689)[        0.652]    INFO ziti-edge-tunnel:ziti-edge-tunnel.c:1181 on_event() ztx[/Users/<USER>/ziti-tunnel/xx.json] context event : status is OK
(57689)[        0.746]    INFO ziti-sdk:channel.c:270 new_ziti_channel() ch[0] (ap-router) new channel for ztx[0] identity[xx]
(57689)[        0.746]    INFO tunnel-cbs:ziti_tunnel_ctrl.c:1039 on_ziti_event() ztx[xx] added edge router ap-router@zt.abc.com
route: writing to routing socket: File exists
add host X.X.X.X: gateway 10.49.64.1: File exists
route: writing to routing socket: File exists
add host X.X.X.X: gateway 10.49.64.1: File exists
(57689)[        0.746]    INFO ziti-sdk:channel.c:799 reconnect_channel() ch[0] reconnecting NOW
(57689)[        0.906]    INFO tunnel-cbs:ziti_tunnel_cbs.c:414 new_ziti_intercept() creating intercept for service[ap-dashboard.svc] with intercept.v1 = { "addresses": [ "kubernetes-dashboard.kubernetes-dashboard", "ap-dashboard.ziti" ], "portRanges": [ { "high": 443, "low": 443 } ], "protocols": [ "tcp" ] }
(57689)[        0.906]    INFO tunnel-cbs:ziti_dns.c:349 new_ipv4_entry() registered DNS entry kubernetes-dashboard.kubernetes-dashboard -> 100.64.0.3
(57689)[        0.906]    INFO tunnel-cbs:ziti_dns.c:349 new_ipv4_entry() registered DNS entry ap-dashboard.ziti -> 100.64.0.4
add net 100.64.0.3: gateway utun2
add net 100.64.0.4: gateway utun2
(57689)[        0.906]    INFO tunnel-cbs:ziti_tunnel_ctrl.c:925 on_service() starting intercepting for service[ap-dashboard.svc]
(57689)[        0.906]    INFO ziti-edge-tunnel:ziti-edge-tunnel.c:1304 on_event() =============== service event (added) - ap-dashboard.svc:6t1A1qgCuVxNpjUwl56f6O ===============
(57689)[        1.100]    INFO ziti-sdk:channel.c:697 hello_reply_cb() ch[0] connected. EdgeRouter version: v1.1.15|0eec47ce3c80|2024-10-02T12:59:41Z|linux|amd64
(57689)[        1.100]    INFO tunnel-cbs:ziti_tunnel_ctrl.c:1043 on_ziti_event() ztx[xx] router ap-router connected
(57689)[        1.509]    INFO ziti-sdk:posture.c:206 ziti_send_posture_data() ztx[0] first run or potential controller restart detected

I can’t access the service using ap-dashboard.ziti, but I can access it via 100.64.0.4. The DNS hijacking doesn’t seem to be working. I’m not sure if this is due to a configuration issue. Additionally, I’d like to know how to modify the /tmp/config.json path, as storing it in /tmp feels awkward.

Hi,

At the moment DNS intercept is not implemented on Darwin. It's been on my mind but it hasn't been a priority for us. Depending on your urgency and willingness to tinker, it is possible to manually configure the macOS resolver to use ziti-edge-tunnel's DNS server for specific domains.

For each domain (or fqdn) that you want to map to an OpenZiti service, you can create a resolv.conf-style file in /etc/resolver/ that specifies the nameserver IP of your ziti-edge-tunnel process. For example I use this to send all ".zet.ziti" queries to ziti-edge-tunnel:

% cat /etc/resolver/zet.ziti
nameserver 100.64.0.2

Note that ziti-edge-tunnel's nameserver IP is always the IP of its tun interface + 1. The default tun IP is 100.64.0.1, hence the DNS server IP of 100.64.0.2. You can change the tun IP indirectly by passing the --dns-ip-range option when starting ziti-edge-tunnel.

As for the config file location, I think that's an oversight that would be easy to change in the next release.

1 Like

The configurations in the /etc/resolver/ directory are effective, but they only work for domains with the ziti suffix. If there are multiple private domain suffixes, many configurations are required. Originally, I wanted to add a nameserver 100.64.0.2 in /etc/resolv.conf to solve this, as dig @100.64.0.2 xxx.ziti can resolve normally. However, it doesn't work. After checking relevant materials, I found that this is due to some mechanisms of the macOS system. At least I now know the reason, thank you for your answer, thank you!

Thank you for updating the code to set the configuration file directory to /var/lib/ziti for all systems except Windows. If time permits, I would suggest adding an option for parameter passing to enhance flexibility. As a non-developer, I may not be able to contribute directly, but I hope my suggestions can be helpful to the project.

1 Like