Deployment guide

MITRE Caldera

Overview

MITRE Caldera is an open-source adversary emulation platform maintained by MITRE. It automates the work of a red team. You choose an adversary profile assembled from a library of abilities mapped to MITRE ATT&CK, and Caldera plans the sequence, deploys agents to the hosts in scope, executes each step and collects the results. Blue-team plugins support the defensive side of the same exercise. Security teams use Caldera to test, repeatably, whether their detection and response work.

Functionally, Caldera is command-and-control (C2) infrastructure: the server issues instructions that agents execute on target hosts. That is what makes it powerful, and it is why you must run it carefully. Upstream's own documentation states that the web interface is "not hardened and thoroughly pentested" and should be deployed on isolated networks rather than exposed to the public internet. The SecureAnyCloud image is built around that guidance.

The image installs Caldera 5.3.0 at /opt/caldera in a dedicated Python virtual environment. Caldera runs as the non-login caldera user, bound to loopback 127.0.0.1:8888, behind nginx on port 80. The VueJS console is pre-built into the image, and the Go toolchain that the sandcat agent compiler needs is installed. You can build an adversary profile, deploy an agent and run an operation immediately after launch.

Closed by default, because this is C2. Upstream's sample configuration publishes working logins (red/admin, admin/admin, blue/admin) and API keys (ADMIN123, BLUEADMIN123). The image treats every one of them as compromised. It removes them from the tree, refuses them at runtime, and empties the seeded user map, so even an insecure server start yields no working login. On the first boot of every instance, a one-shot service generates seven per-VM secrets and writes them to a root-only file. The secrets are the reverse-proxy gate password, the red and blue account passwords, the red and blue REST API keys, the encryption key and the salt.

No open interface. The nginx reverse proxy enforces HTTP Basic Authentication across the whole platform: the console, the entire REST API, agent tasking, ability execution and file upload. Only a static, unauthenticated /healthz probe is left open for load balancers. Behind the gate, Caldera enforces its own per-VM accounts and API keys.

No published C2 port. Caldera's defaults expose six agent-contact listeners on all interfaces (HTTP 8888, DNS 8853, SSH-tunnel 8022, FTP 2222, TCP 7010, UDP 7011, WebSocket 7012). In this image, every one is bound to 127.0.0.1, so a freshly launched VM publishes no command-and-control port. Opening a contact for a real engagement is a deliberate step, described later in this guide.

Authorised use only. Caldera is adversary-emulation infrastructure. Use it only against systems that you are explicitly authorised to test. Before you expose this VM to anything, restrict its Azure network security group to your own source IP address, as described in the first section below.

What you get:

  • MITRE Caldera 5.3.0 (Apache-2.0), pinned to the release tag with its plugin submodules pinned to the exact commits that tag records
  • caldera.service bound to 127.0.0.1:8888, running as the dedicated non-login caldera user, gated so it cannot start before per-VM secrets exist
  • The pre-built magma VueJS console, the ATT&CK-mapped stockpile ability library, and the Go toolchain the sandcat agent compiler requires
  • No prebuilt offensive payload binaries. The Atomic Red Team plugin and the precompiled Windows tools and agent binaries bundled in upstream's plugin trees are not shipped. Sandcat agents are compiled on demand from Go source, and you upload any payload your engagement needs through the console's payloads page
  • nginx reverse proxy on port 80 with per-VM HTTP Basic Auth over everything except /healthz, ready for your TLS certificate
  • caldera-firstboot.service, which generates seven per-VM secrets, resolves the instance URL and proves that the auth gate is closed before it completes
  • Ubuntu 24.04 LTS base, patched at build time, unattended security upgrades enabled
  • 24/7 SecureAnyCloud support, 24h response SLA

Before you begin: scope the network security group to your own IP

This is the most important step, so complete it first. Because Caldera is C2 infrastructure, nobody but you should be able to reach the VM. In the Azure portal, open your VM's Networking blade and edit the inbound rule for port 80 (and 22). Set the Source to your own IP address rather than Any/0.0.0.0/0. Alternatively, use the Azure CLI:

# Replace with YOUR public IP (find it with:
curl -s https://ifconfig.me) MY_IP="203.0.113.10" az network nsg rule update \
  --resource-group <your-rg> \
  --nsg-name <your-nsg> \
  --name <the-inbound-web-rule> \
  --source-address-prefixes "${MY_IP}/32"

Complete this step before you retrieve credentials or open the console.

Connect and retrieve your per-VM credentials

Connect to the VM over SSH as azureuser, then read the credentials file. The file is generated uniquely on this instance at first boot and is readable only by root.

sudo cat /root/caldera-credentials.txt

Example output (the values shown are illustrative, and yours are unique to this VM):

# MITRE Caldera 5.3.0 - Per-VM Credentials
# Generated on first boot by caldera-firstboot.service. Unique to THIS VM. Store them safely. CALDERA_URL=http://<this-vm-public-ip>/ CALDERA_WEB_USER=caldera CALDERA_WEB_PASSWORD=<CALDERA_WEB_PASSWORD> CALDERA_RED_USER=red CALDERA_RED_PASSWORD=<CALDERA_RED_PASSWORD> CALDERA_BLUE_USER=blue CALDERA_BLUE_PASSWORD=<CALDERA_BLUE_PASSWORD> CALDERA_API_KEY_RED=<CALDERA_API_KEY_RED> CALDERA_API_KEY_BLUE=<CALDERA_API_KEY_BLUE>

The image uses two authentication layers by design:

  • The nginx gate. Use CALDERA_WEB_USER / CALDERA_WEB_PASSWORD. The browser prompts for them before anything else loads.
  • Caldera's own login. Sign in as red (offensive) or blue (defensive) with CALDERA_RED_PASSWORD / CALDERA_BLUE_PASSWORD on Caldera's login page.

Verify the service and the health endpoint

Confirm that both services are active and that the unauthenticated health probe answers:

sudo systemctl status caldera nginx --no-pager | head -18 curl -s -o /dev/null -w '%{http_code}\n' http://127.0.0.1/healthz

caldera.service and nginx.service should both report active (running), and the /healthz probe should print 200.

Confirm the platform is closed to unauthenticated callers

The /healthz probe is the only path reachable without a credential. Everything else returns 401 unless you present the per-VM gate credential. That includes the console, the REST API, agent tasking, ability execution and file upload. The image ships a helper that proves this end to end. It includes a positive control, in which the same requests succeed with the real credential, and a check that the published upstream defaults are refused:

sudo /usr/local/sbin/caldera-cred-roundtrip.sh

Expected output:

OK: gate closed unauthenticated (UI 401, agents 401, operations 401, file-upload 401, wrong-pass 401); OK: positive control passed (UI 200 and /api/v2/agents 200 with the per-VM credential); OK: published upstream default API key ADMIN123 refused (401); OK: published upstream default login red/admin issued NO session, while the per-VM red OK: credential DID - asserted on the API_SESSION cookie, not on /enter's always-302 status.

Confirm no command-and-control port is published

List every listening socket and confirm that only SSH (22) and the nginx gate (80) are bound to a non-loopback address. Every Caldera agent-contact listener is bound to 127.0.0.1:

sudo ss -lntu sudo /usr/local/sbin/caldera-listener-audit.sh | tail -3

The audit prints LISTENER-AUDIT OK: only tcp:22 tcp:80 udp:68 are publicly bound; every Caldera agent contact is loopback-only. (udp:68 is the OS DHCP client, not an application listener.)

Open the console

In a browser, go to CALDERA_URL (http://<this-vm-public-ip>/). The nginx gate prompts you first, so enter CALDERA_WEB_USER / CALDERA_WEB_PASSWORD. Caldera's own login page then appears. Sign in as red with CALDERA_RED_PASSWORD.

The abilities view shows the ATT&CK-mapped stockpile library that adversary profiles are built from. Over 150 abilities ship in the image, and you can add your own or enable further ability plugins:

Run your first operation against a local agent

The quickest way to see Caldera work end to end is to deploy an agent on the VM itself and run a small operation against it. This is a self-contained demonstration on a host that you already control.

  • In the console, open agents and select Deploy an agent. Choose the Sandcat agent and platform linux, and set the server address to http://127.0.0.1:8888. Copy the generated one-line delivery command.
  • Connect to the VM over SSH and paste that command. It downloads the compiled agent and starts it, and the agent registers within a few seconds.
  • Return to agents. The new agent appears as alive and trusted, with its host, PID, platform and privilege.
  • Open operations and select New Operation. Choose an adversary profile (for example, a simple discovery profile) and the group that your agent joined, and start the operation. When it finishes, expand a link and select View Output to see the command output that the agent returned through the C2 channel.

This round trip, in which the agent runs a real command and the result comes back, is the core of the platform.

Drive Caldera from the REST API

Every action in the console is also available over the REST API. The API is gated by both the nginx credential and a Caldera API key. Send the API key in the KEY header:

# From the VM (loopback bypasses the nginx gate); off-box, add -u "$CALDERA_WEB_USER:$CALDERA_WEB_PASSWORD"
KEY=$(sudo grep '^CALDERA_API_KEY_RED=' /root/caldera-credentials.txt | cut -d= -f2-)
curl -s -H "KEY: ${KEY}" http://127.0.0.1:8888/api/v2/agents | head -c 400

The call returns the JSON list of registered agents. The full API documentation is available in the console under api docs.

Running against remote hosts (advanced)

By default, this image publishes no C2 port, so agents can reach the server only over loopback, as in the demonstration above. To run an engagement against remote hosts that you are authorised to test, deliberately expose the contact that you need:

  • Edit /opt/caldera/conf/local.yml and change the relevant app.contact.* binding from 127.0.0.1 to 0.0.0.0. For the HTTP contact, also set host: 0.0.0.0. Keep every contact that you are not using on loopback.
  • Restart Caldera with sudo systemctl restart caldera.
  • Add an inbound Azure NSG rule for that specific port, scoped to the source ranges of the hosts in scope. Never use 0.0.0.0/0.
  • Generate agents that point at your VM's public address from the agents view.

Treat an exposed contact as live C2. Keep the NSG tightly scoped, remove the rule when the engagement ends, and never leave a contact open to the internet.

Verify the shipped software provenance

The image records the exact Caldera version and the pinned plugin submodule commits on disk:

head -12 /opt/caldera/.sac-plugin-pins.txt

TLS

nginx serves plain HTTP on port 80 out of the box, so you can reach the console immediately behind your scoped NSG. For any real use, put TLS in front of it. Point a DNS name at the VM and issue a certificate with your own ACME client, or use an existing certificate. Then add a listen 443 ssl; server block to the nginx site at /etc/nginx/sites-available/sac-caldera and reload nginx. Caldera derives its URLs from the request host, so no application reconfiguration is needed.

Support

This image includes 24/7 SecureAnyCloud support with a 24-hour response SLA. Our engineers can help with Caldera deployment, per-instance credential management and the reverse-proxy gate, agent deployment and contact configuration, building adversary profiles and custom abilities, running and interpreting operations, REST API automation, plugin and version upgrades, and reverse-proxy and TLS configuration. Email sales@secureanycloud.com.

This image is a repackaged open-source software product, and SecureAnyCloud support services carry additional charges. Caldera and ATT&CK are trademarks of The MITRE Corporation. All product and company names are trademarks or registered trademarks of their respective holders. Their use does not imply any affiliation with or endorsement by them.

Deploy on Azure

Launch MITRE Caldera on Ubuntu 24.04 LTS on Azure with 24/7 support from SecureAnyCloud.

View this image

Need Help?

Our support team is available 24/7.

sales@secureanycloud.com

Deploy on Azure