build: multi-stage Alpine Dockerfile, compose, Makefile, README
This commit is contained in:
@@ -0,0 +1,116 @@
|
||||
# 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"]
|
||||
Reference in New Issue
Block a user