Getting Started#
Prerequisites#
Both the manager and agent servers must run a Debian-based Linux distribution (Debian, Ubuntu).
The manager installation will automatically install:
ca-certificates,curl,cronopenssl(PKI generation)apache2-utils(htpasswdfor dashboard basic-auth)python3-pymongo,python3-yaml(interaction with MongoDB and YAML rules from cron scripts)Docker CE + Docker Compose plugin (if not already present)
The agent installation will automatically install:
ca-certificates,curl,jq,openssl,python3uv (modern Python package manager)
Docker CE + Docker Compose plugin (if not already present)
Note
Both machines need root access (sudo) — the install scripts configure system services (Docker, SSH, cron).
Manager Installation#
Clone the repository on the manager server:
git clone https://github.com/ilostmypassword/Melissae.git
cd Melissae/manager/
chmod +x melissae-manager.sh
Launch the interactive console and run install:
./melissae-manager.sh
manager [0 active] > install
The installer performs the following steps:
System packages — Installs prerequisites via
apt-get(Docker, OpenSSL,python3-pymongo,python3-yaml,apache2-utils,cron).PKI initialization — Prompts for the Certificate Authority identity (this CN appears in every TLS certificate — prefer a neutral name to avoid revealing the deployment as a honeypot):
CA Common Name [manager.local CA]: CA Organization (optional, leave blank to omit):
The installer then generates:
CA key: ECDSA P-384, stored in
pki/ca/ca.key(mode 600)CA certificate: 10-year validity, subject built from your inputs (
CN, optionalO)An OpenSSL config (
pki/ca/openssl.cnf), serial file, and index for future cert issuance
Manager certificate — The installer detects the machine’s IP and hostname, then asks:
Manager certificate configuration Detected IP: 192.168.1.10 Detected hostname: manager.local Public FQDN or IP (e.g. manager.example.com) [192.168.1.10]:
A dual-purpose (client + server) certificate is generated with SANs covering the FQDN/IP entered, the detected IP (when distinct),
localhost, and127.0.0.1.Dashboard credentials — Prompts for a username (default:
melissae) and password, saved todashboard/conf/htpasswdusing bcrypt (htpasswd -Bbc).Cron jobs — Three scheduled tasks are added to the system crontab (rule engine, health poller, log purge). See Scheduled Jobs in the Architecture page for the full schedule.
After installation, add your user to the Docker group and apply the changes immediately:
sudo usermod -aG docker $USER
newgrp docker
Note
newgrp docker activates the group in the current shell session without requiring a full re-login. Alternatively, log out and log back in.
Then start the manager stack (MongoDB + Flask API + Nginx/Dashboard):
manager [0 active] > start
This brings up 3 containers:
Container |
Port |
Role |
|---|---|---|
|
127.0.0.1:27017 |
MongoDB data store (local only) |
|
127.0.0.1:5000 |
Flask REST API (local only) |
|
0.0.0.0:443, 0.0.0.0:8443 |
Nginx — serves dashboard (:443) and terminates mTLS ingestion (:8443) |
Note
A fourth optional container, melissae_inspektor (internal port 8088), is
added when the AI analyst is enabled via the inspektor command. See
Enabling Inspektor (optional) below.
Agent Enrollment#
Enrollment is a two-step process: generate a token on the manager, then use it on the agent.
Step 1: Generate the token (manager)#
manager [3 active] > enroll my-agent 192.168.1.50
This command:
Validates the agent name (alphanumeric, hyphens, underscores only)
Generates a dual-purpose certificate for the agent (SANs: agent host, localhost, 127.0.0.1)
Creates a one-time enrollment token (64 hex chars, stored in MongoDB, 10-minute TTL)
Registers the agent in MongoDB with
pendingstatus
The output gives you the exact command to run on the agent:
[✓] Enrollment token generated (expires in 10 minutes)
Run this on the agent:
./melissae-agent.sh install https://<manager-ip>:8443 a1b2c3d4...
Step 2: Install on the agent#
On the agent server, clone the repository:
git clone https://github.com/ilostmypassword/Melissae.git
cd Melissae/agent/
chmod +x melissae-agent.sh
Launch the interactive console and run the install command with the manager URL and token:
./melissae-agent.sh
agent:? [0 active] > install https://192.168.1.10:8443 a1b2c3d4...
Danger
The agent installer will randomize your SSH port to a value between 20000 and 30000. Note this port carefully — it will be displayed at the end of the installation. You will need it to reconnect via SSH to the agent server.
The agent installer performs the following steps:
System packages — Installs
ca-certificates,curl,jq,openssl,python3.Python environment — Installs uv, creates a virtual environment in
daemon/.venv, installs dependencies (requests,pyyaml).Docker — Installs Docker CE + Compose plugin if not already present.
Enrollment — Sends
POST /api/enrollwith the one-time token to the manager (insecure TLS — CA not yet known). The manager responds with:The JSON response contains the fields
agent_id,ca_crt,agent_crt, andagent_key(all base64-encoded where applicable). Certificates are saved inagent/certs/with key permissions set to 600.Configuration — Generates
daemon/config.ymlwith all paths and settings:agent_id: "my-agent" manager: url: "https://192.168.1.10:8443" ca_cert: "/path/to/certs/ca.crt" agent: cert: "/path/to/certs/agent.crt" key: "/path/to/certs/agent.key" health_port: 8444 push: interval_seconds: 10 batch_size: 500 retry_max_seconds: 300 buffer: db_path: "/path/to/data/buffer.db" max_size_mb: 512 modules: ssh: enabled: true log_path: "ssh/sshd.log" ftp: enabled: true log_path: "ftp/vsftpd.log" http: enabled: true log_path: "web/access.log" modbus: enabled: true log_path: "modbus/modbus.log" mqtt: enabled: true log_path: "mqtt/mosquitto.log" telnet: enabled: true log_path: "telnet/auth.log" cve-2026-24061: enabled: false log_path: "cve/CVE-2026-24061/auth.log"
By default, all native modules are enabled and the CVE module is disabled.
mTLS test — Sends a test
POST /api/ingestto the manager with the new certificates. An HTTP 400 or 405 response confirms the mTLS channel is functional.SSH hardening — A random port (20000–30000) replaces port 22 in
/etc/ssh/sshd_config. You are asked whether to restart SSH immediately. Reconnect on the new port after installation.
Configuring Modules#
Before starting the agent, review daemon/config.yml to enable/disable modules. You can also use the CLI:
agent:my-agent [0 active] > list # See available modules
agent:my-agent [0 active] > disable modbus # Disable a module
agent:my-agent [0 active] > enable cve-2026-24061 # Enable a CVE module
Warning
Modules that bind the same host port cannot run together. For example, telnet (port 23) and cve-2026-24061 (port 23) conflict — the CLI will reject the combination.
Warning
The CVE module (cve-2026-24061) reproduces a real vulnerability. Deploy it only on machines that are fully isolated from your production infrastructure. It runs with pids_limit: 64, mem_limit: 128m, and a dedicated Docker network (172.30.0.0/24).
Starting Services#
Manager — starts MongoDB, Flask API, and the Nginx/Dashboard container:
manager [0 active] > start
Agent — starts the enabled honeypot containers and the agent daemon (log parser + push):
agent:my-agent [0 active] > start
The agent daemon runs as a background process on the host (not in Docker). It:
Parses raw logs from honeypot containers (incremental, hash-based deduplication)
Buffers parsed entries in a local SQLite database (up to 512 MB)
Pushes batches (up to 500 entries) to
POST /api/ingestevery 10 seconds via mTLSExposes a health endpoint on port 8444 for the manager to poll
Falls back to exponential backoff (up to 5 minutes) if the manager is unreachable
Accessing the Dashboard#
The dashboard is served over HTTPS on port 443 using the manager’s self-signed TLS certificate:
https://<manager-ip>/
Authenticate with the credentials set during install. Your browser will show a security warning because the certificate is signed by Melissae’s internal CA — this is expected. You can import pki/ca/ca.crt into your browser’s trust store to suppress the warning.
Note
Port 8443 is reserved for mTLS-authenticated agent traffic (ingestion and enrollment). Do not use it for browser access.
Tip
After starting the agent, verify that it registered successfully on the manager:
manager [3 active] > agents
The agent should appear with status healthy within a minute of its first log push.
Enabling Inspektor (optional)#
Inspektor is the optional AI threat analyst. It is disabled by default and requires AWS Bedrock credentials with model access. Enable it at any time from the manager CLI:
manager [3 active] > inspektor
The command prompts for your AWS credentials, region and Bedrock model id, saves
them to the manager .env file (chmod 600) with the inspektor Docker
Compose profile, then builds and starts the melissae_inspektor container:
[?] Enable Inspektor AI analyst? [y/N] y
AWS Access Key ID: ...
AWS Secret Access Key: ...
AWS Session Token (optional, press Enter to skip):
AWS Region [us-east-1]:
Bedrock Model ID [anthropic.claude-3-5-sonnet-20240620-v1:0]:
Running inspektor again lets you reconfigure or disable it. Once enabled, the
Inspektor page appears on the dashboard for chat and on-demand threat
briefings. See AI Threat Analyst (Inspektor) for the full reference.
Note
The Inspektor service listens on port 8088 on the internal Docker network
only and is reached exclusively through the manager API proxy — it is never
exposed externally.