Skip to content

Security model

A decoy is the one service on your network built to be found by an intruder. EasyDecoy is designed on the assumption that everyone who connects to it is hostile, and that it should give them nothing to use.

Low-interaction by design

The decoys imitate a service's prompts and replies, and that is all they do. There is no shell behind the Telnet login, no web application behind the sign-in page, and no real service anywhere a client could reach. Nothing a client sends is executed, interpreted or passed to the host.

Passwords are never stored

A login attempt records the username and the password's length. Anyone who reaches a decoy might be a colleague typing their real password into the wrong window. Storing it would turn the decoy into a store of real credentials for the next intruder to find.

Hostile input, bounded

Protection Limit
Open sessions, across all decoys max_connections, default 256
Silence before a client is dropped idle_timeout_secs, default 30 s
Longest session session_limit_secs, default 120 s
Telnet line 1024 bytes
HTTP request head / body 8 KiB / 4 KiB
Recorded text, per field 16 to 512 characters

Connections beyond the session limit are closed at once, so a flood costs a socket for a moment, never a buffer or a task. Everything recorded from a client has its control characters replaced, so it cannot forge log lines or send escape sequences to the terminal of whoever reads them.

EasyDecoy is written in Rust, so the code that parses hostile input is memory-safe.

Least privilege

The packaged service runs as its own easydecoy account, never as root. Its one extra permission is binding ports below 1024 (CAP_NET_BIND_SERVICE). systemd then takes away what it has no use for:

  • The whole filesystem is read-only to it, except /var/log/easydecoy.
  • No access to home directories or devices, and a private /tmp.
  • No new privileges, no set-uid, no kernel tunables or modules, no clock, hostname or namespace changes.
  • Only the system calls an ordinary network service makes, and only IPv4, IPv6 and local sockets.
  • No writable executable memory.

systemd-analyze security easydecoy shows the full list on your host.

Containers

Some of these settings depend on kernel features that unprivileged containers, LXC in particular, don't always provide. If the service fails to start inside one, journalctl -u easydecoy names the setting.

What EasyDecoy does not do

  • It is not invisible. A careful intruder can tell a low-interaction decoy from a real service, for example by trying commands it never gets to run. Decoys catch the scans, the guesses and the scripts, which is most of what moves through a network.
  • It does not block anyone. It records; acting on what it records is up to you or your collector.
  • No encryption. There is no HTTPS or SSH decoy yet, and syslog is sent as plain UDP or TCP. Keep the path to your collector on a network you trust.
  • The events file is not tamper-proof. Anyone with root on the decoy host can edit it. Sending events to a collector keeps a copy out of reach.