Skip to content

Latest commit

 

History

History

Folders and files

NameName
Last commit message
Last commit date

parent directory

..
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

README.md

go — LLM honeypot persona

An SSH-exposed honeypot whose shell is an LLM hallucination, driven by ARCP.

An attacker SSHes into :2222, gets a shell that feels like a misconfigured Debian dev server. Every command they type is forwarded as an ARCP tool_call event into a job; the agent invents plausible output via Ollama and the runtime streams it back as a tool_result. Per-attacker persona state (fake $HOME, fake .bash_history, fake uid) is keyed by the SSH session fingerprint and survives reconnects.

Showcases: goroutine-per-connection concurrency, persistent per-job state (session.resume), capability-scoped leases, per-attacker budget enforcement (cost.budget), job.subscribe for an out-of-band defender dashboard, and the full spec event vocabulary (thought, tool_call, tool_result, metric, artifact_ref, progress, log).

Quickstart

cp .env.example .env
make up

In another terminal:

make ssh
# prints the connection string; password is anything
ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null root@localhost -p 2222

Run whoami, id, ls /home, cat /etc/shadow. Each appears in the dashboard event stream as tool_calltool_result. cat /etc/shadow returns a plausible-looking hash file the agent invented. Disconnect, reconnect within 24 hours, and the same fake home directory and history are intact.

Architecture

  ssh client                      ollama
  (attacker)                        ▲
      │                             │ http
      ▼                             │
  ssh-frontend  ──ws/arcp──▶  arcp-runtime
  (per-conn                   (registers
   goroutine)                  honeypot.shell)
                                    │
                                    │ job.subscribe
                                    ▼
                              arcp-client
                              (TUI dashboard,
                               writes loot/)

Four containers in docker-compose.yml: ollama, ssh-frontend, arcp-runtime, arcp-client.

Configure

Variable Default Effect
HONEYPOT_SSH_PORT 2222 Host port the ssh-frontend listens on.
HONEYPOT_HOSTNAME debian-prod-04 Hostname baked into every persona.
HONEYPOT_IDLE_TTL 24h How long a paused job is resumable.
HONEYPOT_PER_SESSION_BUDGET_USD 0.10 Per-attacker cost.budget. 0.00 disables enforcement.
HONEYPOT_MAX_TOKENS 256 Max output tokens per synthesized command.
RUNTIME_STORE_DIR /data Persona-store directory inside the runtime container.
HONEYPOT_DROP_DIR /loot Captured artifact_ref payload dir in the client.
OLLAMA_MODEL qwen2.5:1.5b-instruct See top-level README for alternatives.
ARCP_SDK_VERSION latest Pin a specific module release for reproducible builds.

Cost arithmetic

The default USD:0.10 budget per attacker caps engagement at ~500 commands when the demo is wired against a hypothetical hosted endpoint at $0.50/$1.50 per Mtok (~200 prompt + ~80 output tokens per command). Running locally against Ollama, the cost figure is illustrative only — it still drives cost.budget.remaining decrement so you can watch the budget mechanic in action. Set HONEYPOT_PER_SESSION_BUDGET_USD=0.00 to disable enforcement; don't deploy that way.

What "done" looks like

  • make up brings up four containers; runtime logs honeypot.shell registered.
  • ssh root@localhost -p 2222 with any password lands in a synthetic shell.
  • Dashboard updates within ~500ms with a new session.
  • whoami, id, cat /etc/shadow each appear in the dashboard event stream.
  • Disconnect, reconnect within HONEYPOT_IDLE_TTL: the persona is intact.
  • ~500 commands in one session exhausts the budget; the agent emits Killed, the connection drops, the dashboard shows BUDGET_EXHAUSTED.

Where to add code

  • src/runtime/main.goserver.New, registers honeypot.shell.
  • src/sshfrontend/main.gogolang.org/x/crypto/ssh listener, one goroutine per connection.
  • src/client/main.gobubbletea TUI; subscribes to every honeypot.shell job.
  • src/honeypot/ — Persona, persona store (JSON-on-disk), prompt builder, binary-drop detector, SSH version parser. All pure Go and covered by tests.

Smoke tests

A small set of fast local tests (no docker, no Ollama, no network) covers the on-disk persona store, the prompt builder, the binary-drop detector, and the SSH version/fingerprint helpers.

make test
# or
go test ./...

Verify install only

make verify