Files
bug-bounty-harness/recon-triage/Dockerfile
T

117 lines
4.8 KiB
Docker

# syntax=docker/dockerfile:1
#
# recon-triage — Docker-only build. Multi-stage:
# go-builder : compiles pinned ProjectDiscovery Go tools (static binaries)
# test : runs the fully-offline pytest suite (used by `make test`)
# runtime : minimal Alpine image, non-root, with nmap + exploitdb + the app
#
# Alpine is used throughout (musl). All Python deps (pydantic v2 included) ship
# musllinux wheels, so no Debian fallback is needed.
# ---------------------------------------------------------------------------
# Stage 1: build Go recon tools. Pinned for reproducibility.
# ---------------------------------------------------------------------------
FROM golang:1.23-alpine AS go-builder
# libpcap-dev is required to compile naabu; git for go module fetches.
RUN apk add --no-cache git build-base libpcap-dev
ENV CGO_ENABLED=1 GOFLAGS=-buildvcs=false
# Pinned tool versions (see README "Tool versions").
ARG SUBFINDER_VERSION=v2.6.6
ARG DNSX_VERSION=v1.2.1
ARG NAABU_VERSION=v2.3.1
ARG HTTPX_VERSION=v1.6.9
ARG NUCLEI_VERSION=v3.3.5
RUN go install -v github.com/projectdiscovery/subfinder/v2/cmd/subfinder@${SUBFINDER_VERSION} \
&& go install -v github.com/projectdiscovery/dnsx/cmd/dnsx@${DNSX_VERSION} \
&& go install -v github.com/projectdiscovery/naabu/v2/cmd/naabu@${NAABU_VERSION} \
&& go install -v github.com/projectdiscovery/httpx/cmd/httpx@${HTTPX_VERSION} \
&& go install -v github.com/projectdiscovery/nuclei/v3/cmd/nuclei@${NUCLEI_VERSION}
# ---------------------------------------------------------------------------
# Stage 1b: fetch Exploit-DB + searchsploit at BUILD time (release-independent;
# the Alpine `exploitdb` package is not in every release's stable repo). The DB
# ships inside the image, so searchsploit needs NO network at runtime.
# ---------------------------------------------------------------------------
FROM alpine:3.20 AS exploitdb-builder
ARG EXPLOITDB_REF=main
RUN apk add --no-cache git \
&& git clone --depth 1 --branch ${EXPLOITDB_REF} \
https://gitlab.com/exploit-database/exploitdb.git /opt/exploitdb \
&& rm -rf /opt/exploitdb/.git
# ---------------------------------------------------------------------------
# Stage 2: offline test image. No Go tools, no network at runtime — the suite
# is driven entirely by committed fixtures and an injected searchsploit stub.
# ---------------------------------------------------------------------------
FROM python:3.12-alpine AS test
WORKDIR /app
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
COPY pyproject.toml README.md ./
COPY src ./src
RUN pip install --no-cache-dir -e ".[dev]"
COPY tests ./tests
# Fully offline: -p no:cacheprovider keeps it hermetic.
RUN python -m pytest -q -p no:cacheprovider
# ---------------------------------------------------------------------------
# Stage 3: runtime image. Non-root, connect-scan by default (no caps needed).
# ---------------------------------------------------------------------------
FROM python:3.12-alpine AS runtime
# Runtime packages:
# nmap service/version detection
# libpcap naabu runtime dependency
# bash, coreutils searchsploit is a bash script using standard text utilities
# ca-certificates TLS roots for passive sources / optional LLM endpoint
RUN apk add --no-cache \
nmap nmap-scripts \
libpcap \
ca-certificates \
bash coreutils
# Copy compiled recon tools from the builder.
COPY --from=go-builder /go/bin/subfinder /usr/local/bin/subfinder
COPY --from=go-builder /go/bin/dnsx /usr/local/bin/dnsx
COPY --from=go-builder /go/bin/naabu /usr/local/bin/naabu
COPY --from=go-builder /go/bin/httpx /usr/local/bin/httpx
COPY --from=go-builder /go/bin/nuclei /usr/local/bin/nuclei
# Exploit-DB checkout (DB shipped in the image). searchsploit resolves its DB path
# relative to the real script location, so a symlink onto PATH is sufficient.
COPY --from=exploitdb-builder /opt/exploitdb /opt/exploitdb
RUN ln -sf /opt/exploitdb/searchsploit /usr/local/bin/searchsploit \
&& searchsploit --json apache >/dev/null 2>&1 || true
# Install the app into an isolated venv.
RUN python -m venv /opt/venv
ENV PATH="/opt/venv/bin:$PATH"
WORKDIR /app
COPY pyproject.toml README.md ./
COPY src ./src
RUN pip install --no-cache-dir .
# Export the JSON Schema into the image for inspection.
COPY tests/fixtures ./tests/fixtures
RUN python -m recon_triage.schema /app/schemas
# Non-root user. Connect scans need no elevated capabilities.
RUN addgroup -S app && adduser -S -G app -h /home/app app \
&& mkdir -p /data/out /home/app/nuclei-templates \
&& chown -R app:app /data /home/app /app/schemas
USER app
# nuclei templates cache to a mountable volume (not baked into the image).
ENV NUCLEI_TEMPLATES_DIR=/home/app/nuclei-templates
ENV HOME=/home/app
ENTRYPOINT ["recon-triage"]
CMD ["--help"]