Currently exploring the use of OpenZiti. I have a containerised router set up to facilitate user access to some services running in their own containers (all docker compose). So far, so good. Now I need containerised service A to be able to communicate with another service on my ziti overlay, but I’m struggling to find any documentation or reference implementation - can anyone provide any pointers here? How do I “tell” a service container to use a router running in another container for openziti services? And how do I define an appropriate dial policy? Appreciate any guidance or pointers to documentation - thanks!
Hello @nibble can you share a network diagram, on how you did your current setup? I am not a moderator but can help a little
Hi @nibble, this is a modestly complex deployment. Docker allows one the use of one container as another container's network. The functionality is the network_mode: service:${container} pattern.
You can see examples of this on this page of the doc Deploy the Router with Docker | NetFoundry Documentation
Basically you first need to configure a router similar to:
ziti-router:
dns:
- 127.0.0.1
- 1.1.1.1
user: root
cap_add:
- NET_ADMIN
networks:
- whatever-network
Then when adding a second container, you assign this router container as the new target container's network_mode:
demo-container:
....
network_mode: service:ziti-router
....
Hope that helps
Oh and I forgot to say: Hi @nibble, welcome to the community and to OpenZiti! ![]()
From what I can tell this lets Container A1 “have” the same network config as Container X - including the ability to communicate outbound to other networks / internet. I’m trying to avoid this; I want highly restrictive outbound as well as inbound given the workloads running on the container. Any further thoughts on how to achieve this? Thanks.
Restricting the outbound network is not in scope of OpenZiti in that way. Your post was about dialing outbound ziti services from containers. What i shared is that mechanism. Yes it basically melds two containers together and both share the same network in effect. If you want to restrict what the containers can access outbound, you'd have to do that with docker/host firewalling. That's not something OpenZiti would do though
Yeah I’m not expecting OpenZiti to put in place an outbound restriction - just trying to work out how to combine multiple elements to achieve the desired result of having isolated containers with the only entry/exit being OpenZiti, and given that outbound filtering managed by Docker seems to be non-existant…
You can restrict outbound networking from your Ziti-enhanced Docker Compose network (i.e., the bridge network managed by your compose.yaml).
First, I'll give you an overview of the relevant Linux networking concepts and then an example Docker Compose YAML and Linux commands to control outbound networking.
Linux Networking for Docker Containers
Since Docker containers rely on features of the Linux kernel like process control groups, you always have Linux networking at your disposal when using Docker containers.
The default network mode for containers is "bridge", which is a subnet attached to a virtual network interface on the Docker host. This means the Docker host is the default gateway for the bridge network, so you can control egress through firewall rules assigned to that interface.
The default interface name isn't predictable. Still, you can define a name so that it is predictable, and maintain permanent rules that are reliably enforced on that interface, where the bridge's containers can only egress through that interface.
For example, if your Docker bridge network has a subnet 172.21.0.0/16 and the containers attached to that network have an IP router/gateway at 172.21.0.1, then the Docker host's IP address on that network is 172.21.0.1. Each container on that network has an IP address in that subnet, e.g., 172.21.0.11, and all traffic between those containers and other networks, e.g., the internet, flows through the Docker host's IP address, which serves as the router for that network.
❯ ipcalc 172.21.0.0/16
Address: 172.21.0.0 10101100.00010101. 00000000.00000000
Netmask: 255.255.0.0 = 16 11111111.11111111. 00000000.00000000
Wildcard: 0.0.255.255 00000000.00000000. 11111111.11111111
=>
Network: 172.21.0.0/16 10101100.00010101. 00000000.00000000
HostMin: 172.21.0.1 10101100.00010101. 00000000.00000001
HostMax: 172.21.255.254 10101100.00010101. 11111111.11111110
Broadcast: 172.21.255.255 10101100.00010101. 11111111.11111111
Hosts/Net: 65534 Class B, Private Internet
Example
Take this compose.yaml as an example. You will need to audit and substitute your preferred ports, domains, etc., in this example.
myapp-client:
image: busybox
network_mode: "service:ziti-router"
depends_on:
- ziti-router
ziti-router:
depends_on:
chown-router:
condition: service_completed_successfully
image: openziti/ziti-router:1.7.1
dns:
- 127.0.0.1 # Ziti nameserver
- 1.1.1.1 # a nameserver for resolving non-Ziti names
user: root
cap_add:
- NET_ADMIN
networks:
- ziti-egress
ports:
- 0.0.0.0:443:443
expose:
- 443
volumes:
- ziti-router:/ziti-router
environment:
ZITI_CTRL_ADVERTISED_ADDRESS: ctrl1.ziti.example.com
ZITI_CTRL_ADVERTISED_PORT: 443
ZITI_ENROLL_TOKEN: mylong.base64.jwtsegments
ZITI_ROUTER_ADVERTISED_ADDRESS: router1.ziti.example.com
ZITI_ROUTER_PORT: 443
ZITI_ROUTER_MODE: tproxy # transparent interception w/ Ziti nameserver
restart: unless-stopped
healthcheck:
test:
- CMD
- ziti
- agent
- stats
interval: 3s
timeout: 3s
retries: 5
start_period: 15s
chown-router:
image: busybox
command: chown -R ${ZIGGY_UID:-2171} /ziti-router
volumes:
- ziti-router:/ziti-router
volumes:
ziti-router:
networks:
ziti-egress:
driver: bridge
driver_opts:
com.docker.network.bridge.name: 'br-ziti-egress'
Finally, write firewall rules to restrict any unexpected outbound traffic. Now that your Docker network has a predictable name, br-ziti-egress, you could add a reject rule to the end of the chain so that no traffic is routed via that interface unless it matches one of your exceptions. Then, the containers in your Compose project will be unable to egress to anywhere unless explicitly allowed. You will need exceptions for the Ziti router's controller endpoint, e.g., ctrl1.ziti.example.com, and for the public link listener addresses advertised by your other Ziti routers, if any, e.g. router2.ziti.example.com. You'll also need exceptions for your recursive nameservers, e.g., 1.1.1.1.
