Skip to content

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.