Setup and Onboarding
Everything needed to install, configure, and run Echidra OSS locally, in Docker, or on a bare VM.
Setup and Onboarding
Python 3.11+ and, for the dashboard/API/alerts, a local PostgreSQL server. The honeypot itself runs and logs to logs/sessions.jsonl without a database — Postgres only unlocks the dashboard, live classification storage, and alerts.
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
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.
Quick start
A handful of commands, no need to know the underlying modules.
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).
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.
Deployment options
Three supported paths — pick the one that matches where this is running. All three read the same .env file and produce the same logs/sessions.jsonl, so switching between them later doesn't require re-architecting anything.
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
| Protocol | Port | Env override |
|---|---|---|
| SSH-style shell | 2222 | ECHIDRA_PORT |
| HTTP | 8080 | ECHIDRA_HTTP_PORT |
| FTP | 2121 | ECHIDRA_FTP_PORT |
| Telnet | 2323 | ECHIDRA_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.
One persona at a time
Echidra runs one active persona at a time — set it with ECHIDRA_PERSONA=ubuntu_web_server before echidra start. The five presets visible in the dashboard are configuration choices, not five simultaneous honeypots.
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.
Troubleshooting
- echidra: command not found — your PATH doesn't include the environment
pip install -e .installed into. Activate that virtualenv first, or run the CLI aspython -m echidrainstead. - echidra status shows a listener/API as unreachable — check the other shell running
echidra startfor a traceback; a common cause is a port already in use, often a previousechidra startthat's still running. Runechidra stopto stop it. Otherwise, usess -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.