Guides
Examples
Four complete Isoloom specs: a two-machine application, a segmented network with a DMZ, an edge firewall, and an Active Directory domain.
These four specs ship in the Isoloom repository under examples/, and its tests check that
each gets exactly the targets listed here.
A two-machine application
A web API and its database. Both machines have both implementations: every target.
version: 1
name: supplier-portal-api
networks:
lab: { cidr: 10.20.0.0/24 }
inputs: [API_URL, LAUNCH_TOKEN]
machines:
database:
networks: { lab: 32 }
services: [{ port: 3207, name: mysql }]
inputs: [API_URL, LAUNCH_TOKEN]
docker: { image: "mysql:8.0", init: [build/database/init] }
vm: { os: debian-12, provision: [provision/database.sh] }
web:
networks: { lab: 31 }
services: [{ port: 3206, name: portal, http: true }]
depends_on: [database]
docker: { build: build/web }
vm: { os: debian-12, provision: [provision/web.sh] }
checks: [build/check/check.sh]
A segmented network
A gateway in a DMZ, an application and a database behind it, and the user's machine that only sees the DMZ. Every target; the user's machine is supplied by the runner.
version: 1
name: pivot-dmz
networks:
dmz: { cidr: 10.30.10.0/24 }
internal: { cidr: 10.30.20.0/24, internet: false }
access: { cidr: 10.30.99.0/24 }
reach:
- { from: access, to: dmz }
- { from: dmz, to: internal, ports: [8080, 5432] }
machines:
gateway:
networks: { dmz: 10, internal: 10 }
services: [{ port: 80 }, { port: 22 }]
docker: { build: build/gateway }
vm: { os: debian-12, provision: [provision/gateway.yml] }
app:
networks: { internal: 20 }
services: [{ port: 8080 }]
docker: { build: build/app }
vm: { os: debian-12, provision: [provision/app.yml] }
db:
networks: { internal: 30 }
services: [{ port: 5432 }]
docker: { image: "postgres:16" }
vm: { os: debian-12, provision: [provision/db.yml] }
user:
access: true
networks: { access: 10 }
vm: { os: kali }
checks:
- checks/dmz-reachable.sh
- checks/internal-not-reachable-from-access.sh
An edge firewall
A Linux firewall routes a DMZ and an offline LAN with its own nftables rules: the web server is reachable from outside on port 80, the DMZ reaches the cache on the LAN, and nothing else crosses. Every target; it runs for real in CI on Docker, and was verified on VirtualBox.
version: 1
name: edge-firewall
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] }
web:
networks: { dmz: 10 }
services: [{ port: 80, http: true }]
docker: { build: build/web }
vm: { os: debian-12, provision: [provision/web.sh] }
cache:
networks: { lan: 20 }
services: [{ port: 6379, name: redis }]
docker: { image: "redis:7-alpine" }
vm: { os: debian-12, provision: [provision/cache.sh] }
user:
access: true
networks: { outside: 10 }
vm: { os: debian-12 }
checks:
- checks/web-through-firewall.sh
- checks/lan-blocked.sh
Here reach isn't enforced by Isoloom: it documents what the firewall's rules should allow,
and the checks prove it.
An Active Directory domain
A domain controller, a workstation and a web server in a DMZ. The Windows machines have no
container form, so: VM targets only (vagrant, proxmox, cloud-vm, ludus).
version: 1
name: corp-ad-basics
networks:
dmz: { cidr: 10.40.10.0/24 }
corp: { cidr: 10.40.20.0/24 }
access: { cidr: 10.40.99.0/24 }
reach:
- { from: access, to: dmz }
- { from: dmz, to: corp }
machines:
dc01:
networks: { corp: 5 }
services: [{ port: 53 }, { port: 88 }, { port: 389 }, { port: 445 }]
resources: { cpus: 2, memory_mb: 4096, disk_gb: 60 }
vm: { os: windows-server-2022, provision: [provision/ad-domain.yml] }
ws01:
networks: { corp: 21 }
depends_on: [dc01]
resources: { cpus: 2, memory_mb: 4096, disk_gb: 60 }
vm: { os: windows-11, provision: [provision/ad-join.yml, provision/ws01.yml] }
web01:
networks: { dmz: 10, corp: 10 }
services: [{ port: 80 }]
docker: { build: build/web01 }
vm: { os: debian-12, provision: [provision/web01.yml] }
user:
access: true
networks: { access: 10 }
checks:
- checks/domain-up.sh
- checks/web01-reaches-dc01.sh
web01 could be a container, but the environment can't run on Docker without its domain
controller: targets are all or nothing.