mirror of
https://github.com/alexmi256/rea-agent-docker.git
synced 2026-11-07 09:45:59 -10:00
`make check-updates` failed with BEHIND-REA on both Hopper rows: the vendor's
publisher-signed release feed moved its Ubuntu/Mint entry from Hopper 6.6.1 to
6.6.2 on 2026-11-06 16:22 UTC. REA 6.8.0 admits a Linux Hopper only when the
installed launcher is the feed's *current* main_exe_hash, so the old pin was
already wrong - and the build layer would have refused outright ("Hopper feed
moved: Hopper-6.6.2-Linux-demo.deb is no longer Hopper-6.6.1-Linux-demo.deb").
rea-agents itself is current: 6.8.0 is the newest npm release *and* the newest
github tag (v6.8.0, 2026-10-25), and its release notes list nothing pending for
Hopper beyond the feed-admission rule already implemented. So nothing else moved:
same REA_VERSION, same Node 24.22.1, same bundled skill (v49 / 229 tools), same
Ghidra 12.1.4, same helper tools (unicorn stays held at 2.1.2 because pwntools
4.15.0 excludes 2.1.3/2.1.4; Node 24.22.2, frida 17.26.1, uv 0.13.7,
supergateway 4.2.1, mitmproxy 12.3.1, pwndbg 2026.10.28 and Ghidra 12.2 are
newer upstream but wait for the next REA release per docs/UPDATES.md).
Re-pinned to the feed's row:
HOPPER_DEMO_VERSION 6.6.1 -> 6.6.2
HOPPER_DEB_SHA1 a2c28339..-> 9b46788160ba0b37f9050e0aa23a1372b3ecff53
HOPPER_DEB_BYTES 35749234 -> 35749280
HOPPER_LAUNCHER_SHA256 74b51599..-> 226800f154d766664bad5c45912f3a606ffa894316f97464f3c37f01fab5fb82
None of it was taken on trust: the .deb was downloaded (35,749,280 bytes,
sha1 9b467881...), its detached PGP signature verified against the vendor key
whose primary fingerprint is 7C2D73BAFAF5B9A710A69DA1A26DF815099B1BCD - the one
REA pins as HOPPER_LINUX_PRIMARY_FINGERPRINT - and opt/hopper/bin/Hopper hashed
out of the unpacked package (226800f1...), which is what the feed claims. The
build re-checks all four against the live feed, verifies bytes + SHA-1 and the
installed launcher, and bakes the signed evidence under
/home/rea/.cache/rea/hopper-releases/226800f1.../ (archive, release.json,
public-key.asc) so admission works offline; `rea doctor --provider hopper --json`
reports hopper-version healthy, reported_release_version 6.6.2,
source signed_package_cache.
Verified: scripts/build-all.sh (all four rebuilt; Hopper layer 3 min, the rest
cache hits), scripts/verify-all-engines.sh - all 121/0/3, ghidra 109/0/8, hopper
102/0/7, ida 94/0/11, 0 failures, exit 0 on every image; runs 20261107T091717Z /
20261107T092924Z / 20261107T094115Z / 20261107T094312Z. Counts are identical to
the 6.6.1 round; docs/verify-engines.txt regenerated and the sweep recorded in
docs/VERIFICATION.md. `make check-updates` is back to 0 actionable / 0 unknown /
0 unverifiable.
Docs that name the shipped Hopper build follow the pin (README, ARCHITECTURE,
MULTIARCH, BYO-LICENSES, TROUBLESHOOTING, vendor/README, the checker's header
comment); the 6.6.1 and 6.6.0 records in docs/VERIFICATION.md keep the versions
they actually ran.
282 lines
11 KiB
YAML
282 lines
11 KiB
YAML
# =============================================================================
|
|
# rea-agent : REA + full reverse-engineering toolchain, MCP-ready
|
|
#
|
|
# Four images, one service each - pick the engine you actually use:
|
|
#
|
|
# docker compose up -d # rea-agent (Ghidra + Hopper)
|
|
# docker compose --profile ghidra up -d rea-ghidra # Ghidra only
|
|
# docker compose --profile hopper up -d rea-hopper # Hopper only
|
|
# docker compose --profile ida up -d rea-ida # no engine; bring your own IDA
|
|
#
|
|
# Named services above are the reliable form: a plain `--profile ghidra up -d`
|
|
# also starts `rea-agent`, because a service without a profile always starts.
|
|
# `make up-ghidra` / `up-hopper` / `up-ida` do the right thing for you.
|
|
#
|
|
# Every image carries the same auxiliary toolchain (firmware extraction,
|
|
# captures, browsers, managed code, Android, debuggers, cross toolchains,
|
|
# binfmt/QEMU); the images differ only in the native analysis engine and in
|
|
# what /usr/local/share/rea/engine.env advertises. See docs/IMAGES.md.
|
|
#
|
|
# Optional overlays:
|
|
# -f compose.http.yml publish REA's MCP surface over Streamable HTTP
|
|
# -f compose.ida.yml IDA registration (IDA Pro / Home; see docs/ida-variants.md)
|
|
#
|
|
# Copy .env.example to .env and adjust before the first `up`.
|
|
# =============================================================================
|
|
name: rea-agent
|
|
|
|
# --- shared build arguments --------------------------------------------------
|
|
x-build-args: &build-args
|
|
REA_VERSION: ${REA_VERSION:-6.8.0}
|
|
NODE_VERSION: ${NODE_VERSION:-24.22.1}
|
|
GHIDRA_VERSION: ${GHIDRA_VERSION:-12.1.4}
|
|
GHIDRA_ZIP: ${GHIDRA_ZIP:-ghidra_12.1.4_PUBLIC_20260921.zip}
|
|
GHIDRA_SHA256: ${GHIDRA_SHA256:-}
|
|
HOPPER_DEB_URL: ${HOPPER_DEB_URL:-}
|
|
HOPPER_DEMO_VERSION: ${HOPPER_DEMO_VERSION:-6.6.2}
|
|
HOPPER_DEB_SHA1: ${HOPPER_DEB_SHA1:-9b46788160ba0b37f9050e0aa23a1372b3ecff53}
|
|
HOPPER_DEB_BYTES: ${HOPPER_DEB_BYTES:-35749280}
|
|
HOPPER_LAUNCHER_SHA256: ${HOPPER_LAUNCHER_SHA256:-226800f154d766664bad5c45912f3a606ffa894316f97464f3c37f01fab5fb82}
|
|
INSTALL_CHROME: ${INSTALL_CHROME:-1}
|
|
INSTALL_PLAYWRIGHT: ${INSTALL_PLAYWRIGHT:-1}
|
|
INSTALL_PWNDBG: ${INSTALL_PWNDBG:-1}
|
|
INSTALL_WINE: ${INSTALL_WINE:-1}
|
|
INSTALL_CROSS_TOOLCHAINS: ${INSTALL_CROSS_TOOLCHAINS:-1}
|
|
# vendor/ida/*.run is installed only when INSTALL_IDA=1
|
|
INSTALL_IDA: ${INSTALL_IDA:-auto}
|
|
REA_UID: ${REA_UID:-1000}
|
|
REA_GID: ${REA_GID:-1000}
|
|
|
|
# --- engine-independent runtime environment ---------------------------------
|
|
# Engine paths (GHIDRA_INSTALL_DIR, HOPPER_LAUNCHER_PATH, IDADIR) are NOT here:
|
|
# each service sets the ones its own image actually ships, and the image's
|
|
# /usr/local/share/rea/engine.env supplies them for `docker run` / bare `rea` invocations.
|
|
#
|
|
# NOTE: REA rejects *empty* values for its own REA_* settings
|
|
# ("configuration_invalid: Too small: expected string to have >=1 characters"),
|
|
# so optional settings are never listed with an empty default. Put them in
|
|
# ./config/rea.env (loaded through env_file, which only defines variables that
|
|
# are actually present).
|
|
x-rea-env: &rea-env
|
|
# --- auxiliary engines ------------------------------------------------
|
|
REA_PWNTOOLS_PYTHON: /opt/venvs/pwntools/bin/python
|
|
REA_PWNDBG_GDB: /usr/bin/gdb
|
|
REA_PWNDBG_GDBINIT: /opt/pwndbg/gdbinit.py
|
|
REA_PWNDBG_VENV_PATH: /opt/pwndbg/.venv
|
|
REA_WABT_BIN_DIRECTORY: /opt/wabt/bin
|
|
REA_JADX_MCP_JAR: /opt/jadx/jadx-headless-mcp-0.7.1-all.jar
|
|
REA_APKTOOL_COMMAND: /usr/local/bin/apktool
|
|
REA_ADB_PATH: /usr/bin/adb
|
|
REA_BINWALK_COMMAND: /usr/local/bin/binwalk
|
|
REA_UNBLOB_COMMAND: /opt/venvs/unblob/bin/unblob
|
|
REA_TSHARK_COMMAND: /usr/bin/tshark
|
|
REA_CAPINFOS_COMMAND: /usr/bin/capinfos
|
|
REA_SIGROK_COMMAND: /usr/bin/sigrok-cli
|
|
REA_MITMDUMP_COMMAND: /opt/venvs/mitmproxy/bin/mitmdump
|
|
REA_ILSPY_CMD_PATH: /opt/dotnet-tools/ilspycmd
|
|
# --- JDK (jadx, apktool, ilspycmd) and MCP client shaping -------------
|
|
JAVA_HOME: /usr/lib/jvm/java-21-openjdk-amd64
|
|
REA_MCP_INPUT_SCHEMA_PROFILE: ${REA_MCP_INPUT_SCHEMA_PROFILE:-compact}
|
|
REA_BROWSER_NO_SANDBOX: ${REA_BROWSER_NO_SANDBOX:-1}
|
|
PLAYWRIGHT_BROWSERS_PATH: /opt/ms-playwright
|
|
REA_LOG_LEVEL: ${REA_LOG_LEVEL:-info}
|
|
REA_ENTRYPOINT_DOCTOR: ${REA_ENTRYPOINT_DOCTOR:-1}
|
|
TMPDIR: /tmp/rea
|
|
|
|
# --- environment that only matters when an engine is present -----------------
|
|
x-ghidra-env: &ghidra-env
|
|
GHIDRA_INSTALL_DIR: ${GHIDRA_INSTALL_DIR:-/opt/ghidra}
|
|
REA_GHIDRA_STARTUP_TIMEOUT_MS: ${REA_GHIDRA_STARTUP_TIMEOUT_MS:-900000}
|
|
GHIDRA_HEADLESS_MAXMEM: ${GHIDRA_HEADLESS_MAXMEM:-4G}
|
|
|
|
x-hopper-env: &hopper-env
|
|
HOPPER_LAUNCHER_PATH: ${HOPPER_LAUNCHER_PATH:-/opt/hopper/bin/Hopper}
|
|
HOPPER_STATE_DIR: ${HOPPER_STATE_DIR:-/home/rea/.local/share/hopper}
|
|
REA_HOPPER_STARTUP_TIMEOUT_MS: ${REA_HOPPER_STARTUP_TIMEOUT_MS:-300000}
|
|
|
|
# IDA is bring-your-own in every image; these are the mount/registration
|
|
# defaults (see docs/ida-variants.md).
|
|
x-ida-env: &ida-env
|
|
IDADIR: ${IDADIR:-/opt/ida}
|
|
REA_IDA_MCP_LOCAL_PORT: ${REA_IDA_MCP_LOCAL_PORT:-8745}
|
|
|
|
services:
|
|
# ===========================================================================
|
|
# rea-agent : Ghidra + Hopper (the "all engines" image, default service)
|
|
# ===========================================================================
|
|
rea-agent:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
<<: *build-args
|
|
REA_ENGINE: all
|
|
image: ${REA_IMAGE:-ghcr.io/alexmi256/rea-agent:6.8.0-linux-amd64}
|
|
container_name: ${REA_CONTAINER_NAME:-rea-agent}
|
|
platform: linux/amd64
|
|
init: true
|
|
restart: unless-stopped
|
|
# The image ships user `rea` (uid/gid 1000). Match your host user so files
|
|
# written into ./work are readable without sudo.
|
|
user: "${REA_UID:-1000}:${REA_GID:-1000}"
|
|
working_dir: /work
|
|
# Chromium, Playwright and Ghidra all want more /dev/shm than the 64 MiB
|
|
# Docker default.
|
|
shm_size: ${REA_SHM_SIZE:-1gb}
|
|
environment:
|
|
<<: [*rea-env, *ghidra-env, *hopper-env, *ida-env]
|
|
env_file:
|
|
- path: ./config/rea.env
|
|
required: false
|
|
volumes: &rea-volumes
|
|
# Analysis workspace: targets to inspect, snapshots, exported Evidence.
|
|
- ./work:/work
|
|
# Read-only sample drop-box (what you ask the agent to analyse).
|
|
- ${REA_TARGETS_DIR:-./targets}:/targets:ro
|
|
# Overrides + secrets that must not live in a layer:
|
|
# config/rea.env extra REA_* overrides
|
|
# config/ida-mcp.json IDA MCP registration
|
|
# config/ida/ida.hexlic IDA licence file
|
|
# config/hopper/* Hopper state (see docs/BYO-LICENSES.md)
|
|
- ./config:/etc/rea:ro
|
|
# IDA install (bring your own). Empty by default -> harmless no-op.
|
|
- ${IDA_INSTALL_DIR:-./vendor/ida}:/opt/ida:ro
|
|
# Hopper licence/state (optional; see docs/BYO-LICENSES.md).
|
|
- ${HOPPER_STATE_VOLUME:-./vendor/hopper-state}:/home/rea/.local/share/hopper
|
|
healthcheck:
|
|
test: ["CMD", "/usr/local/bin/rea-agent-healthcheck"]
|
|
interval: 60s
|
|
timeout: 90s
|
|
start_period: 120s
|
|
retries: 3
|
|
|
|
# ===========================================================================
|
|
# rea-ghidra : Ghidra only (broadest architecture coverage, no Hopper)
|
|
# ===========================================================================
|
|
rea-ghidra:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
<<: *build-args
|
|
REA_ENGINE: ghidra
|
|
image: ${REA_GHIDRA_IMAGE:-ghcr.io/alexmi256/rea-agent-ghidra:6.8.0-linux-amd64}
|
|
container_name: ${REA_GHIDRA_CONTAINER_NAME:-rea-agent-ghidra}
|
|
profiles: ["ghidra"]
|
|
platform: linux/amd64
|
|
init: true
|
|
restart: unless-stopped
|
|
user: "${REA_UID:-1000}:${REA_GID:-1000}"
|
|
working_dir: /work
|
|
shm_size: ${REA_SHM_SIZE:-1gb}
|
|
environment:
|
|
# REA_ANALYSIS_PROVIDER is already baked into this image's engine.env;
|
|
# list it here only to make the choice visible/overridable.
|
|
<<: [*rea-env, *ghidra-env, *ida-env]
|
|
REA_ANALYSIS_PROVIDER: ${REA_GHIDRA_PROVIDER:-ghidra}
|
|
env_file:
|
|
- path: ./config/rea.env
|
|
required: false
|
|
volumes:
|
|
- ./work:/work
|
|
- ${REA_TARGETS_DIR:-./targets}:/targets:ro
|
|
- ./config:/etc/rea:ro
|
|
- ${IDA_INSTALL_DIR:-./vendor/ida}:/opt/ida:ro
|
|
- rea-ghidra-home:/home/rea
|
|
healthcheck:
|
|
test: ["CMD", "/usr/local/bin/rea-agent-healthcheck"]
|
|
interval: 60s
|
|
timeout: 90s
|
|
start_period: 120s
|
|
retries: 3
|
|
|
|
# ===========================================================================
|
|
# rea-hopper : Hopper only (small, headless demo or your own licensed DEB)
|
|
# ===========================================================================
|
|
rea-hopper:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
<<: *build-args
|
|
REA_ENGINE: hopper
|
|
image: ${REA_HOPPER_IMAGE:-ghcr.io/alexmi256/rea-agent-hopper:6.8.0-linux-amd64}
|
|
container_name: ${REA_HOPPER_CONTAINER_NAME:-rea-agent-hopper}
|
|
profiles: ["hopper"]
|
|
platform: linux/amd64
|
|
init: true
|
|
restart: unless-stopped
|
|
user: "${REA_UID:-1000}:${REA_GID:-1000}"
|
|
working_dir: /work
|
|
shm_size: ${REA_SHM_SIZE:-1gb}
|
|
environment:
|
|
<<: [*rea-env, *hopper-env, *ida-env]
|
|
REA_ANALYSIS_PROVIDER: ${REA_HOPPER_PROVIDER:-hopper}
|
|
env_file:
|
|
- path: ./config/rea.env
|
|
required: false
|
|
volumes:
|
|
- ./work:/work
|
|
- ${REA_TARGETS_DIR:-./targets}:/targets:ro
|
|
- ./config:/etc/rea:ro
|
|
- ${HOPPER_STATE_VOLUME:-./vendor/hopper-state}:/home/rea/.local/share/hopper
|
|
- rea-hopper-home:/home/rea
|
|
healthcheck:
|
|
test: ["CMD", "/usr/local/bin/rea-agent-healthcheck"]
|
|
interval: 60s
|
|
timeout: 90s
|
|
start_period: 120s
|
|
retries: 3
|
|
|
|
# ===========================================================================
|
|
# rea-ida : no bundled engine. Mount your own IDA (Pro/Home/Free) install and
|
|
# licence, register an IDA MCP endpoint, and REA analyses natively through it.
|
|
# IDA Free cannot be used headlessly (no idalib) - see docs/ida-variants.md.
|
|
# ===========================================================================
|
|
rea-ida:
|
|
build:
|
|
context: .
|
|
dockerfile: Dockerfile
|
|
args:
|
|
<<: *build-args
|
|
REA_ENGINE: ida
|
|
image: ${REA_IDA_IMAGE:-ghcr.io/alexmi256/rea-agent-ida:6.8.0-linux-amd64}
|
|
container_name: ${REA_IDA_CONTAINER_NAME:-rea-agent-ida}
|
|
profiles: ["ida"]
|
|
platform: linux/amd64
|
|
init: true
|
|
restart: unless-stopped
|
|
user: "${REA_UID:-1000}:${REA_GID:-1000}"
|
|
working_dir: /work
|
|
shm_size: ${REA_SHM_SIZE:-1gb}
|
|
environment:
|
|
<<: [*rea-env, *ida-env]
|
|
REA_IDA_MCP_CONFIG: ${REA_IDA_MCP_CONFIG:-/etc/rea/ida-mcp.json}
|
|
env_file:
|
|
- path: ./config/rea.env
|
|
required: false
|
|
volumes:
|
|
- ./work:/work
|
|
- ${REA_TARGETS_DIR:-./targets}:/targets:ro
|
|
- ./config:/etc/rea:ro
|
|
- ${IDA_INSTALL_DIR:-./vendor/ida}:/opt/ida:ro
|
|
- ${IDA_LICENSE_DIR:-./config/ida}:/etc/rea/ida:ro
|
|
- ${IDA_MCP_CONFIG_FILE:-./config/ida-mcp.json}:/etc/rea/ida-mcp.json:ro
|
|
- rea-ida-home:/home/rea
|
|
healthcheck:
|
|
test: ["CMD", "/usr/local/bin/rea-agent-healthcheck"]
|
|
interval: 60s
|
|
timeout: 90s
|
|
start_period: 120s
|
|
retries: 3
|
|
|
|
volumes:
|
|
rea-home:
|
|
name: ${REA_HOME_VOLUME:-rea-agent-home}
|
|
rea-ghidra-home:
|
|
name: ${REA_HOME_VOLUME:-rea-agent-home}-ghidra
|
|
rea-hopper-home:
|
|
name: ${REA_HOME_VOLUME:-rea-agent-home}-hopper
|
|
rea-ida-home:
|
|
name: ${REA_HOME_VOLUME:-rea-agent-home}-ida
|