Spaces:
Running
Running
Port Space to REA MCP Server + Caddy + code-server + goFiles + opencode-router (browser hard-blocked)
Browse files- Caddyfile +62 -0
- Dockerfile +150 -18
- README.md +26 -3
- init.d.sh +33 -0
- init.d/05-code-server.sh +32 -0
- init.d/10-gofiles.sh +63 -0
- init.d/15-supergateway.sh +51 -0
- init.d/20-opencode-router.sh +67 -0
- init.d/90-rea-doctor.sh +16 -0
- start.sh +39 -52
- static/index.html +73 -0
- stub-playwright-index.js +38 -0
- stub-playwright-index.mjs +12 -0
Caddyfile
ADDED
|
@@ -0,0 +1,62 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
:7860 {
|
| 2 |
+
# 1. REA MCP Server (Streamable HTTP via supergateway)
|
| 3 |
+
handle /mcp* {
|
| 4 |
+
reverse_proxy 127.0.0.1:8093 {
|
| 5 |
+
flush_interval -1
|
| 6 |
+
}
|
| 7 |
+
}
|
| 8 |
+
|
| 9 |
+
handle /healthz {
|
| 10 |
+
reverse_proxy 127.0.0.1:8093
|
| 11 |
+
}
|
| 12 |
+
|
| 13 |
+
# 2. code-server routing (/code)
|
| 14 |
+
@code_noslash path /code
|
| 15 |
+
redir @code_noslash /code/ 308
|
| 16 |
+
|
| 17 |
+
handle_path /code/* {
|
| 18 |
+
reverse_proxy 127.0.0.1:8443
|
| 19 |
+
}
|
| 20 |
+
|
| 21 |
+
# 3. goFiles file manager (/files -> mounted at /data)
|
| 22 |
+
@files_noslash path /files
|
| 23 |
+
redir @files_noslash /files/ 308
|
| 24 |
+
|
| 25 |
+
handle_path /files/* {
|
| 26 |
+
reverse_proxy 127.0.0.1:8100 {
|
| 27 |
+
header_up X-Forwarded-Prefix /files
|
| 28 |
+
}
|
| 29 |
+
}
|
| 30 |
+
|
| 31 |
+
# 4. opencode-router (/opencode + root /v1, /api, /assets for its SPA)
|
| 32 |
+
@opencode_noslash path /opencode
|
| 33 |
+
redir @opencode_noslash /opencode/ 308
|
| 34 |
+
|
| 35 |
+
handle_path /opencode/* {
|
| 36 |
+
reverse_proxy 127.0.0.1:8787
|
| 37 |
+
}
|
| 38 |
+
|
| 39 |
+
handle /v1/* {
|
| 40 |
+
reverse_proxy 127.0.0.1:8787
|
| 41 |
+
}
|
| 42 |
+
|
| 43 |
+
handle /api/* {
|
| 44 |
+
reverse_proxy 127.0.0.1:8787
|
| 45 |
+
}
|
| 46 |
+
|
| 47 |
+
handle /assets/* {
|
| 48 |
+
reverse_proxy 127.0.0.1:8787
|
| 49 |
+
}
|
| 50 |
+
|
| 51 |
+
# 5. REA Doctor status JSON
|
| 52 |
+
handle /rea-status.json {
|
| 53 |
+
root * /data/logs
|
| 54 |
+
file_server
|
| 55 |
+
}
|
| 56 |
+
|
| 57 |
+
# 6. Main Status UI fallback
|
| 58 |
+
handle {
|
| 59 |
+
root * /opt/cbot-defaults/static
|
| 60 |
+
file_server
|
| 61 |
+
}
|
| 62 |
+
}
|
Dockerfile
CHANGED
|
@@ -1,37 +1,169 @@
|
|
| 1 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 2 |
|
| 3 |
-
#
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
curl \
|
|
|
|
| 7 |
zip \
|
| 8 |
unzip \
|
| 9 |
tar \
|
| 10 |
xz-utils \
|
| 11 |
bzip2 \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 12 |
python3 \
|
| 13 |
python3-pip \
|
|
|
|
| 14 |
rsync \
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 15 |
&& rm -rf /var/lib/apt/lists/*
|
| 16 |
|
| 17 |
-
|
| 18 |
-
|
|
|
|
|
|
|
| 19 |
|
| 20 |
-
#
|
| 21 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 22 |
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
/root/.openclaw/agents/main/sessions \
|
| 26 |
-
/root/.openclaw/credentials \
|
| 27 |
-
/root/.openclaw/workspace
|
| 28 |
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 32 |
|
| 33 |
-
#
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
COPY start.sh /usr/local/bin/start.sh
|
| 35 |
-
RUN chmod +x /usr/local/bin/start.sh
|
| 36 |
|
|
|
|
| 37 |
CMD ["/usr/local/bin/start.sh"]
|
|
|
|
| 1 |
+
# ==========================================
|
| 2 |
+
# Stage 1: Build Binwalk 3.1.0 in Rust
|
| 3 |
+
# ==========================================
|
| 4 |
+
FROM rust:1-bookworm AS binwalk-builder
|
| 5 |
+
RUN cargo install binwalk --version 3.1.0 --root /install
|
| 6 |
|
| 7 |
+
# ==========================================
|
| 8 |
+
# Stage 2: Main Production Image
|
| 9 |
+
# ==========================================
|
| 10 |
+
FROM node:24-bookworm-slim
|
| 11 |
+
|
| 12 |
+
ENV DEBIAN_FRONTEND=noninteractive
|
| 13 |
+
ENV PORT=7860
|
| 14 |
+
EXPOSE 7860
|
| 15 |
+
|
| 16 |
+
# ------------------------------------------
|
| 17 |
+
# 1. Browser Hard-Block (APT Pinning)
|
| 18 |
+
# ------------------------------------------
|
| 19 |
+
RUN mkdir -p /etc/apt/preferences.d && \
|
| 20 |
+
printf 'Package: *chromium* *chrome* *firefox* *playwright* *puppeteer* *webkit* *geckodriver* *chromedriver* *electron*\nPin: release *\nPin-Priority: -1\n' > /etc/apt/preferences.d/99-block-browsers
|
| 21 |
+
|
| 22 |
+
# ------------------------------------------
|
| 23 |
+
# 2. System Dependencies (Zero Browser Packages)
|
| 24 |
+
# ------------------------------------------
|
| 25 |
+
RUN apt-get update && apt-get install -y --no-install-recommends \
|
| 26 |
+
ca-certificates \
|
| 27 |
curl \
|
| 28 |
+
git \
|
| 29 |
zip \
|
| 30 |
unzip \
|
| 31 |
tar \
|
| 32 |
xz-utils \
|
| 33 |
bzip2 \
|
| 34 |
+
zstd \
|
| 35 |
+
lz4 \
|
| 36 |
+
lzip \
|
| 37 |
+
lzop \
|
| 38 |
+
unar \
|
| 39 |
+
cabextract \
|
| 40 |
+
squashfs-tools \
|
| 41 |
+
cpio \
|
| 42 |
+
e2fsprogs \
|
| 43 |
+
p7zip-full \
|
| 44 |
python3 \
|
| 45 |
python3-pip \
|
| 46 |
+
python3-venv \
|
| 47 |
rsync \
|
| 48 |
+
tshark \
|
| 49 |
+
wabt \
|
| 50 |
+
gdb \
|
| 51 |
+
binutils \
|
| 52 |
+
file \
|
| 53 |
+
patchelf \
|
| 54 |
+
procps \
|
| 55 |
+
util-linux \
|
| 56 |
+
liblz4-1 \
|
| 57 |
+
liblzo2-2 \
|
| 58 |
&& rm -rf /var/lib/apt/lists/*
|
| 59 |
|
| 60 |
+
ENV PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1 \
|
| 61 |
+
PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1 \
|
| 62 |
+
PUPPETEER_SKIP_DOWNLOAD=1 \
|
| 63 |
+
REA_BROWSER_EXECUTABLE=""
|
| 64 |
|
| 65 |
+
# ------------------------------------------
|
| 66 |
+
# 4. Adoptium Temurin JDK 21 (Full JDK)
|
| 67 |
+
# ------------------------------------------
|
| 68 |
+
RUN mkdir -p /opt/jdk-21 && \
|
| 69 |
+
curl -fsSL "https://github.com/adoptium/temurin21-binaries/releases/download/jdk-21.0.12.1%2B1/OpenJDK21U-jdk_x64_linux_hotspot_21.0.12.1_1.tar.gz" -o /tmp/jdk21.tar.gz && \
|
| 70 |
+
tar -xzf /tmp/jdk21.tar.gz -C /opt/jdk-21 --strip-components=1 && \
|
| 71 |
+
rm -f /tmp/jdk21.tar.gz
|
| 72 |
|
| 73 |
+
ENV JAVA_HOME="/opt/jdk-21"
|
| 74 |
+
ENV PATH="/opt/jdk-21/bin:${PATH}"
|
|
|
|
|
|
|
|
|
|
| 75 |
|
| 76 |
+
# ------------------------------------------
|
| 77 |
+
# 5. Ghidra 12.1.4 (Official Release)
|
| 78 |
+
# ------------------------------------------
|
| 79 |
+
RUN mkdir -p /opt/ghidra && \
|
| 80 |
+
curl -fsSL "https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_12.1.4_build/ghidra_12.1.4_PUBLIC_20260921.zip" -o /tmp/ghidra.zip && \
|
| 81 |
+
unzip -q /tmp/ghidra.zip -d /opt/ghidra && \
|
| 82 |
+
chmod +x /opt/ghidra/ghidra_12.1.4_PUBLIC/support/analyzeHeadless && \
|
| 83 |
+
rm -f /tmp/ghidra.zip
|
| 84 |
+
|
| 85 |
+
ENV GHIDRA_INSTALL_DIR="/opt/ghidra/ghidra_12.1.4_PUBLIC"
|
| 86 |
+
ENV REA_ANALYSIS_PROVIDER="ghidra"
|
| 87 |
+
|
| 88 |
+
# ------------------------------------------
|
| 89 |
+
# 6. Headless JADX MCP + JADX CLI + Apktool
|
| 90 |
+
# ------------------------------------------
|
| 91 |
+
RUN mkdir -p /opt/jadx /opt/jadx-cli && \
|
| 92 |
+
curl -fsSL "https://github.com/1013503897/jadx-headless-mcp/releases/download/v0.7.1/jadx-headless-mcp-0.7.1-all.jar" -o /opt/jadx/jadx-headless-mcp-0.7.1-all.jar && \
|
| 93 |
+
curl -fsSL "https://github.com/skylot/jadx/releases/download/v1.5.6/jadx-1.5.6.zip" -o /tmp/jadx.zip && \
|
| 94 |
+
unzip -q /tmp/jadx.zip -d /opt/jadx-cli && \
|
| 95 |
+
chmod +x /opt/jadx-cli/bin/jadx && \
|
| 96 |
+
ln -sf /opt/jadx-cli/bin/jadx /usr/local/bin/jadx && \
|
| 97 |
+
rm -f /tmp/jadx.zip && \
|
| 98 |
+
curl -fsSL "https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool" -o /usr/local/bin/apktool && \
|
| 99 |
+
chmod +x /usr/local/bin/apktool && \
|
| 100 |
+
curl -fsSL "https://github.com/iBotPeaches/Apktool/releases/download/v3.0.3/apktool_3.0.3.jar" -o /usr/local/bin/apktool.jar
|
| 101 |
+
|
| 102 |
+
ENV REA_JADX_MCP_JAR="/opt/jadx/jadx-headless-mcp-0.7.1-all.jar"
|
| 103 |
+
ENV REA_APKTOOL_COMMAND="/usr/local/bin/apktool"
|
| 104 |
+
|
| 105 |
+
# ------------------------------------------
|
| 106 |
+
# 7. Binwalk 3.1.0 & Unblob 26.6.4 & Pwntools
|
| 107 |
+
# ------------------------------------------
|
| 108 |
+
COPY --from=binwalk-builder /install/bin/binwalk /usr/local/bin/binwalk
|
| 109 |
+
RUN chmod +x /usr/local/bin/binwalk && \
|
| 110 |
+
pip3 install --no-cache-dir --break-system-packages unblob==26.6.4 pwntools
|
| 111 |
+
|
| 112 |
+
ENV REA_BINWALK_COMMAND="/usr/local/bin/binwalk"
|
| 113 |
+
ENV REA_UNBLOB_COMMAND="/usr/local/bin/unblob"
|
| 114 |
+
ENV REA_FIRMWARE_PRLIMIT_COMMAND="/usr/bin/prlimit"
|
| 115 |
+
ENV REA_PWNTOOLS_PYTHON="/usr/bin/python3"
|
| 116 |
+
|
| 117 |
+
# ------------------------------------------
|
| 118 |
+
# 8. Caddy Server
|
| 119 |
+
# ------------------------------------------
|
| 120 |
+
RUN curl -fsSL "https://caddyserver.com/api/download?os=linux&arch=amd64" -o /usr/local/bin/caddy && \
|
| 121 |
+
chmod +x /usr/local/bin/caddy
|
| 122 |
+
|
| 123 |
+
# ------------------------------------------
|
| 124 |
+
# 9. code-server
|
| 125 |
+
# ------------------------------------------
|
| 126 |
+
RUN curl -fsSL https://code-server.dev/install.sh | sh
|
| 127 |
+
|
| 128 |
+
# ------------------------------------------
|
| 129 |
+
# 10. goFiles & opencode-router
|
| 130 |
+
# ------------------------------------------
|
| 131 |
+
RUN mkdir -p /tmp/dl /opt/opencode-router && \
|
| 132 |
+
curl -fsSL "https://github.com/G-Aman/goFiles/releases/latest/download/gofiles-linux-amd64.zip" -o /tmp/dl/gf.zip && \
|
| 133 |
+
unzip -q /tmp/dl/gf.zip -d /tmp/dl/gf && \
|
| 134 |
+
mv /tmp/dl/gf/gofiles-linux-amd64/gofiles /usr/local/bin/gofiles && \
|
| 135 |
+
chmod +x /usr/local/bin/gofiles && \
|
| 136 |
+
curl -fsSL "https://github.com/G-Aman/opencode-router/releases/latest/download/opencode-router-linux-amd64.zip" -o /tmp/dl/ocr.zip && \
|
| 137 |
+
unzip -q /tmp/dl/ocr.zip -d /tmp/dl/ocr && \
|
| 138 |
+
cp -r /tmp/dl/ocr/opencode-router-linux-amd64/* /opt/opencode-router/ && \
|
| 139 |
+
chmod +x /opt/opencode-router/opencode-router && \
|
| 140 |
+
ln -sf /opt/opencode-router/opencode-router /usr/local/bin/opencode-router && \
|
| 141 |
+
rm -rf /tmp/dl
|
| 142 |
+
|
| 143 |
+
# ------------------------------------------
|
| 144 |
+
# 11. REA & supergateway + Browser Hard-Block
|
| 145 |
+
# ------------------------------------------
|
| 146 |
+
COPY stub-playwright-index.js /tmp/stub-pw.js
|
| 147 |
+
COPY stub-playwright-index.mjs /tmp/stub-pw.mjs
|
| 148 |
+
RUN npm install -g rea-agents@latest supergateway@latest && \
|
| 149 |
+
cp /tmp/stub-pw.js /usr/local/lib/node_modules/rea-agents/node_modules/playwright-core/index.js 2>/dev/null || true && \
|
| 150 |
+
cp /tmp/stub-pw.mjs /usr/local/lib/node_modules/rea-agents/node_modules/playwright-core/index.mjs 2>/dev/null || true && \
|
| 151 |
+
rm -f /tmp/stub-pw.* && \
|
| 152 |
+
for b in chromium chromium-browser google-chrome google-chrome-stable chrome firefox playwright playwright-core puppeteer chromedriver geckodriver msedge brave-browser webkit; do \
|
| 153 |
+
printf '#!/bin/sh\necho "ERROR: Browser engines and browser automation are strictly disabled by host security policy." >&2\nexit 126\n' > "/usr/local/bin/$b" && chmod 755 "/usr/local/bin/$b"; \
|
| 154 |
+
done && \
|
| 155 |
+
rm -rf /root/.npm
|
| 156 |
|
| 157 |
+
# ------------------------------------------
|
| 158 |
+
# 12. Copy CBot Repo Defaults & Runtime Runner
|
| 159 |
+
# ------------------------------------------
|
| 160 |
+
RUN mkdir -p /opt/cbot-defaults/init.d /opt/cbot-defaults/static /data
|
| 161 |
+
COPY Caddyfile /opt/cbot-defaults/Caddyfile
|
| 162 |
+
COPY init.d.sh /opt/cbot-defaults/init.d.sh
|
| 163 |
+
COPY init.d/ /opt/cbot-defaults/init.d/
|
| 164 |
+
COPY static/ /opt/cbot-defaults/static/
|
| 165 |
COPY start.sh /usr/local/bin/start.sh
|
| 166 |
+
RUN chmod +x /usr/local/bin/start.sh /opt/cbot-defaults/init.d.sh /opt/cbot-defaults/init.d/*.sh
|
| 167 |
|
| 168 |
+
WORKDIR /data
|
| 169 |
CMD ["/usr/local/bin/start.sh"]
|
README.md
CHANGED
|
@@ -1,10 +1,33 @@
|
|
| 1 |
---
|
| 2 |
-
title:
|
| 3 |
-
emoji:
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: blue
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
---
|
| 9 |
|
| 10 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
---
|
| 2 |
+
title: REA MCP Server & Workspace
|
| 3 |
+
emoji: 🔬
|
| 4 |
colorFrom: purple
|
| 5 |
colorTo: blue
|
| 6 |
sdk: docker
|
| 7 |
pinned: false
|
| 8 |
---
|
| 9 |
|
| 10 |
+
# REA MCP Server Space (`amangs/cbot`)
|
| 11 |
+
|
| 12 |
+
High-performance reverse-engineering server and persistent workspace backed by [REA](https://github.com/morluto/rea).
|
| 13 |
+
|
| 14 |
+
## Architecture (`:7860` Caddy Gateway)
|
| 15 |
+
|
| 16 |
+
- **`/mcp`** → Streamable HTTP MCP endpoint (`supergateway` → `rea mcp`)
|
| 17 |
+
- **`/code/`** → In-browser VS Code Server bound to `/data/workspace`
|
| 18 |
+
- **`/files/`** → [goFiles](https://github.com/G-Aman/goFiles) File Manager & WebDAV server on `/data`
|
| 19 |
+
- **`/opencode/`** → [OpenCode Router](https://github.com/G-Aman/opencode-router) WebUI and `/v1` AI proxy
|
| 20 |
+
- **`/`** → System dashboard & analysis status
|
| 21 |
+
|
| 22 |
+
## Included Engines
|
| 23 |
+
|
| 24 |
+
- **Ghidra 12.1.4 Headless** + **JDK 21**
|
| 25 |
+
- **JADX Headless MCP 0.7.1** + **JADX CLI 1.5.6** + **Apktool 3.0.3**
|
| 26 |
+
- **Binwalk 3.1.0 (Rust)** + **Unblob 26.6.4** + **Pwntools**
|
| 27 |
+
- **WABT** (WebAssembly WAT/WASM) + **TShark** (Packet capture)
|
| 28 |
+
- **Zero Browser Policy**: All browser packages, Playwright, and automation engines are strictly locked and restricted at the kernel, APT, and runtime level.
|
| 29 |
+
|
| 30 |
+
## Storage & Persistence
|
| 31 |
+
|
| 32 |
+
All persistent data, code-server workspace, uploads, and runtime scripts live on the persistent storage volume mounted at `/data`.
|
| 33 |
+
Custom startup services can be placed into `/data/script/init.d/*.sh` to execute automatically on boot.
|
init.d.sh
ADDED
|
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# ============================================================
|
| 3 |
+
# init.d - auto-start hook for persistent services
|
| 4 |
+
#
|
| 5 |
+
# Any executable script placed in /data/script/init.d runs on boot.
|
| 6 |
+
# - Source order: files run in sorted (alphabetical) order
|
| 7 |
+
# - A failing script logs and does NOT block the rest
|
| 8 |
+
# - Scripts are started in the background (setsid)
|
| 9 |
+
# ============================================================
|
| 10 |
+
|
| 11 |
+
INITD_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)/init.d"
|
| 12 |
+
LOG="/data/script/init.d.log"
|
| 13 |
+
|
| 14 |
+
if [ ! -d "$INITD_DIR" ]; then
|
| 15 |
+
exit 0
|
| 16 |
+
fi
|
| 17 |
+
|
| 18 |
+
shopt -s nullglob
|
| 19 |
+
scripts=("$INITD_DIR"/*.sh)
|
| 20 |
+
|
| 21 |
+
if [ ${#scripts[@]} -eq 0 ]; then
|
| 22 |
+
exit 0
|
| 23 |
+
fi
|
| 24 |
+
|
| 25 |
+
echo "🧩 init.d: ${#scripts[@]} script(s) to run ($(date -Iseconds))" >> "$LOG"
|
| 26 |
+
for s in "${scripts[@]}"; do
|
| 27 |
+
name="$(basename "$s")"
|
| 28 |
+
chmod +x "$s" 2>/dev/null || true
|
| 29 |
+
echo " ▶️ $name" >> "$LOG"
|
| 30 |
+
setsid bash "$s" >> "$LOG" 2>&1 < /dev/null &
|
| 31 |
+
disown 2>/dev/null || true
|
| 32 |
+
done
|
| 33 |
+
exit 0
|
init.d/05-code-server.sh
ADDED
|
@@ -0,0 +1,32 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# 05-code-server.sh — code-server service on 127.0.0.1:8443
|
| 3 |
+
DIR="/data/script/code-server"
|
| 4 |
+
WORKSPACE="${CODE_WORKSPACE:-/data/workspace}"
|
| 5 |
+
USER_DATA="${CODE_USER_DATA:-/data/code-server}"
|
| 6 |
+
LOG="$DIR/code-server.log"
|
| 7 |
+
|
| 8 |
+
mkdir -p "$DIR" "$WORKSPACE" "$USER_DATA"
|
| 9 |
+
|
| 10 |
+
if [ -f /data/.env ]; then
|
| 11 |
+
set -a
|
| 12 |
+
. /data/.env
|
| 13 |
+
set +a
|
| 14 |
+
fi
|
| 15 |
+
|
| 16 |
+
export PASSWORD="${CODE_PASSWORD:-${AUTH_TOKEN:-aman@g}}"
|
| 17 |
+
rm -f "$HOME/.config/code-server/config.yaml" "$USER_DATA/config.yaml" 2>/dev/null || true
|
| 18 |
+
|
| 19 |
+
if pgrep -f "code-server.*8443" >/dev/null 2>&1; then
|
| 20 |
+
echo "code-server already running"
|
| 21 |
+
exit 0
|
| 22 |
+
fi
|
| 23 |
+
|
| 24 |
+
exec code-server \
|
| 25 |
+
--port 8443 \
|
| 26 |
+
--auth password \
|
| 27 |
+
--user-data-dir "$USER_DATA" \
|
| 28 |
+
--bind-addr 127.0.0.1:8443 \
|
| 29 |
+
--disable-telemetry \
|
| 30 |
+
--disable-update-check \
|
| 31 |
+
"$WORKSPACE" \
|
| 32 |
+
>> "$LOG" 2>&1
|
init.d/10-gofiles.sh
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# 10-gofiles.sh — goFiles file manager on 127.0.0.1:8100 serving /data
|
| 3 |
+
DIR="/data/script/gofiles"
|
| 4 |
+
CONFIG="$DIR/config.json"
|
| 5 |
+
LOG="$DIR/gofiles.log"
|
| 6 |
+
|
| 7 |
+
mkdir -p "$DIR"
|
| 8 |
+
|
| 9 |
+
if [ -f /data/.env ]; then
|
| 10 |
+
set -a
|
| 11 |
+
. /data/.env
|
| 12 |
+
set +a
|
| 13 |
+
fi
|
| 14 |
+
|
| 15 |
+
GOFILES_USER="${GOFILES_USER:-aman}"
|
| 16 |
+
GOFILES_PASS="${GOFILES_PASS:-${AUTH_TOKEN:-aman@g}}"
|
| 17 |
+
|
| 18 |
+
if [ ! -f "$CONFIG" ]; then
|
| 19 |
+
HASH="$(/usr/local/bin/gofiles -genpass "$GOFILES_PASS" 2>/dev/null | tr -d '\r\n')"
|
| 20 |
+
cat > "$CONFIG" <<EOF
|
| 21 |
+
{
|
| 22 |
+
"app_name": "goFiles",
|
| 23 |
+
"logo_url": "",
|
| 24 |
+
"listen": "127.0.0.1:8100",
|
| 25 |
+
"root": "/data",
|
| 26 |
+
"path_prefix": "",
|
| 27 |
+
"assets": "",
|
| 28 |
+
"users": [
|
| 29 |
+
{
|
| 30 |
+
"name": "${GOFILES_USER}",
|
| 31 |
+
"pass": "${HASH}",
|
| 32 |
+
"home": "/"
|
| 33 |
+
}
|
| 34 |
+
],
|
| 35 |
+
"allow": {
|
| 36 |
+
"write": true,
|
| 37 |
+
"delete": true,
|
| 38 |
+
"upload": true,
|
| 39 |
+
"urlfetch": true,
|
| 40 |
+
"archive": true,
|
| 41 |
+
"extract": true,
|
| 42 |
+
"edit": true,
|
| 43 |
+
"chmod": true,
|
| 44 |
+
"hash": true,
|
| 45 |
+
"webdav": true
|
| 46 |
+
},
|
| 47 |
+
"max_upload_bytes": 50000000000,
|
| 48 |
+
"chunk_bytes": 4000000,
|
| 49 |
+
"theme": "auto",
|
| 50 |
+
"lang": "en",
|
| 51 |
+
"trust_proxy": true,
|
| 52 |
+
"session_name": "gofm_session"
|
| 53 |
+
}
|
| 54 |
+
EOF
|
| 55 |
+
fi
|
| 56 |
+
|
| 57 |
+
if pgrep -f "/usr/local/bin/gofiles" >/dev/null 2>&1; then
|
| 58 |
+
echo "gofiles already running"
|
| 59 |
+
exit 0
|
| 60 |
+
fi
|
| 61 |
+
|
| 62 |
+
cd "$DIR" || exit 1
|
| 63 |
+
exec /usr/local/bin/gofiles -config "$CONFIG" >> "$LOG" 2>&1
|
init.d/15-supergateway.sh
ADDED
|
@@ -0,0 +1,51 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# 15-supergateway.sh — REA MCP Server over Streamable HTTP on 127.0.0.1:8093
|
| 3 |
+
DIR="/data/script/rea-mcp"
|
| 4 |
+
LOG="$DIR/supergateway.log"
|
| 5 |
+
|
| 6 |
+
mkdir -p "$DIR" /data/workspace /data/tmp
|
| 7 |
+
|
| 8 |
+
if [ -f /data/.env ]; then
|
| 9 |
+
set -a
|
| 10 |
+
. /data/.env
|
| 11 |
+
set +a
|
| 12 |
+
fi
|
| 13 |
+
|
| 14 |
+
export JAVA_HOME="/opt/jdk-21"
|
| 15 |
+
export PATH="/opt/jdk-21/bin:/opt/jadx-cli/bin:/usr/local/bin:/usr/bin:/bin"
|
| 16 |
+
export GHIDRA_INSTALL_DIR="/opt/ghidra/ghidra_12.1.4_PUBLIC"
|
| 17 |
+
export REA_ANALYSIS_PROVIDER="ghidra"
|
| 18 |
+
export REA_JADX_MCP_JAR="/opt/jadx/jadx-headless-mcp-0.7.1-all.jar"
|
| 19 |
+
export REA_BINWALK_COMMAND="/usr/local/bin/binwalk"
|
| 20 |
+
export REA_UNBLOB_COMMAND="/usr/local/bin/unblob"
|
| 21 |
+
export REA_APKTOOL_COMMAND="/usr/local/bin/apktool"
|
| 22 |
+
export REA_FIRMWARE_PRLIMIT_COMMAND="/usr/bin/prlimit"
|
| 23 |
+
export REA_PWNTOOLS_PYTHON="/usr/bin/python3"
|
| 24 |
+
export REA_GHIDRA_STARTUP_TIMEOUT_MS="${REA_GHIDRA_STARTUP_TIMEOUT_MS:-600000}"
|
| 25 |
+
export TMPDIR="/data/tmp"
|
| 26 |
+
export PLAYWRIGHT_SKIP_BROWSER_DOWNLOAD=1
|
| 27 |
+
export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=1
|
| 28 |
+
export PUPPETEER_SKIP_DOWNLOAD=1
|
| 29 |
+
|
| 30 |
+
if pgrep -f "supergateway.*8093" >/dev/null 2>&1; then
|
| 31 |
+
echo "supergateway already running"
|
| 32 |
+
exit 0
|
| 33 |
+
fi
|
| 34 |
+
|
| 35 |
+
AUTH_ARGS=()
|
| 36 |
+
API_KEY="${REA_API_KEY:-${AUTH_TOKEN:-}}"
|
| 37 |
+
if [ -n "$API_KEY" ]; then
|
| 38 |
+
AUTH_ARGS=(--apiKey "$API_KEY")
|
| 39 |
+
fi
|
| 40 |
+
|
| 41 |
+
cd /data/workspace || exit 1
|
| 42 |
+
exec /usr/local/bin/supergateway \
|
| 43 |
+
--stdio "/usr/local/bin/rea mcp" \
|
| 44 |
+
--outputTransport streamableHttp \
|
| 45 |
+
--host 127.0.0.1 \
|
| 46 |
+
--port 8093 \
|
| 47 |
+
--streamableHttpPath /mcp \
|
| 48 |
+
--healthEndpoint /healthz \
|
| 49 |
+
--healthCheck server \
|
| 50 |
+
"${AUTH_ARGS[@]}" \
|
| 51 |
+
>> "$LOG" 2>&1
|
init.d/20-opencode-router.sh
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# 20-opencode-router.sh — OpenCode Router on 127.0.0.1:8787
|
| 3 |
+
DIR="/data/script/opencode-router"
|
| 4 |
+
CONFIG="$DIR/opencode-router.json"
|
| 5 |
+
LOG="$DIR/proxy.log"
|
| 6 |
+
|
| 7 |
+
mkdir -p "$DIR"
|
| 8 |
+
|
| 9 |
+
if [ -f /data/.env ]; then
|
| 10 |
+
set -a
|
| 11 |
+
. /data/.env
|
| 12 |
+
set +a
|
| 13 |
+
fi
|
| 14 |
+
|
| 15 |
+
# Copy bundled assets/public/defaults from /opt/opencode-router if missing
|
| 16 |
+
cp -rn /opt/opencode-router/* "$DIR/" 2>/dev/null || true
|
| 17 |
+
|
| 18 |
+
PROXY_KEY="${OCROUTER_KEY:-${AUTH_TOKEN:-aman@g}}"
|
| 19 |
+
|
| 20 |
+
if [ ! -f "$CONFIG" ]; then
|
| 21 |
+
cat > "$CONFIG" <<EOF
|
| 22 |
+
{
|
| 23 |
+
"host": "127.0.0.1",
|
| 24 |
+
"port": 8787,
|
| 25 |
+
"upstream": "https://opencode.ai/zen/v1",
|
| 26 |
+
"ua": "opencode/1.19.0 ai-sdk/provider-utils/4.0.23 runtime/bun/1.3.14",
|
| 27 |
+
"autoUA": true,
|
| 28 |
+
"injectSession": true,
|
| 29 |
+
"defaultModel": "nemotron-3.5-lightning-free",
|
| 30 |
+
"fallbackModels": [
|
| 31 |
+
"nemotron-3-ultra-free",
|
| 32 |
+
"muse-spark-1.3-contributor-free",
|
| 33 |
+
"mimo-v2.6-flash-free",
|
| 34 |
+
"longcat-2.5-preview-free",
|
| 35 |
+
"space-bunny-free"
|
| 36 |
+
],
|
| 37 |
+
"disabledModels": [
|
| 38 |
+
"ling-3.0-flash-fin-free"
|
| 39 |
+
],
|
| 40 |
+
"modelAliases": {},
|
| 41 |
+
"responsesModels": [
|
| 42 |
+
"gpt-5*",
|
| 43 |
+
"gpt-6*",
|
| 44 |
+
"grok-*",
|
| 45 |
+
"muse-spark-*"
|
| 46 |
+
],
|
| 47 |
+
"rateLimitMax": 0,
|
| 48 |
+
"rateLimitWindowMs": 60000,
|
| 49 |
+
"proxyKey": "${PROXY_KEY}",
|
| 50 |
+
"defaultUpstreamKey": "",
|
| 51 |
+
"outboundProxy": "",
|
| 52 |
+
"trustForwarded": true,
|
| 53 |
+
"timeoutMs": 120000,
|
| 54 |
+
"cacheMs": 0,
|
| 55 |
+
"autoSync": false,
|
| 56 |
+
"autoSyncIntervalMs": 0
|
| 57 |
+
}
|
| 58 |
+
EOF
|
| 59 |
+
fi
|
| 60 |
+
|
| 61 |
+
if pgrep -f "$DIR/opencode-router" >/dev/null 2>&1; then
|
| 62 |
+
echo "opencode-router already running"
|
| 63 |
+
exit 0
|
| 64 |
+
fi
|
| 65 |
+
|
| 66 |
+
cd "$DIR" || exit 1
|
| 67 |
+
exec "$DIR/opencode-router" 8787 >> "$LOG" 2>&1
|
init.d/90-rea-doctor.sh
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
#!/bin/bash
|
| 2 |
+
# 90-rea-doctor.sh — Export REA readiness report to /data/logs/rea-status.json
|
| 3 |
+
mkdir -p /data/logs /data/tmp
|
| 4 |
+
export JAVA_HOME="/opt/jdk-21"
|
| 5 |
+
export PATH="/opt/jdk-21/bin:/opt/jadx-cli/bin:/usr/local/bin:/usr/bin:/bin"
|
| 6 |
+
export GHIDRA_INSTALL_DIR="/opt/ghidra/ghidra_12.1.4_PUBLIC"
|
| 7 |
+
export REA_ANALYSIS_PROVIDER="ghidra"
|
| 8 |
+
export REA_JADX_MCP_JAR="/opt/jadx/jadx-headless-mcp-0.7.1-all.jar"
|
| 9 |
+
export REA_BINWALK_COMMAND="/usr/local/bin/binwalk"
|
| 10 |
+
export REA_UNBLOB_COMMAND="/usr/local/bin/unblob"
|
| 11 |
+
export REA_APKTOOL_COMMAND="/usr/local/bin/apktool"
|
| 12 |
+
export REA_FIRMWARE_PRLIMIT_COMMAND="/usr/bin/prlimit"
|
| 13 |
+
export REA_PWNTOOLS_PYTHON="/usr/bin/python3"
|
| 14 |
+
export TMPDIR="/data/tmp"
|
| 15 |
+
|
| 16 |
+
/usr/local/bin/rea doctor --format json > /data/logs/rea-status.json 2>/data/logs/rea-doctor.err || true
|
start.sh
CHANGED
|
@@ -1,59 +1,46 @@
|
|
| 1 |
#!/bin/bash
|
| 2 |
set -e
|
| 3 |
|
| 4 |
-
|
| 5 |
-
|
| 6 |
-
EXCLUDES=(
|
| 7 |
-
--exclude="cache/"
|
| 8 |
-
--exclude="logs/"
|
| 9 |
-
--exclude="tmp/"
|
| 10 |
-
--exclude="*.sock"
|
| 11 |
-
--exclude="*.lock*"
|
| 12 |
-
--exclude="*-wal"
|
| 13 |
-
--exclude="*-shm"
|
| 14 |
-
--exclude="*-journal"
|
| 15 |
-
)
|
| 16 |
-
|
| 17 |
-
# 1. Restore on boot
|
| 18 |
-
if [ -d "$BUCKET_DIR" ] && [ "$(ls -A "$BUCKET_DIR" 2>/dev/null)" ]; then
|
| 19 |
-
echo "[Storage] Restoring from $BUCKET_DIR..."
|
| 20 |
-
rsync -a "${EXCLUDES[@]}" "$BUCKET_DIR/" "$OPENCLAW_DIR/"
|
| 21 |
-
echo "[Storage] Restore completed."
|
| 22 |
-
fi
|
| 23 |
|
| 24 |
-
#
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
# 3. Background sync to bucket every 30s
|
| 28 |
-
if [ -d "/data" ]; then
|
| 29 |
-
mkdir -p "$BUCKET_DIR"
|
| 30 |
-
(
|
| 31 |
-
set +e
|
| 32 |
-
while true; do
|
| 33 |
-
sleep 30
|
| 34 |
-
|
| 35 |
-
# Flush SQLite WAL to main db files
|
| 36 |
-
for db in "$OPENCLAW_DIR"/state/*.sqlite "$OPENCLAW_DIR"/agents/*/agent/*.sqlite; do
|
| 37 |
-
if [ -f "$db" ]; then
|
| 38 |
-
python3 -c "import sqlite3; c=sqlite3.connect('$db'); c.execute('PRAGMA wal_checkpoint(PASSIVE);'); c.close()" 2>/dev/null || true
|
| 39 |
-
fi
|
| 40 |
-
done
|
| 41 |
-
|
| 42 |
-
# Sync state excluding runtime journals/locks
|
| 43 |
-
rsync -a --delete "${EXCLUDES[@]}" "$OPENCLAW_DIR/" "$BUCKET_DIR/" 2>/dev/null || true
|
| 44 |
-
done
|
| 45 |
-
) &
|
| 46 |
-
fi
|
| 47 |
|
| 48 |
-
#
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
}
|
| 54 |
-
trap sync_exit SIGTERM SIGINT
|
| 55 |
|
| 56 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
| 57 |
|
| 58 |
-
|
| 59 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
#!/bin/bash
|
| 2 |
set -e
|
| 3 |
|
| 4 |
+
echo "🚀 Starting REA MCP Server Space..."
|
| 5 |
+
echo "=================================="
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 6 |
|
| 7 |
+
# 1. Directory Structure on Persistent Storage (/data)
|
| 8 |
+
mkdir -p /data/{workspace,logs,tmp,code-server,script/init.d}
|
| 9 |
+
chmod -R 755 /data/script
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 10 |
|
| 11 |
+
# 2. Seed Default Scripts & Caddyfile if not already customized
|
| 12 |
+
if [ ! -f /data/script/Caddyfile ]; then
|
| 13 |
+
echo "📋 Seeding default Caddyfile..."
|
| 14 |
+
cp /opt/cbot-defaults/Caddyfile /data/script/Caddyfile
|
| 15 |
+
fi
|
|
|
|
|
|
|
| 16 |
|
| 17 |
+
if [ ! -f /data/script/init.d.sh ]; then
|
| 18 |
+
echo "📋 Seeding init.d runner..."
|
| 19 |
+
cp /opt/cbot-defaults/init.d.sh /data/script/init.d.sh
|
| 20 |
+
chmod +x /data/script/init.d.sh
|
| 21 |
+
fi
|
| 22 |
|
| 23 |
+
for f in /opt/cbot-defaults/init.d/*.sh; do
|
| 24 |
+
target="/data/script/init.d/$(basename "$f")"
|
| 25 |
+
if [ ! -f "$target" ]; then
|
| 26 |
+
echo "📋 Seeding service script $(basename "$f")..."
|
| 27 |
+
cp "$f" "$target"
|
| 28 |
+
chmod +x "$target"
|
| 29 |
+
fi
|
| 30 |
+
done
|
| 31 |
+
|
| 32 |
+
# 3. Enforce Browser Hard-Block Policies
|
| 33 |
+
echo "🛡️ Verifying browser lockdown..."
|
| 34 |
+
rm -rf /root/.cache/ms-playwright /root/.cache/puppeteer /data/.cache/ms-playwright 2>/dev/null || true
|
| 35 |
+
mkdir -p /root/.cache /data/.cache
|
| 36 |
+
ln -sfn /dev/null /root/.cache/ms-playwright 2>/dev/null || true
|
| 37 |
+
ln -sfn /dev/null /root/.cache/puppeteer 2>/dev/null || true
|
| 38 |
+
echo "Browser lockdown verified: zero browser packages permitted." > /data/logs/browser-block.log
|
| 39 |
+
|
| 40 |
+
# 4. Run Persistent init.d Services
|
| 41 |
+
echo "🧩 Running init.d services..."
|
| 42 |
+
/data/script/init.d.sh
|
| 43 |
+
|
| 44 |
+
# 5. Run Caddy in Foreground on Port 7860
|
| 45 |
+
echo "🌐 Starting Caddy edge proxy on :7860..."
|
| 46 |
+
exec caddy run --config /data/script/Caddyfile --adapter caddyfile
|
static/index.html
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
<!DOCTYPE html>
|
| 2 |
+
<html lang="en">
|
| 3 |
+
<head>
|
| 4 |
+
<meta charset="utf-8">
|
| 5 |
+
<meta name="viewport" content="width=device-width,initial-scale=1">
|
| 6 |
+
<title>REA MCP Server & Workspace</title>
|
| 7 |
+
<style>
|
| 8 |
+
:root{--bg:#0b0f19;--card:#131b2e;--border:#1e293b;--text:#e2e8f0;--muted:#94a3b8;--accent:#38bdf8;--ok:#10b981;--warn:#f59e0b}
|
| 9 |
+
*{box-sizing:border-box;margin:0;padding:0}
|
| 10 |
+
body{font-family:ui-sans-serif,system-ui,-apple-system,sans-serif;background:var(--bg);color:var(--text);padding:2rem;max-width:920px;margin:0 auto;line-height:1.5}
|
| 11 |
+
h1{font-size:1.5rem;margin-bottom:.25rem;display:flex;align-items:center;gap:.6rem}
|
| 12 |
+
p.sub{color:var(--muted);font-size:.9rem;margin-bottom:1.75rem}
|
| 13 |
+
.grid{display:grid;grid-template-columns:repeat(auto-fit,minmax(210px,1fr));gap:1rem;margin-bottom:1.75rem}
|
| 14 |
+
a.card{display:block;background:var(--card);border:1px solid var(--border);border-radius:10px;padding:1.1rem;text-decoration:none;color:var(--text);transition:border-color .15s}
|
| 15 |
+
a.card:hover{border-color:var(--accent)}
|
| 16 |
+
.card h3{font-size:1rem;margin-bottom:.3rem;color:var(--accent)}
|
| 17 |
+
.card p{font-size:.82rem;color:var(--muted)}
|
| 18 |
+
.panel{background:var(--card);border:1px solid var(--border);border-radius:10px;padding:1.1rem;margin-bottom:1rem}
|
| 19 |
+
.panel h2{font-size:.95rem;margin-bottom:.6rem;color:var(--muted);text-transform:uppercase;letter-spacing:.04em}
|
| 20 |
+
.badges{display:flex;flex-wrap:wrap;gap:.5rem}
|
| 21 |
+
.badge{background:#0f172a;border:1px solid var(--border);padding:.3rem .65rem;border-radius:6px;font-size:.8rem;font-family:ui-monospace,monospace}
|
| 22 |
+
.badge.ok{border-color:rgba(16,185,129,.4);color:#34d399}
|
| 23 |
+
.badge.lock{border-color:rgba(245,158,11,.4);color:#fbbf24}
|
| 24 |
+
code{font-family:ui-monospace,monospace;font-size:.82rem;background:#0f172a;padding:.15rem .4rem;border-radius:4px}
|
| 25 |
+
</style>
|
| 26 |
+
</head>
|
| 27 |
+
<body>
|
| 28 |
+
<h1>REA MCP Server <span id="health" class="badge">checking...</span></h1>
|
| 29 |
+
<p class="sub">Reverse Engineering MCP + Persistent Workspace on <code>/data</code></p>
|
| 30 |
+
|
| 31 |
+
<div class="grid">
|
| 32 |
+
<a class="card" href="/code/">
|
| 33 |
+
<h3>/code/ →</h3>
|
| 34 |
+
<p>VS Code Server bound to <code>/data/workspace</code></p>
|
| 35 |
+
</a>
|
| 36 |
+
<a class="card" href="/files/">
|
| 37 |
+
<h3>/files/ →</h3>
|
| 38 |
+
<p>goFiles File Manager & WebDAV on <code>/data</code></p>
|
| 39 |
+
</a>
|
| 40 |
+
<a class="card" href="/opencode/">
|
| 41 |
+
<h3>/opencode/ →</h3>
|
| 42 |
+
<p>OpenCode Router Dashboard & <code>/v1</code> API</p>
|
| 43 |
+
</a>
|
| 44 |
+
<a class="card" href="/rea-status.json">
|
| 45 |
+
<h3>/mcp →</h3>
|
| 46 |
+
<p>Streamable HTTP MCP endpoint + Doctor status</p>
|
| 47 |
+
</a>
|
| 48 |
+
</div>
|
| 49 |
+
|
| 50 |
+
<div class="panel">
|
| 51 |
+
<h2>Active Analysis Engines</h2>
|
| 52 |
+
<div class="badges">
|
| 53 |
+
<span class="badge ok">Node.js 24.x (SQLite ready)</span>
|
| 54 |
+
<span class="badge ok">Ghidra 12.1.4 Headless + JDK 21</span>
|
| 55 |
+
<span class="badge ok">JADX Headless MCP 0.7.1 + JADX 1.5.6</span>
|
| 56 |
+
<span class="badge ok">Apktool 3.0.3</span>
|
| 57 |
+
<span class="badge ok">Binwalk 3.1.0 + Unblob 26.6.4</span>
|
| 58 |
+
<span class="badge ok">Pwntools + WABT + TShark</span>
|
| 59 |
+
<span class="badge lock">Browser / Playwright Hard-Blocked</span>
|
| 60 |
+
</div>
|
| 61 |
+
</div>
|
| 62 |
+
|
| 63 |
+
<script>
|
| 64 |
+
fetch('/healthz').then(r=>r.ok?r.text():Promise.reject()).then(()=>{
|
| 65 |
+
const el=document.getElementById('health');
|
| 66 |
+
el.textContent='MCP Online';el.className='badge ok';
|
| 67 |
+
}).catch(()=>{
|
| 68 |
+
const el=document.getElementById('health');
|
| 69 |
+
el.textContent='Starting...';el.className='badge lock';
|
| 70 |
+
});
|
| 71 |
+
</script>
|
| 72 |
+
</body>
|
| 73 |
+
</html>
|
stub-playwright-index.js
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
/**
|
| 2 |
+
* Strict Security Policy Stub — Playwright & Browser Automation are Prohibited
|
| 3 |
+
*/
|
| 4 |
+
const denied = () => {
|
| 5 |
+
throw new Error("Browser engines and automation are strictly disabled on this system by host security policy.");
|
| 6 |
+
};
|
| 7 |
+
|
| 8 |
+
const pw = {
|
| 9 |
+
chromium: {
|
| 10 |
+
launch: denied,
|
| 11 |
+
launchPersistentContext: denied,
|
| 12 |
+
connect: denied,
|
| 13 |
+
connectOverCDP: denied,
|
| 14 |
+
executablePath: () => ""
|
| 15 |
+
},
|
| 16 |
+
firefox: {
|
| 17 |
+
launch: denied,
|
| 18 |
+
launchPersistentContext: denied,
|
| 19 |
+
connect: denied,
|
| 20 |
+
executablePath: () => ""
|
| 21 |
+
},
|
| 22 |
+
webkit: {
|
| 23 |
+
launch: denied,
|
| 24 |
+
launchPersistentContext: denied,
|
| 25 |
+
connect: denied,
|
| 26 |
+
executablePath: () => ""
|
| 27 |
+
},
|
| 28 |
+
_electron: {
|
| 29 |
+
launch: denied
|
| 30 |
+
},
|
| 31 |
+
_android: {},
|
| 32 |
+
selectors: {},
|
| 33 |
+
devices: {},
|
| 34 |
+
errors: {},
|
| 35 |
+
request: {}
|
| 36 |
+
};
|
| 37 |
+
|
| 38 |
+
module.exports = pw;
|
stub-playwright-index.mjs
ADDED
|
@@ -0,0 +1,12 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import pw from './index.js';
|
| 2 |
+
|
| 3 |
+
export const chromium = pw.chromium;
|
| 4 |
+
export const firefox = pw.firefox;
|
| 5 |
+
export const webkit = pw.webkit;
|
| 6 |
+
export const _electron = pw._electron;
|
| 7 |
+
export const _android = pw._android;
|
| 8 |
+
export const selectors = pw.selectors;
|
| 9 |
+
export const devices = pw.devices;
|
| 10 |
+
export const errors = pw.errors;
|
| 11 |
+
export const request = pw.request;
|
| 12 |
+
export default pw;
|