Skip to content

Harden Docker Compose: credential security, sqlite support, profiles, and AMASS_LOGLEVEL#13

Open
Dude4Linux wants to merge 12 commits into
owasp-amass:developfrom
Dude4Linux:harden-docker-compose
Open

Harden Docker Compose: credential security, sqlite support, profiles, and AMASS_LOGLEVEL#13
Dude4Linux wants to merge 12 commits into
owasp-amass:developfrom
Dude4Linux:harden-docker-compose

Conversation

@Dude4Linux
Copy link
Copy Markdown

Summary

  • Credential security: Removes hardcoded credentials from config/config.yaml. A new config-init service (Alpine one-shot container) substitutes ${AMASS_USER}, ${AMASS_PASSWORD}, and ${AMASS_DB} from .env at startup via Docker secrets, so secrets never live in the config file.
  • SQLite support: When neither postgres nor neo4j profile is active, the engine falls back to its built-in SQLite. No database server required for simple deployments.
  • Opt-in profiles: assetdb (PostgreSQL) and neo4j services now use profiles: [postgres] and profiles: [neo4j] respectively, so they only start when explicitly requested. Default (docker compose up -d) runs engine + postal + syslog only.
  • COMPOSE_PROFILES as single DB selector: Replaces the previous DB_SERVER env var — setting COMPOSE_PROFILES=postgres both starts the assetdb service and configures config.yaml to use PostgreSQL. No two variables to keep in sync.
  • AMASS_LOGLEVEL: Adds an AMASS_LOGLEVEL environment variable (INFO/WARN/ERROR/DEBUG) threaded into all six Amass containers via compose.yaml. Replaces a binary debug flag with fine-grained control.
  • Security hardening: All containers get cap_drop: [ALL], security_opt: [no-new-privileges:true], capped resource limits, and structured JSON logging with rotation via YAML anchors.
  • README overhaul: Adds usage examples for all subcommands (enum, subs, assoc, track, viz), shell function tips for Linux/macOS/Windows, and a security note on database port binding.
  • .env.template: Ships a documented template with sensible defaults; .env is gitignored.

Rebase note

This PR supersedes #12 and is rebased onto the current develop tip (commit 784d0c9), incorporating upstream changes to build refs (#develop), the new libpostal repo URL, and the engine URL fix.

Test plan

  • docker compose up -d starts engine + postal + syslog with SQLite (no DB server needed)
  • docker compose --profile postgres up -d starts assetdb, config-init substitutes postgres credentials into config.yaml
  • docker compose --profile neo4j up -d starts neo4j, config-init substitutes bolt credentials
  • docker compose run --rm enum -d owasp.org discovers subdomains
  • AMASS_LOGLEVEL=DEBUG docker compose up -d produces debug output in container logs

🤖 Generated with Claude Code

Dude4Linux and others added 12 commits March 7, 2026 12:18
- Replace tracked .env with .env.template and .gitignore to keep
  credentials, config files, and data directories out of version control
- Add config-init one-shot service using Docker secrets to source .env
  credentials and prepare config.yaml (DB selection + placeholder
  substitution) before any client service starts
- Add config-init dependency to all 5 client services
  (enum, viz, subs, assoc, track)
- Add Neo4j initial database name env var and DB_SERVER switching
  between PostgreSQL and Neo4j
- Rewrite README: streamlined setup instructions, Neo4j Browser
  section, Usage section with examples for all subcommands, shell
  function tips for Linux/macOS/Windows, and simplified update steps

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Pin image versions, replace no-op healthchecks with real checks, bind
database ports to localhost, drop all capabilities (adding back only
what each service needs), add log rotation, enforce resource limits
on all services, and document port binding in README.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Add sqlite as a zero-dependency database option alongside postgres and
neo4j. Propagate AMASS_LOGLEVEL from .env into all amass containers so
users can control log verbosity (INFO/WARN/ERROR/DEBUG) with a single
uncommented line.

config/config-init.sh
  - Resolve DB_SERVER once upfront; default to sqlite when unset
  - Add explicit sqlite branch that comments out all network DB lines
    (session.go falls through to its built-in SQLite when GraphDBs is nil)
  - Gate credential substitution on non-sqlite backends to avoid set -u
    failures when AMASS_USER/PASSWORD/DB are absent from the environment

compose.yaml
  - Add AMASS_LOGLEVEL=${AMASS_LOGLEVEL:-} to engine, enum, viz, subs,
    assoc, and track so the variable flows from .env into each container

.env.template
  - Document sqlite/postgres/neo4j options; postgres remains the default
  - Add commented-out AMASS_LOGLEVEL=INFO with level choices

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds Docker Compose profiles so the heavyweight database services only
start when explicitly requested, making sqlite-only deployments (such as
on a Raspberry Pi) work with a plain `docker compose up -d`.

compose.yaml
  - assetdb assigned profile 'postgres'
  - neo4j assigned profile 'neo4j'
  - engine, viz, subs, assoc, track: remove assetdb/neo4j from depends_on
    (engine depends only on postal + syslog; clients depend only on
     syslog + config-init — the user is responsible for activating the
     right profile before running DB-backed tools)

.env.template
  - Document the three start commands alongside each DB_SERVER option
  - Add commented-out COMPOSE_PROFILES=postgres as a reminder to keep
    DB_SERVER and COMPOSE_PROFILES in sync

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
COMPOSE_PROFILES already controls which database service starts; having a
separate DB_SERVER variable that must be kept in sync was error-prone.
config-init.sh now reads COMPOSE_PROFILES directly, making .env a single
control point for the entire stack.

config/config-init.sh
  - Replace if/elif/else on DB_SERVER with case match on COMPOSE_PROFILES
  - Wrap value in commas (,${COMPOSE_PROFILES:-},) to match whole profile
    names — unrelated profiles (tor, mcp, …) are safely ignored
  - Credential substitution co-located with each database branch

.env.template
  - Remove DB_SERVER; COMPOSE_PROFILES is the only database selector
  - Sectioned layout with whitespace for readability
  - Credentials moved to bottom under their own header

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Hardcoded /home/john/Docker/amass-test caused all benchmark scripts to
fail when run from any other host or user. Use dirname-based resolution
so scripts work wherever the repo is cloned.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Runs only Mode C' (NLP only) and Mode C (brute + NLP), reusing existing
Mode A/B results and ground_truth.txt from a previous benchmark.sh run.
Regenerates the full report at the end.

Usage: benchmark/run_nlp_modes.sh -d <domain> [-t <timeout_min>]

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
…VERRIDE from clients

- config-init.sh: add escape_sed() to escape backslash/pipe/ampersand in
  sed replacement strings, preventing password injection into config.yaml
- config-init.sh: fail fast if AMASS_PASSWORD or POSTGRES_PASSWORD equals
  the .env.template default 'ChangeMe!' before any config files are touched
- config-init.sh: replace /tmp/config.yaml with mktemp + EXIT trap to avoid
  predictable temp filename collision
- compose.yaml: add x-client-hardened anchor (cap_drop ALL, no cap_add) for
  stateless client services (enum, viz, subs, assoc, track) that don't need
  DAC_OVERRIDE; engine, postal, config-init retain the full anchor

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Client containers default to localhost:4000 for the engine GraphQL
endpoint, which resolves to the container's own loopback and fails.
Set AMASS_ENGINE_HOST=engine on enum, viz, subs, assoc, and track so
they resolve the engine container by name via Docker's internal DNS.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two config-init.sh fixes for upstream amass compatibility:

1. Strip the /graphql suffix from the engine URL: upstream amass
   migrated from GraphQL to a REST API at /api/v1/*. The template may
   carry the legacy /graphql path; normalize it to the base URL.

2. chmod 644 config.yaml after writing: config-init runs as root so
   the file is created 0600 root:root. Client containers run as uid=1000
   and silently fall back to SQLite defaults when they cannot read it.
   644 lets the service user read without write.

Also fix the config.yaml template engine URL from the legacy GraphQL
path to the current REST base URL.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Two neo4j-related fixes:

1. Remove NEO4J_initial_dbms_default__database from the neo4j service
   environment. Setting this to ${AMASS_DB} (= assetdb) prevents the
   neo4j-go-driver's VerifyConnectivity from working because the driver
   checks for the default "neo4j" database during routing table resolution.
   Using neo4j's standard default database avoids this startup failure.

2. Hardcode "neo4j" as the database name in the bolt:// URL template.
   The neo4j database is always named "neo4j" with this setup; ${AMASS_DB}
   is only meaningful for postgres.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Adds a bats-based unit test suite (23 tests) covering all
config-init.sh logic — credential guards, DB backend selection,
credential substitution, special-character escaping, profile
exactness, and /graphql stripping — with no Docker required.

Adds integration smoke tests for all three DB backends (SQLite,
postgres, neo4j) and flag tests for -brute, -alts, and -active,
each verified by querying the resulting asset.db or network DB.

Also patches config-init.sh with SECRETS_FILE and CONFIG_FILE
env overrides to enable host-side unit testing, removes stale
benchmark/ scripts and config/proxy.env artifacts, and updates
.gitignore to exclude runtime DB files (config/asset.db*).

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant