#ssh #server #security #tarpit #netsec

app decoyssh

A compact and portable SSH tarpit server

8 stable releases

1.0.7 Mar 3, 2024
1.0.6 Feb 19, 2024
1.0.5 Nov 5, 2023
1.0.3 Mar 16, 2023
0.3.0 Jul 7, 2022

#610 in Network programming

Download history 120/week @ 2024-02-14 61/week @ 2024-02-21 161/week @ 2024-02-28 20/week @ 2024-03-06 5/week @ 2024-03-13

279 downloads per month

ISC license

15KB
260 lines

DecoySSH

It’s a compact and portable SSH tarpit written in Rust and async-std.

Motivation

Yup, there are millions of SSH tarpit servers, besides the original one. Some are written in Rust as well, but—as far as I’ve seen—none of them use async-std. To my taste, some of them are a bit too much, and some lack configurability. So here’s my take.

Yet this pet project developed not to compete with anyone but to learn new things and experiment. Not just with Rust and async-std but also with things behind: GitHub workflows, cross-compiling, containerization, etc. A somewhat complete delivery cycle, in other words. (But no tests yet, maybe someday.)

Despite that, it should be 100% usable. Give it a try if it suits your tarpit needs.

Usage

DecoySSH is available as stand-alone binaries, a Cargo package, and a container image.

Binaries can be found on the repo’s releases page. If there’s no platform you’re looking for, you can compile an appropriate binary yourself. Or feel free to create a PR or an issue.

Cargo package can be installed as usually:

cargo install decoyssh

The container image is available as docker.io/aeron/decoyssh and ghcr.io/Aeron/decoyssh. You can use them both interchangeably.

docker pull docker.io/aeron/decoyssh
# …or…
docker pull ghcr.io/aeron/decoyssh

App Options

Running the app with -h or --help option will give you the following:

Usage: decoyssh [OPTIONS]

Options:
  -4, --ipv4-address [<IPV4_ADDR>...]  IPv4 address(es) to bind on [max: 8]
  -6, --ipv6-address [<IPV6_ADDR>...]  IPv6 address(es) to bind on [max: 8]
  -d, --delay <DELAY>                  Message delay (in milliseconds) [default: 10000]
  -l, --length <LENGTH>                Maximum line length [default: 32]
  -c, --capacity <CAP>                 Maximum number of connections [default: 4096]
  -h, --help                           Print help information
  -V, --version                        Print version information

If no addresses are given, it’ll run on 0.0.0.0:22 only. To use both IPv4 and IPv6 addresses, both options—with or without values—must be given explicitly.

All options are available as environment variables, with the same name as value names but with the DECOYSSH_ prefix. For example, DECOYSSH_IPV4_ADDR.

Container Running

Running a container is pretty straigthforward:

docker -d --restart unless-stopped --name decoyssh \
    --user=65534 \
    -p 22/2222:tcp \
    -e DECOYSSH_PORT=2222 \
    docker.io/aeron/decoyssh

By default, the containerized app uses only an IPv4 address and 2222 port instead of 22.

If you’re planning to use IPv4 binding only, you can use the container-specific DECOYSSH_PORT variable to change the listening/exposed port number. Otherwise, use standard environment variables explicitly.

Don’t forget about the unprivileged user trick. The container itself won’t enforce any specific UID.

Dependencies

~9–20MB
~284K SLoC