Skip to content

Oracle Cloud (OCI) Setup ​

What "Oracle" means in this project ​

Read this first: there is no Oracle Database

The repository contains no Oracle Database: no oracledb or cx_Oracle driver, no JDBC URL, no port 1521, no sqlplus, no schemas or database users. The platform's relational data is stored in SQLite (see Database) and identities in Keycloak.

"Oracle" here means Oracle Cloud Infrastructure (OCI), the cloud provider that hosts the whole platform on one Ampere A1 virtual machine. The questions "which Oracle users, schemas and services does it use?" therefore have the answer not applicable; the OCI resources below are what the project actually depends on.

Why OCI ​

The operator manual sizes everything around OCI's Always Free allowance: 2 OCPU, 12 GiB RAM and 200 GB of block storage per tenancy, enough for exactly one Ampere A1 VM. This lets the capstone run a real multi-service lab platform at no cloud cost. The deployment profile oci_12gib in the code is tuned for this host (one concurrent lab, Wazuh manager only, native Keycloak) (manual/README.md, manual/M4 to Ampere Guide for First-Time OCI.md, cyberrange/src/provisioning/profiles.py).

Where OCI fits in the architecture ​

OCI resources used ​

ResourceSettingSource
Tenancy / regionAlways Free tenancy; the VM must be in the home regionmanual/M4 to Ampere Guide for First-Time OCI.md
CompartmentThe default compartmentsame
Instance shapeVM.Standard.A1.Flex, 2 OCPU / 12 GiB (the older 4 OCPU / 24 GiB Always Free shape is noted as no longer free)same, manual/01-oci-host-and-network.md
ImageUbuntu 24.04 (Minimal) aarch64; not Oracle Linux, not amd64 (golden images are ARM64)same
Boot volumeabout 50 GB (counts toward the 200 GB)same
Block volume150 GB attached as /dev/sdb, formatted btrfs, mounted at /mnt/ampere-lxd, used as the LXD storage poolmanual/01-oci-host-and-network.md, manual/appendix-network-map.md
NetworkVCN with a public subnet; ephemeral public IPv4 used only for operator SSHmanual/01-oci-host-and-network.md
Security listIngress TCP 22 from the operator's /32, ICMP types 3 and 4; egress allsame
SSH keyOperator key pair (the manual names it id_oci_arm64)same
Operator accountllms_admin (created during setup)same

Capacity errors

"Out of host capacity" means the availability domain has no free Ampere capacity. The manual says to wait or try another availability domain, and not to switch to a bigger or AMD shape.

Setup, step by step (summary of Chapter 01) ​

The authoritative, command-by-command procedure is manual/01-oci-host-and-network.md. The sequence is:

  1. Create the instance in the OCI console with the shape, image, VCN, subnet, public IP and SSH key above; create and attach the 150 GB block volume.

  2. First SSH as ubuntu, confirm uname -m is aarch64, 2 CPUs and about 11 GiB of memory.

  3. Create the operator user llms_admin and copy the SSH key to it.

  4. Format and mount the data disk (only /dev/sdb) as btrfs at /mnt/ampere-lxd and add it to /etc/fstab.

  5. Install LXD (snap), add llms_admin to the lxd group, initialize LXD and create the storage pool on the block volume.

  6. Fix the OCI packet filter before creating any container:

    bash
    cd ~/cyberrange
    sudo bash deploy/host/install_lxd_oci_iptables.sh
    # expected last line: lxd_oci_iptables=PASS

    OCI's Ubuntu images ship with a firewall (from oracle-cloud-agent) whose INPUT and FORWARD chains reject everything. Without the fix, LXD's DHCP never reaches containers and every container comes up without an address. The script inserts ACCEPT rules only for lxdbr0, vmbr1, lxdovn* and br-int, saves them to /etc/iptables/rules.v4, and installs cyberrange-lxd-iptables.service so they survive reboots. It opens nothing on the public interface.

  7. Prove container networking with a throwaway container:

    bash
    lxc init ubuntu:22.04 nettest </dev/null
    lxc start nettest </dev/null
    sleep 15
    lxc exec nettest -- ping -c2 1.1.1.1
    lxc delete -f nettest </dev/null
  8. Add swap with zram (cyberrange/deploy/host/setup_zram_and_swap.sh).

  9. Create the LXD bridge lxdbr0 at 10.115.77.1/24; later chapters add OVN (vmbr1, mgmt-net, mon-net).

  10. Lock the security list so TCP 22 accepts only the operator's /32 (the VCN wizard default is 0.0.0.0/0).

  11. Copy the code tree to ~/cyberrange and create ~/cyberrange-data with mode 700.

Ports: what is open and what must stay closed ​

PortServiceExposure
22SSHOpen to the operator's /32 only
80, 443WebClosed. Public access is the outbound Cloudflare Tunnel
3000PortalClosed; bound to 10.115.77.1
5000Provisioning APIClosed; bound to 10.115.77.1
8083KeycloakClosed; bound to 127.0.0.1 inside the gateway container
8765Terminal bridgeClosed; bound to 10.115.77.1
18301 to 18306DVWA lab proxiesClosed; intentionally vulnerable apps, never published
55000Wazuh APIClosed; LXD proxy on the host's 127.0.0.1. Since the Chapter 02 update (§4d) the API is also bound to 127.0.0.1 inside the manager container, so it is not reachable on the manager's 10.0.40.10 address from peered lab networks
8443LXD APIClosed; LXD is used through its Unix socket

Source: manual/01-oci-host-and-network.md, manual/appendix-network-map.md.

Connectivity and application integration ​

  • Operator access: SSH to the public IP from the allowed address, as llms_admin.
  • User access: HTTPS through Cloudflare. cloudflared on the VM dials out on port 443, so OCI needs no inbound web rule (cyberrange/deploy/systemd/cloudflared.service).
  • Application settings for OCI: the env template cyberrange/env/oci-12gib.env.example sets PROFILE=oci_12gib and the capacity values (for example MAX_PODS), the storage pool name (LXD_STORAGE_POOL), bind addresses and database path. It also documents optional, commented-out switches such as the instructor scoring diagnostics (SCORING_DIAGNOSTICS_SCENARIOS, SCORING_DIAGNOSTICS_RETENTION_DAYS). Values are placeholders; the real file is ~/cyberrange/env/.env (mode 600).
  • Resource profile: oci_12gib in cyberrange/src/provisioning/profiles.py: 1 concurrent lab, 4096 MB RAM reserved per lab plus a 1536 MB buffer, 7168 MB storage per lab, a 180000 MB storage limit, Wazuh manager only, native Keycloak.

Address ranges

The manual's guide notes the VCN private range 10.0.0.0/16 must not collide with the LXD bridge 10.115.77.0/24. The per-lab OVN subnets 10.0.51.0/24 to 10.0.56.0/24 are internal to OVN and NATed; they sit inside the VCN's /16 but not inside the host's 10.0.0.0/24 subnet. Needs verification that this overlap causes no routing issue for lab traffic to VCN addresses.

Troubleshooting OCI-specific problems ​

SymptomLikely causeFix
New containers have no IPv4; apt says "Network is unreachable"OCI packet filter rejects FORWARD/DHCPRun install_lxd_oci_iptables.sh; confirm lxd_oci_iptables=PASS and systemctl status cyberrange-lxd-iptables
SSH works from anywhereSecurity list still 0.0.0.0/0 on TCP 22Edit the rule to your /32
SSH times out after your IP changedSecurity list allows the old /32Update the rule in the OCI console
Cloudflare connector shows InactiveVM cannot reach Cloudflare on outbound 443Keep OCI egress HTTPS allowed; never add inbound 443
Create instance fails with out of capacityNo free A1 capacity in that availability domainRetry later or choose another availability domain; keep the A1 shape
Lab images fail with "exec format error"Wrong CPU architectureUse aarch64 images; build goldens with deploy/oci_build_goldens_arm64.sh

Sources

manual/README.md, manual/01-oci-host-and-network.md, manual/02-gateway-and-wazuh.md, manual/M4 to Ampere Guide for First-Time OCI.md, manual/Ampere Cloudflare Tunnel Guide for First-Time Operators.md, manual/appendix-network-map.md, cyberrange/docs/02_OCI_DEPLOY.md, cyberrange/deploy/host/install_lxd_oci_iptables.sh, cyberrange/env/oci-12gib.env.example, cyberrange/src/provisioning/profiles.py.

Cyber Range capstone documentation (Capstone 2 · Group 2 · A4102). Documents main at commit 6971373.