Honeypot · part of EasySYS

Nobody should knock. When someone does, you'll know.

EasyDecoy runs fake network services, a Telnet login and a web admin panel, that look real and lead nowhere. Nothing legitimate ever connects to them, so every connection, request and login attempt is worth a look. Each one is recorded as a JSON event and can be forwarded over syslog.

Rust core Single binary Never stores passwords JSON + syslog
intruder@10.0.4.17 — bash
# someone on your network tries the "file server" $ telnet fileserver01 Ubuntu 22.04.4 LTS fileserver01 login: admin Password: Login incorrect # EasyDecoy has already written it down → {"decoy":"telnet","kind":"login_attempt", "src_ip":"10.0.4.17","username":"admin", "password_length":8}
Decoys
telnet · http
Events
JSON · syslog
Arch
x86_64 · arm64
Packaged for
Debian / Ubuntu RHEL / Fedora openSUSE / SLES .deb / .rpm x86_64 · arm64
Decoys

Two services, built to be found.

Each decoy answers like the real thing for long enough to be convincing, then refuses. Nothing a client sends is ever run or passed to the host: the decoys only imitate prompts and replies.

:23
Telnet

A login prompt that never lets anyone in

An Ubuntu-style banner and login: prompt that hides the password as it is typed, pauses like a real check, answers Login incorrect, and hangs up after three tries.

connectlogin_attempt
:80
Web admin panel

A sign-in page with nothing behind it

An appliance-style sign-in page on / and /login, a 404 everywhere else, and every sign-in refused. Each request is recorded with its path, Host and User-Agent.

connectrequestlogin_attemptnon_http
easydecoy.toml
Made to look like yours

Named the way your real machines are

A decoy called fileserver01 on a network of fs-ams-02s stands out. Set the banner, the hostname in the prompt, the web server's Server header and the sign-in page's title to match what an intruder expects to find.

bannerhostnameserver_headertitle
Why it works

High signal, by construction.

Intrusion detection usually means telling the attack apart from a flood of normal traffic. A decoy has no normal traffic, so whatever reaches it is the signal.

Alerts worth reading

Nobody has a reason to log in to a server that doesn't exist. A scan, a guessed password or a curious script is exactly what you wanted to hear about.

Passwords never stored

A login attempt keeps the username and the password's length. A colleague who types their real password into the wrong window doesn't end up in a log file.

Nothing is executed

The decoys are low-interaction: scripted prompts and replies, no shell and no real service behind them. There is nothing for an intruder to break out of.

Bounded under attack

Sessions are capped in number, idle time and length, and every read has a size limit. A flood of connections costs sockets for a moment, never memory.

Least privilege

The service runs as its own account with one capability, binding ports below 1024, inside a systemd sandbox that leaves it the log directory and nothing else to write to.

JSON lines and syslog

One JSON object per event, ready for jq, and a copy to any syslog collector, EasyLog included. A collector that is down never holds up the local record.

Architecture

Decoys on your network, events on your desk.

Each decoy reports what happens to it to a single event writer, which appends one JSON line to the events file and hands a copy to the syslog sender. You read the file directly, or the collector it feeds.

YOUR NETWORK EASYDECOY YOU Port scansnmap · masscan Intrudersmoving between hosts Malwareworms · botnets EasyDecoyone binary · own account · sandboxed Telnet decoy:23 login HTTP decoy:80 sign-in Event writerone JSON line events.jsonl/var/log/… SyslogUDP · TCP Administratorstail · jq EasyLogor any collector telnet http http read copy
EasySYS service Your network and people The events file is always written first. Syslog is a copy, and a collector that is down never holds it up.
Deploy

One package. Live when you say so.

EasyDecoy is published as .deb and .rpm packages for x86_64 and arm64 on every GitHub release. Installing starts nothing: the decoys go live when you enable the service. The installation guide has the details.

1
Install the package
It creates the easydecoy account and a default config.
2
Make the decoys look like yours
Ports, banner, hostname and page title live in one TOML file.
3
Enable it and watch
Events land in /var/log/easydecoy, and on your syslog collector if you set one.
# 1 — download from github.com/easysysio/EasyDecoy/releases $ sudo apt install ./easydecoy_*_amd64.deb # or _arm64.deb # 2 — make the decoys look like yours $ sudoedit /etc/easydecoy/easydecoy.toml # 3 — go live, and watch $ sudo systemctl enable --now easydecoy $ sudo tail -f /var/log/easydecoy/events.jsonl
# 1 — download from github.com/easysysio/EasyDecoy/releases $ sudo dnf install ./easydecoy-*.x86_64.rpm # or .aarch64.rpm # 2 — make the decoys look like yours $ sudoedit /etc/easydecoy/easydecoy.toml # 3 — go live, and watch $ sudo systemctl enable --now easydecoy $ sudo tail -f /var/log/easydecoy/events.jsonl
# 1 — download from github.com/easysysio/EasyDecoy/releases $ sudo zypper install ./easydecoy-*.x86_64.rpm # or .aarch64.rpm # 2 — make the decoys look like yours $ sudoedit /etc/easydecoy/easydecoy.toml # 3 — go live, and watch $ sudo systemctl enable --now easydecoy $ sudo tail -f /var/log/easydecoy/events.jsonl
# 1 — build it (needs a Rust toolchain) $ git clone https://github.com/easysysio/EasyDecoy $ cd EasyDecoy # 2 — run it: telnet on :2323, http on :8080 $ cargo run | jq . # 3 — knock, from another terminal $ telnet localhost 2323

Put one decoy on an unused address.

Give it a name that fits in, and wait. If your network is quiet, so is EasyDecoy. MIT licensed and developed in the open.