Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

5 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

RollingPanda

License

A lightweight SSH-2 server in Rust, inspired by DropBear. RollingPanda does not use system accounts (/etc/passwd, PAM, or Windows users). It authenticates only against a username and password compiled into the binary.

Repository: github.com/uber6/RollingPanda

Typical uses: embedded devices, appliances, lab jump boxes, or any host where you want a fixed SSH login without provisioning OS users.

Security: Default credentials are for local testing only. Rebuild with your own ROLLINGPANDA_* values before any real deployment.

Features

Capability Details
Authentication Password only (baked in at compile time)
Host identity Ephemeral Ed25519 host key in memory (optional --host-key file)
Sessions Interactive shell and remote commands (ssh host, ssh host cmd)
Platforms Linux, macOS, Windows (PTY via portable-pty)
Default listen 0.0.0.0 on port 2222 (baked-in; customizable at build time)

Public-key authentication is not supported.

Requirements

  • Rust 1.85+ (edition 2024)
  • An SSH client (e.g. OpenSSH) for testing

Quick start

git clone https://github.com/uber6/RollingPanda.git
cd RollingPanda
cargo build --release

Start the server:

# Linux / macOS
./target/release/rollingpanda

# Windows
.\target\release\rollingpanda.exe

Connect from another terminal:

ssh -p 2222 panda@127.0.0.1

Default credentials (change before any real deployment):

Field Default
Username panda
Password rolling

Build-time configuration

Username, password, and default listen port are embedded at build time:

Variable Default Description
ROLLINGPANDA_USER panda SSH username
ROLLINGPANDA_PASSWORD rolling SSH password
ROLLINGPANDA_PORT 2222 Default TCP port (1–65535)
# Bash / Linux / macOS
export ROLLINGPANDA_USER=admin
export ROLLINGPANDA_PASSWORD='your-secret-here'
export ROLLINGPANDA_PORT=8022
cargo build --release
# Windows PowerShell
$env:ROLLINGPANDA_USER = "admin"
$env:ROLLINGPANDA_PASSWORD = "your-secret-here"
$env:ROLLINGPANDA_PORT = "8022"
cargo build --release

After building with ROLLINGPANDA_PORT=8022, running ./target/release/rollingpanda listens on 8022 unless you pass -p to override for that run.

Security note: strings can often be recovered from the binary (strings, reverse engineering). Treat baked-in passwords like firmware secrets, not as a substitute for vaults, rotation, or network isolation in hostile environments.

Command-line options

rollingpanda --help

  --bind <ADDR>       Address to bind (default: 0.0.0.0)
  -p, --port <PORT>   TCP port (default: compile-time `ROLLINGPANDA_PORT`, else 2222)
  --host-key <PATH>   Load host key from file (default: generate in memory each start)

By default the server generates a new Ed25519 host key in RAM on every start. Clients will warn about a changed host key after each restart unless you use --host-key with a stable file:

# one-time: create a key to reuse
ssh-keygen -t ed25519 -f rollingpanda_host_key -N ""
./target/release/rollingpanda --host-key rollingpanda_host_key

Cryptography

With a typical OpenSSH client, RollingPanda negotiates modern classical algorithms (not post-quantum hybrid KEX):

Layer Algorithm
Key exchange curve25519-sha256
Host key ssh-ed25519
Encryption chacha20-poly1305@openssh.com
Compression none

RollingPanda intentionally does not offer mlkem768x25519-sha256 or zlib compression by default. Some OpenSSH + russh combinations failed handshakes or interactive sessions when those were enabled.

OpenSSH post-quantum warning

You may see:

WARNING: connection is not using a post-quantum key exchange algorithm.

That means the session is encrypted, but not using OpenSSH’s hybrid PQ KEX. It warns about hypothetical “store now, decrypt later” attacks against recorded traffic. It does not mean the connection is plaintext. See OpenSSH PQ documentation.

To force classic algorithms from the client (if needed on an old build):

ssh -p 2222 -o KexAlgorithms=curve25519-sha256 -o Compression=no panda@HOST

Logging

RUST_LOG=rollingpanda=info ./target/release/rollingpanda

Debug server and protocol issues:

RUST_LOG=russh=debug,rollingpanda=debug ./target/release/rollingpanda

Project layout

RollingPanda/
  src/main.rs         CLI, server startup
  src/creds.rs        Compile-time username, password, and default port
  src/hostkey.rs      In-memory or file-backed Ed25519 host key
  src/handler.rs      SSH auth, channels, algorithm preferences
  src/shell.rs        PTY bridge (shell and exec)
  src/pty_filter.rs   Windows: strip ConPTY CSI private-mode sequences
  .cargo/config.toml  Release linker size opts (MSVC / GNU)

Troubleshooting

Handshake fails: SshEncoding: length invalid

Rebuild the latest code. The server disables ML-KEM KEX and zlib server-side. If problems persist:

ssh -p 2222 -o KexAlgorithms=curve25519-sha256 -o Compression=no panda@HOST

Session drops on first keystroke

Use a build that bridges the PTY with channel.wait() and data_bytes() (current src/shell.rs). Rebuild and redeploy:

cargo build --release

Port already in use

Only one process can bind to a port.

# Windows
Get-Process rollingpanda -ErrorAction SilentlyContinue | Stop-Process -Force
# Linux
pkill rollingpanda
# or: fuser -k 2222/tcp

Broken keystrokes or garbage on the client after disconnect (Windows server)

ConPTY (used for every Windows PTY) emits CSI “private mode” sequences such as \e[?31;115h and \e[?28;13h. Linux SSH clients do not expect these; they can corrupt your local TTY and leave fragments like ;28;13;1;32;1_ on your shell after exit.

RollingPanda strips CSI sequences that use private intermediates (ESC [ ? …) before sending PTY output to the client, uses cmd.exe, forwards window resize, and stops relaying PTY data when the client disconnects.

Rebuild and redeploy on the Windows host. If your local terminal still looks wrong after a bad session, run reset. If you use SSH multiplexing (ControlPath, e.g. /tmp/panda.ssh), test once without it in case a background master is sharing a polluted TTY.

Need to press Enter twice after exit (Windows server)

Older builds only checked whether the remote shell had exited after handling the next SSH packet, so the session stayed open until you pressed Enter again. Current builds select! on process exit and close the channel immediately. Rebuild and redeploy if you still see this.

Host key changed

Remove the old entry from ~/.ssh/known_hosts, or for local testing only:

ssh -o StrictHostKeyChecking=no -o UserKnownHostsFile=/dev/null ...

RollingPanda vs DropBear

DropBear RollingPanda
Implementation C, very small Rust + async runtime
System users Yes No (baked-in creds only)
Public-key auth Yes No
Default port Often 22 2222

License

Licensed under the Apache License, Version 2.0.

File Purpose
LICENSE Full Apache 2.0 legal text
NOTICE Copyright and attribution for RollingPanda

You may use, modify, and distribute RollingPanda (including commercially).

Forks and derivatives

When you redistribute source or binaries (including modified builds):

  1. Include LICENSE and NOTICE unchanged, or with your own copyright line added (do not remove the original notice).
  2. State clearly if your project is a fork and not the upstream RollingPanda release.
  3. Do not use the author’s name to imply endorsement of your derivative without permission.

Questions or contributions: open an issue or pull request on GitHub.

About

Lightweight SSH server with compile-time baked credentials (DropBear-style, Rust + russh)

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages