Setup and Onboarding

Everything needed to install, configure, and run Echidra OSS locally, in Docker, or on a bare VM.

1. Install PostgreSQL

Both platforms below create a dedicated echidra Postgres role, scoped to just owning its own echidra database — not a superuser, since the application only ever needs to create/alter its own tables, never cluster-wide admin rights.

Debian/Ubuntu

sudo apt update && sudo apt install -y postgresql
sudo -u postgres createuser echidra
sudo -u postgres createdb -O echidra echidra
sudo -u postgres psql

At the postgres=# prompt, set the role's password interactively — this keeps it out of your shell history and off the process list, unlike passing it inline to psql -c:

\password echidra
\q

macOS (Homebrew)

brew install postgresql@16 && brew services start postgresql@16
createuser echidra
createdb -O echidra echidra
psql postgres
\password echidra
\q
i
Any password works — echidra is just a placeholder name for the role/database above; set your own password and use it in .env next. An explicit password, rather than relying on peer/trust auth, avoids connection failures that vary by how your local pg_hba.conf is configured.

2. Install Echidra

git clone https://github.com/Qyleron/EchidraOSS.git
cd EchidraOSS
python3 -m venv .venv
source .venv/bin/activate
pip install -e .

This creates an isolated Python environment, installs Echidra into it, and puts the echidra command on your PATH for the current shell. Re-run source .venv/bin/activate in any new terminal before using echidra.

3. Configure .env

cp .env.example .env

Open .env and check only the uncommented ECHIDRA_DATABASE_URL line — with the role/database above, it should read (swap in the password you set with \password):

ECHIDRA_DATABASE_URL=postgresql://echidra:<your-password>@localhost:5432/echidra

Everything else in .env.example has a working default — leave it as-is for a first run.

echidra help       # lists every subcommand (init/start/stop/classify/status/help)
echidra init       # creates .env, generates ECHIDRA_INGEST_API_KEY, initializes the schema
echidra start      # runs the honeypot listeners and the API/dashboard together until Ctrl+C
echidra status     # in a second shell: confirms listeners/API/database are up
echidra stop       # in a second shell: stops a running `echidra start`

Then open http://localhost:8000 — it takes you straight to the dashboard (sign up on first visit).

!
Only the first signup succeeds. Echidra is single-operator by default — once one dashboard account exists, signup closes (403 for anyone else). Use Login from then on; set ECHIDRA_ALLOW_SIGNUPS=true in .env if you deliberately want more than one dashboard user.

No PostgreSQL yet? echidra init skips the database step and tells you so — the honeypot still runs and logs to logs/sessions.jsonl, you just won't get the dashboard/API or live alerting until ECHIDRA_DATABASE_URL is set and you re-run echidra init.

Resetting your local database

The echidra role isn't a superuser and doesn't own CREATEDB, so drop/recreate as the Postgres admin — same as the install step above:

Debian/Ubuntu

sudo -u postgres dropdb echidra
sudo -u postgres createdb -O echidra echidra
echidra init   # re-creates every table

macOS (Homebrew)

dropdb echidra
createdb -O echidra echidra
echidra init   # re-creates every table

echidra init's schema step is idempotent, so you can also re-run it at any time against an existing, populated database to pick up new columns/tables without losing data — only dropdb/createdb above actually discards anything.

JSONL-only mode (no Postgres)

Classify captured sessions on demand:

echidra classify logs/sessions.jsonl

Prints classifier output — actor label, risk, MITRE tags, evidence — for every session in the file. Add --output reports/out.jsonl to write results to a file instead of stdout.

Local machine

Trying it out, day-to-day development — the Quick Start above via the echidra CLI.

Docker Compose

A self-contained stack (honeypot + API + Postgres) on any machine with Docker.

systemd (bare VM)

A long-running deployment on a VM you administer directly, without Docker.

Default listeners

ProtocolPortEnv override
SSH-style shell2222ECHIDRA_PORT
HTTP8080ECHIDRA_HTTP_PORT
FTP2121ECHIDRA_FTP_PORT
Telnet2323ECHIDRA_TELNET_PORT

Set any protocol port to 0 to disable that listener. Pick a persona with ECHIDRA_PERSONA=ubuntu_web_server set before echidra start.

Signup is only open until the first dashboard account exists — after that it returns 403 unless you set ECHIDRA_ALLOW_SIGNUPS=true. POST /classify/session/store similarly refuses all requests until ECHIDRA_INGEST_API_KEY is set and sent back as the X-Api-Key header — echidra init generates this for you.

Full Docker Compose and systemd instructions, plus architecture notes, live in the repo's docs/DEPLOYMENT.md and CONTEXT.md.

To capture different attack profiles in parallel, run Echidra on multiple servers, each with a different persona, all pointing at the same ECHIDRA_DATABASE_URL. The dashboard aggregates sessions from all of them, tagged by persona_id, so you can compare attack patterns across personas in the Analytics and Intelligence pages.

  • echidra: command not found — your PATH doesn't include the environment pip install -e . installed into. Activate that virtualenv first, or run the CLI as python -m echidra instead.
  • echidra status shows a listener/API as unreachable — check the other shell running echidra start for a traceback; a common cause is a port already in use, often a previous echidra start that's still running. Run echidra stop to stop it. Otherwise, use ss -tulnp | grep <port> to identify the PID and terminate it only if it is the stale Echidra process.
  • Working in a remote VS Code session (Remote-SSH, WSL, Codespaces, a dev container) — this workspace turns off remote.autoForwardPorts, so port 8000 won't auto-forward. Forward it yourself: Ctrl+Shift+P → "Forward a Port" → 8000.