Skip to content

Reference

Networks and gateways

How Isoloom describes networks, reachability between them and firewalls on the edge of the network, and how each target enforces it.

Networks and addresses

Each network is an address block; each machine picks its last octet on every network it joins. Machines resolve each other by name on every target, so setup scripts use database, never an IP.

networks:
  app: { cidr: 10.20.0.0/24 }
machines:
  database: { networks: { app: 32 }, … }
  web:      { networks: { app: 31 }, … }

Reach between networks

Machines on the same network always see each other. Between networks, reach: lists what's allowed and everything else is blocked:

reach:
  - { from: access, to: dmz }
  - { from: dmz, to: internal, ports: [8080] }

Isoloom enforces these rules with a router it adds itself (isoloom-router, on every network at its last address), using each target's own tools:

TargetRouter
DockerA router container with nftables; each machine routes the other networks through it (a small sidecar sets the routes inside the machine's own network namespace, so images need nothing special)
VagrantA router VM with nftables; each VM gets its routes from a boot-time service
Proxmox, cloudPlanned (an SDN network per environment; subnets and security rules)

Everything between networks is dropped except what reach allows, and replies to allowed traffic. Machines on other networks still resolve by name.

That router is infrastructure: it isn't part of what the environment is about.

No internet

internet: false cuts a network off from the internet. A machine has internet only if at least one of its networks does. On Docker, an offline machine has no default route; on VMs, new outbound connections through the VM's NAT interface are blocked once it's provisioned (so it can still install its packages first).

A firewall that belongs to the environment

Sometimes the firewall is the subject: an edge firewall, a Linux router with port forwarding, an exposed admin interface. That firewall is a machine, attached to every network it routes at the gateway address, and those networks name it as their gateway:

networks:
  outside: { cidr: 10.70.0.0/24 }
  dmz:     { cidr: 10.70.10.0/24, gateway: fw }
  lan:     { cidr: 10.70.20.0/24, gateway: fw, internet: false }

reach:
  - { from: outside, to: dmz, ports: [80] }
  - { from: dmz, to: lan, ports: [6379] }

machines:
  fw:
    networks: { outside: 2, dmz: 1, lan: 1 }
    services: [{ port: 8080, name: status, http: true }]
    docker: { build: build/fw }
    vm: { os: debian-12, provision: [provision/fw.sh] }
  • On a network with a gateway:, Isoloom adds no router of its own. The gateway takes the gateway address (.1), gets forwarding turned on, and its own configuration sets the rules (the same nftables file for its container and its VM, in the example).
  • The machines behind it send everything through it: routes to the other networks, and their default route, so the gateway also decides what reaches the internet. Machines on the gateway's other networks reach the networks it routes through it.
  • reach: and internet: on those networks stop being something Isoloom enforces and become expected behavior, which the checks verify.
  • Machines behind a gateway start after it. A machine can't both be behind a gateway and be one of its dependencies.

How each target does it:

TargetBehind the gateway
DockerDocker's own address moves to the last address of the network; a sidecar sets the machine's routes once the gateway answers
VagrantThe machine installs its software through the VM's NAT interface, then moves behind the gateway: new connections out through NAT are blocked (name lookups excepted) and the default route goes through the gateway

The complete, tested version is the edge firewall example.

Planned: appliance images such as OPNsense or pfSense (os: opnsense). A firewall with no container form makes the environment VM-only, unless you also provide a Linux container that behaves the same and passes the same checks.