Disclaimer:
Due to a non-disclosure agreement (NDA), the details in this post have been modified and are based on a hypothetical example for illustrative purposes. The core issue, however, remains representative of the actual challenge.
Scenario:
- Two VPCs are configured:
VPC-public
andVPC-private
. - Two EC2 instances are present:
EC2-public
inVPC-public
.EC2-private
inVPC-private
.
- An EKS cluster is set up in
VPC-private
.
The following OpenZiti components have been deployed:
Ziti Controller
The controller was deployed with the following values.yml
configuration:
clientApi:
advertisedHost: ziti-controller.example.com
service:
enabled: true
type: ClusterIP
ingress:
enabled: true
ingressClassName: "nginx"
annotations:
kubernetes.io/ingress.allow-http: "false"
nginx.ingress.kubernetes.io/ssl-passthrough: "true"
external-dns.alpha.kubernetes.io/hostname: "ziti-controller.example.com"
service.beta.kubernetes.io/aws-load-balancer-internal: "false" # Ensures the LB is public
ctrlPlane:
containerPort: "{{ .Values.clientApi.containerPort }}"
advertisedHost: "{{ .Values.clientApi.advertisedHost }}"
advertisedPort: "{{ .Values.clientApi.advertisedPort }}"
service:
enabled: true
type: ClusterIP
highAvailability:
# -- Ziti controller HA mode
mode: standalone
# -- Ziti controller HA swarm replicas
replicas: 1
persistence:
enabled: true
storageClass: "ebs-sc"
accessMode: ReadWriteOnce
size: 3Gi
cert-manager:
enabled: true
enableCertificateOwnerRef: true
installCRDs: false
trust-manager:
enabled: true
app:
trust:
namespace: "ziti-controller"
crds:
enabled: false
ingress-nginx:
enabled: true
controller:
extraArgs:
enable-ssl-passthrough: "true"
service:
annotations:
service.beta.kubernetes.io/aws-load-balancer-internal: "false"
Ziti Routers
Two routers were set up:
-
Router-Private:
ctrl: endpoint: ziti-controller.example.com:443 advertisedHost: ziti-router-private.example.com # Edge configuration for external identities edge: advertisedHost: ziti-router-private.example.com advertisedPort: 443 service: type: LoadBalancer annotations: external-dns.alpha.kubernetes.io/hostname: ziti-router-private.example.com service.beta.kubernetes.io/aws-load-balancer-internal: "true" # loadbalancer here is private ingress: enabled: false # Link listeners for router-to-router communication (internal) linkListeners: transport: advertisedHost: ziti-router-transport-private.example.com advertisedPort: 443 service: enabled: true type: ClusterIP # All routers are internal; no external exposure ingress: enabled: false # Not needed as routers are internal # Persistence for router data persistence: enabled: true accessMode: ReadWriteOnce size: 1Gi storageClass: ebs-sc
-
Router-Public:
ctrl: endpoint: ziti-controller.example.com:443 advertisedHost: ziti-router-public.example.com # Edge configuration for external identities edge: advertisedHost: ziti-router-public.example.com advertisedPort: 443 service: type: LoadBalancer annotations: external-dns.alpha.kubernetes.io/hostname: ziti-router-public.example.com service.beta.kubernetes.io/aws-load-balancer-internal: "false" # Loadbalancer here is public ingress: enabled: false # Link listeners for router-to-router communication (internal) linkListeners: transport: advertisedHost: ziti-router-transport-public.example.com advertisedPort: 443 service: enabled: true type: ClusterIP # All routers are internal; no external exposure ingress: enabled: false # Not needed as routers are internal # Persistence for router data persistence: enabled: true accessMode: ReadWriteOnce size: 1Gi storageClass: ebs-sc
The routers were installed using Helm with enrollment JWTs:
helm install ziti-router-private-release \
--namespace ziti-router --create-namespace \
openziti/ziti-router \
--set-file enrollmentJwt=router-private.jwt \
--values router-values-private.yml
helm install ziti-router-public-release \
--namespace ziti-router --create-namespace \
openziti/ziti-router \
--set-file enrollmentJwt=router-public.jwt \
--values router-values-public.yml
Ziti Edge Tunnel Configuration
-
The identity for
EC2-public
was created, enrolled, and the Ziti tunnel was started:ziti edge create identity device EC2-public --role-attributes "EC2-public" -o EC2-public.jwt ziti edge enroll EC2-public.jwt -o EC2-public.json ziti-tunnel ziti-edge-tunnel run -i EC2-public.json
-
The identity for
EC2-private
was created, enrolled, and the Ziti tunnel was started:ziti edge create identity device EC2-private --role-attributes "EC2-private" -o EC2-private.jwt ziti edge enroll EC2-private.jwt -o EC2-private.json ziti-tunnel ziti-edge-tunnel run -i EC2-private.json
-
Edge router policies were created to bind each EC2 instance to its respective router:
ziti edge create edge-router-policy router-private-router-policy \ --edge-router-roles "#router-private" \ --identity-roles "#EC2-private" \ --semantic "AllOf" ziti edge create edge-router-policy router-public-router-policy \ --edge-router-roles "#router-public" \ --identity-roles "#EC2-public" \ --semantic "AllOf"
Observations:
- Both EC2 instances (
EC2-public
andEC2-private
) successfully connect to their respective routers, as shown in theziti-edge-tunnel
logs. - The
ziti0
interface is active on both EC2 instances but is assigned the same IP (100.64.0.1
). - The following tests were performed:
- Attempting to curl the public-facing application on
EC2-public
using its Ziti tunnel IP (100.64.0.1
) failed:curl -I --interface ziti0 http://100.64.0.1/index.html
- Attempting to curl the application using the private network IP of
EC2-public
also failed:curl -I --interface ziti0 http://10.10.10.29/index.html
- Attempting to curl the public-facing application on
Logs and Outputs
-
ziti-edge-tunnel
logs from EC2-public:About to run tunnel service... ziti-edge-tunnel (2392157)[ 0.000] INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO (2392157)[ 0.000] INFO ziti-sdk:utils.c:167 ziti_log_init() Ziti C SDK version 1.2.1 @g9db50a3(HEAD) starting at (2024-12-20T15:38:21.919) (2392157)[ 0.000] INFO tunnel-sdk:ziti_tunnel.c:60 create_tunneler_ctx() Ziti Tunneler SDK (v1.2.9) (2392157)[ 0.000] INFO tunnel-cbs:ziti_dns.c:173 seed_dns() DNS configured with range 100.64.0.0 - 100.127.255.255 (4194302 ips) (2392157)[ 0.000] INFO ziti-edge-tunnel:ziti-edge-tunnel.c:894 make_socket_path() effective group set to 'ziti' (gid=995) (2392157)[ 0.054] INFO ziti-edge-tunnel:resolvers.c:68 init_libsystemd() Initializing libsystemd (2392157)[ 0.054] WARN ziti-edge-tunnel:instance.c:39 find_tunnel_identity() Identity ztx[EC2-public] is not loaded yet or already removed. (2392157)[ 0.054] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1135 load_ziti_async() attempting to load ziti instance[EC2-public] (2392157)[ 0.054] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1142 load_ziti_async() loading ziti instance[EC2-public] (2392157)[ 0.054] INFO ziti-edge-tunnel:ziti-edge-tunnel.c:402 load_id_cb() identity[EC2-public] loaded (2392157)[ 0.065] INFO ziti-sdk:ziti.c:425 ziti_start_internal() ztx[0] enabling Ziti Context (2392157)[ 0.065] INFO ziti-sdk:ziti.c:442 ziti_start_internal() ztx[0] using tlsuv[v0.32.8/OpenSSL 3.3.1 4 Jun 2024] (2392157)[ 0.065] INFO ziti-sdk:ziti_ctrl.c:604 ziti_ctrl_init() ctrl[(null):] using https://ziti-controller.example.com:443/edge/client/v1 (2392157)[ 0.065] INFO ziti-sdk:ziti.c:512 ztx_init_controller() ztx[0] Loading ziti context with controller[https://ziti-controller.example.com:443/edge/client/v1] (2392157)[ 0.482] WARN ziti-edge-tunnel:resolvers.c:399 try_libsystemd_resolver() libsystemd resolver unsuccessful. Falling back to legacy resolvers (2392157)[ 0.847] INFO ziti-sdk:ziti.c:1778 version_pre_auth_cb() ztx[0] connected to Legacy controller https://ziti-controller.example.com:443/edge/client/v1 version v1.1.15(0eec47ce3c80 2024-10-02T12:59:41Z) (2392157)[ 1.369] INFO tunnel-cbs:ziti_tunnel_ctrl.c:981 on_ziti_event() ziti_ctx[EC2-public] connected to controller (2392157)[ 1.369] INFO ziti-edge-tunnel:ziti-edge-tunnel.c:440 on_event() ztx[EC2-public] context event : status is OK (2392157)[ 6.685] INFO ziti-sdk:posture.c:206 ziti_send_posture_data() ztx[0] first run or potential controller restart detected (2392157)[ 7.199] INFO ziti-sdk:channel.c:272 new_ziti_channel() ch[0] (router-public) new channel for ztx[0] identity[EC2-public] (2392157)[ 7.199] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1052 on_ziti_event() ztx[EC2-public] added edge router router-public@ziti-router-public.example.com (2392157)[ 7.199] INFO ziti-sdk:channel.c:801 reconnect_channel() ch[0] reconnecting NOW (2392157)[ 13.353] INFO ziti-edge-tunnel:tun.c:196 tun_commit_routes() starting 1 route updates (2392157)[ 13.370] INFO ziti-edge-tunnel:tun.c:118 route_updates_done() route updates[1]: 0/OK (2392157)[ 13.426] INFO ziti-sdk:channel.c:699 hello_reply_cb() ch[0] connected. EdgeRouter version: v1.1.15|0eec47ce3c80|2024-10-02T12:59:41Z|linux|amd64 (2392157)[ 13.426] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1056 on_ziti_event() ztx[EC2-public] router router-public connected
-
ziti-edge-tunnel
logs from EC2-private:About to run tunnel service... ziti-edge-tunnel (2758075)[ 0.000] INFO ziti-sdk:utils.c:198 ziti_log_set_level() set log level: root=3/INFO (2758075)[ 0.000] INFO ziti-sdk:utils.c:167 ziti_log_init() Ziti C SDK version 1.2.1 @g9db50a3(HEAD) starting at (2024-12-20T15:37:58.608) (2758075)[ 0.000] INFO tunnel-sdk:ziti_tunnel.c:60 create_tunneler_ctx() Ziti Tunneler SDK (v1.2.9) (2758075)[ 0.000] INFO tunnel-cbs:ziti_dns.c:173 seed_dns() DNS configured with range 100.64.0.0 - 100.127.255.255 (4194302 ips) (2758075)[ 0.000] INFO ziti-edge-tunnel:ziti-edge-tunnel.c:894 make_socket_path() effective group set to 'ziti' (gid=989) (2758075)[ 0.007] WARN ziti-edge-tunnel:instance.c:39 find_tunnel_identity() Identity ztx[EC2-private] is not loaded yet or already removed. (2758075)[ 0.007] INFO ziti-edge-tunnel:resolvers.c:68 init_libsystemd() Initializing libsystemd (2758075)[ 0.007] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1135 load_ziti_async() attempting to load ziti instance[EC2-private] (2758075)[ 0.007] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1142 load_ziti_async() loading ziti instance[EC2-private] (2758075)[ 0.007] INFO ziti-edge-tunnel:ziti-edge-tunnel.c:402 load_id_cb() identity[EC2-private] loaded (2758075)[ 0.007] INFO ziti-sdk:ziti.c:425 ziti_start_internal() ztx[0] enabling Ziti Context (2758075)[ 0.007] INFO ziti-sdk:ziti.c:442 ziti_start_internal() ztx[0] using tlsuv[v0.32.8/OpenSSL 3.3.1 4 Jun 2024] (2758075)[ 0.007] INFO ziti-sdk:ziti_ctrl.c:604 ziti_ctrl_init() ctrl[(null):] using https://ziti-controller.example.com:443/edge/client/v1 (2758075)[ 0.007] INFO ziti-sdk:ziti.c:512 ztx_init_controller() ztx[0] Loading ziti context with controller[https://ziti-controller.example.com:443/edge/client/v1] (2758075)[ 0.049] INFO ziti-sdk:ziti.c:1778 version_pre_auth_cb() ztx[0] connected to Legacy controller https://ziti-controller.example.com:443/edge/client/v1 version v1.1.15(0eec47ce3c80 2024-10-02T12:59:41Z) (2758075)[ 0.063] INFO tunnel-cbs:ziti_tunnel_ctrl.c:981 on_ziti_event() ziti_ctx[EC2-private] connected to controller (2758075)[ 0.063] INFO ziti-edge-tunnel:ziti-edge-tunnel.c:440 on_event() ztx[EC2-private] context event : status is OK (2758075)[ 0.134] INFO ziti-sdk:channel.c:272 new_ziti_channel() ch[0] (router-private) new channel for ztx[0] identity[EC2-private] (2758075)[ 0.134] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1052 on_ziti_event() ztx[EC2-private] added edge router router-private@ziti-router-private.example.com (2758075)[ 0.134] INFO ziti-sdk:channel.c:801 reconnect_channel() ch[0] reconnecting NOW (2758075)[ 0.141] INFO ziti-edge-tunnel:tun.c:196 tun_commit_routes() starting 1 route updates (2758075)[ 0.143] INFO ziti-edge-tunnel:tun.c:118 route_updates_done() route updates[1]: 0/OK (2758075)[ 0.165] INFO ziti-sdk:channel.c:699 hello_reply_cb() ch[0] connected. EdgeRouter version: v1.1.15|0eec47ce3c80|2024-10-02T12:59:41Z|linux|amd64 (2758075)[ 0.165] INFO tunnel-cbs:ziti_tunnel_ctrl.c:1056 on_ziti_event() ztx[EC2-private] router router-private connected (2758075)[ 0.165] INFO ziti-edge-tunnel:resolvers.c:402 try_libsystemd_resolver() systemd-resolved selected as DNS resolver manager (2758075)[ 1.058] INFO ziti-sdk:posture.c:206 ziti_send_posture_data() ztx[0] first run or potential controller restart detected
-
ifconfig
output from EC2-public:eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 10.10.10.29 netmask 255.255.255.0 broadcast 10.10.10.255 inet6 fe80::ba27:ebff:fe0c:a935 prefixlen 64 scopeid 0x20<link> ether b8:27:eb:0c:a9:35 txqueuelen 1000 (Ethernet) RX packets 440588377 bytes 522850420062 (486.9 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 215353337 bytes 17076616432 (15.9 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 36013881 bytes 5975687878 (5.5 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 36013881 bytes 5975687878 (5.5 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ziti0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500 inet 100.64.0.1 netmask 255.255.255.255 destination 100.64.0.1 inet6 fe80::89c2:7484:c7b:9637 prefixlen 64 scopeid 0x20<link> unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC) RX packets 2919 bytes 297279 (290.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 2937 bytes 273446 (267.0 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
-
ifconfig
output from EC2-private:ens5: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9001 inet 192.168.14.181 netmask 255.255.240.0 broadcast 192.168.15.255 inet6 fe80::e0:10ff:fe11:5eb1 prefixlen 64 scopeid 0x20<link> ether 02:e0:10:11:5e:b1 txqueuelen 1000 (Ethernet) RX packets 7418657 bytes 1865728819 (1.7 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 7933658 bytes 3494499519 (3.2 GiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ens6: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 9001 inet 192.168.65.56 netmask 255.255.224.0 broadcast 192.168.95.255 inet6 fe80::8e:7bff:fec9:711f prefixlen 64 scopeid 0x20<link> ether 02:8e:7b:c9:71:1f txqueuelen 1000 (Ethernet) RX packets 1659663 bytes 1590998141 (1.4 GiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 1315295 bytes 111982452 (106.7 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 lo: flags=73<UP,LOOPBACK,RUNNING> mtu 65536 inet 127.0.0.1 netmask 255.0.0.0 inet6 ::1 prefixlen 128 scopeid 0x10<host> loop txqueuelen 1000 (Local Loopback) RX packets 84 bytes 10614 (10.3 KiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 84 bytes 10614 (10.3 KiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 ziti0: flags=4305<UP,POINTOPOINT,RUNNING,NOARP,MULTICAST> mtu 1500 inet 100.64.0.1 netmask 255.255.255.255 destination 100.64.0.1 inet6 fe80::eb3a:226:1135:c53a prefixlen 64 scopeid 0x20<link> unspec 00-00-00-00-00-00-00-00-00-00-00-00-00-00-00-00 txqueuelen 500 (UNSPEC) RX packets 15655 bytes 1315020 (1.2 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 15669 bytes 1315692 (1.2 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0
Requirements:
- Enable communication from
EC2-private
toEC2-public
over the Ziti overlay to access the application (Apache in this case) running onEC2-public
. - Resolve the issue of both
ziti0
interfaces having the same IP (100.64.0.1
), which prevents proper routing and makes direct communication impossible. - Provide a step-by-step guide for configuring the necessary Ziti services and policies to facilitate this setup.
Questions:
- What specific Ziti service and policy configurations are required to enable this communication?
- How can the issue of identical IPs (
100.64.0.1
) for theziti0
interfaces be addressed effectively? - Is there a recommended approach to debug and ensure successful routing for the traffic in this scenario?
Any guidance or insights to resolve this issue would be greatly appreciated. Thank you!