Open-source project
janmojzis/tinyssh avatar
janmojzis/tinyssh

TinySSH review: a minimal SSHv2 server for constrained systems

TinySSH is small server (less than 100000 words of code)

1,535 stars83 forksCNOASSERTION

At a glance

What is it?
TinySSH is a compact C SSH server built around a restricted SSHv2 feature set and modern cryptography. It fits controlled shell-access deployments, but its lack of password authentication, forwarding, compression, and client environment variables is substantial.
Who is it for?
Adopt TinySSH when a compact SSH server with a deliberately restricted feature set fits the deployment and systemd, tcpserver, BusyBox, or inetd is available. Do not adopt it for password-based access, port forwarding, agent forwarding, X11 forwarding, compression, or client-supplied environment variables.
Can I use it commercially?
Check first. The repository uses a licence we do not classify automatically, so read its LICENSE file before any commercial use.
Is it still maintained?
Yes. The repository last received commits 2 days ago.
What is it written in?
Mainly C, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

TinySSH's restricted SSHv2 scope

TinySSH, implemented as the tinysshd server, provides remote shell access while deliberately excluding much of the SSH feature surface found in general-purpose servers. The README describes it as a minimalistic implementation of a subset of SSHv2. It does not implement SSH1, compression, port forwarding, agent forwarding, or X11 forwarding. Password and hostbased authentication are also absent because the project classifies them as unsafe features.

The target user is an administrator who needs SSH shell access but does not depend on those excluded capabilities. The code-size constraint is central to the project. The repository description calls TinySSH less than 100,000 words of code, and the README states that release 20261001 contains 74,260 words of code. The README labels 20261001 a beta release and describes beta as ready for production use, although it still describes stable as an expected future stage.

That narrow scope affects adoption more than conventional deployment options. A client configuration that expects a password prompt, forwarded port, X11 session, compressed stream, or transferred environment variable will not match TinySSH's documented behavior. Missing features are easy to classify. The environment-variable restriction is also explicit: TinySSH has rejected every client-supplied `env` channel request since version 20260906. This is a deliberate compatibility change rather than a missing convenience setting.

Curve25519, sntrup761, Ed25519, and ChaCha20-Poly1305

TinySSH uses a compact modern algorithm set rather than negotiating the broad historical catalogue associated with SSH. For version 20261001, the README lists `curve25519-sha256`, `[email protected]`, `[email protected]`, and `sntrup761x25519-sha512` for `KexAlgorithms`. The documented cipher is `[email protected]`, and the host key algorithm is `ssh-ed25519`.

The README also lists `hmac-sha2-256` under `MACs`. It explains that this algorithm is advertised for protocol compatibility, while packet authentication comes from the `[email protected]` AEAD cipher. TinySSH implements the OpenSSH strict key-exchange extension `[email protected]`.

Two documented command-line options can restrict the exchange set further. The Curve25519 algorithms can be disabled with `-S`. The post-quantum `[email protected]` algorithm can be disabled with `-P`. These switches provide limited policy control, but the README does not document a file-based algorithm policy. A deployment that must enforce an organization-wide SSH cipher policy would need to establish separately whether TinySSH can satisfy it.

Older cryptography is intentionally unsupported. The README names RSA, DSA, HMAC-MD5, HMAC-SHA1, 3DES, and RC4 as examples that TinySSH does not implement. Client compatibility therefore needs an explicit check against the algorithms above, especially for embedded clients or old administrative systems.

Fixed-size packet paths and authorization memory

The README states that TinySSH processes SSH packets with fixed-size buffers. This supports the project's compact design by avoiding a general-purpose allocation policy for ordinary packet handling. The repository layout is consistent with that architecture. It includes separate C modules and headers for packet reception and transmission, packet parsing, packet authentication, channel requests, channel opening, connection information, key exchange, and channel backends.

Authorization path resolution is different. The README says it uses dynamically allocated memory, and that an allocation failure rejects authorization. That boundary is explicit: memory-allocation failure does not cause the server to proceed with an unresolved or incomplete authorization path. The README does not describe any fallback path, retry policy, or operational setting for this case.

Repository files further show separate implementations for stream encryption, authentication, signature verification, X25519 scalar multiplication, Ed25519 signing, SHA-256, SHA-512, and sntrup761x25519 key establishment. This separation allows the server to combine its own cryptographic code with optional library implementations, but the README does not explain the build-time selection process in enough detail to assess which variant an installation uses.

Fixed buffers should not be read as a performance claim. The repository contains `_tinysshd-speed.c`, but neither the README nor the listed Makefile rules provide a benchmark procedure or results. Engineers evaluating constrained hardware therefore need to inspect their own deployment rather than infer throughput from the file name.

Building and installing the tinysshd binaries

The README gives a short source build followed by a privileged installation. Run these commands from the repository root:

bash
make
sudo make install

The first command builds the project. The second installs its files under the configured prefix, which defaults to `/usr/local` in the Makefile. The Makefile also recognizes `CC`, `CFLAGS`, `LDFLAGS`, `CPPFLAGS`, `DESTDIR`, `PREFIX`, and `INSTALL`, so a packager can supply its own build or installation variables. The README does not provide a dependency-install step.

After installation, create the server key directory and initialize its host key as follows:

bash
mkdir -p /etc/tinyssh
tinysshd-makekey /etc/tinyssh/sshkeydir

The first command creates the parent directory under `/etc`. The second asks `tinysshd-makekey` to prepare the key directory. The README's launch examples then pass `/etc/tinyssh/sshkeydir` to `tinysshd`.

The Makefile identifies `tinysshd`, `tinysshd-makekey`, `tinysshd-printkey`, and `tinysshnoneauthd` as linked programs. The README does not document the role of `tinysshnoneauthd`, so it should not be substituted for the normal daemon without checking its source and intended deployment context.

Starting TinySSH with tcpserver or BusyBox

TinySSH's launch model delegates listening to an external service wrapper. The README gives a `tcpserver` command that listens on TCP port 22 and starts `tinysshd` for accepted connections:

bash
tcpserver -HRDl0 0.0.0.0 22 /usr/sbin/tinysshd -v /etc/tinyssh/sshkeydir &

Here, `0.0.0.0` requests listening on all IPv4 interfaces, while the key directory is `/etc/tinyssh/sshkeydir`. The exact meaning of every `tcpserver` flag is outside TinySSH and is not documented in the project README. Operators should review the flags against their local `tcpserver` documentation rather than assuming that the example defines a portable policy.

The README also provides a BusyBox `tcpsvd` example:

bash
busybox tcpsvd 0 22 tinysshd -v /etc/tinyssh/sshkeydir &

This form relies on BusyBox and on `tinysshd` being discoverable in the command path. It differs from the preceding example in both listening utility and executable path. The README does not provide a BusyBox build recipe or list the applets required beyond the shown `tcpsvd` invocation.

Both examples run the listener in the background with `&`. The README does not document log routing, process supervision, restart behavior, or shutdown handling for these two forms. A production service should preserve the documented listening command while supplying the missing lifecycle management from the host system's service configuration.

TinySSH under inetd and systemd socket activation

For inetd systems, the README places an SSH service entry in `/etc/inetd.conf`:

bash
ssh stream tcp nowait root /usr/sbin/tinysshd tinysshd -l -v /etc/tinyssh/sshkeydir

This entry asks inetd to handle the socket and invoke the server. The command includes `-l` and `-v`, but the README does not define these flags. The extra `tinysshd` shown after the executable path appears in the documented line, so it should not be silently removed when converting the example into a configuration.

The systemd example is split between a socket unit and a templated service unit. The socket listens on port 22 and accepts connections:

ini
[Socket]
ListenStream=22
Accept=yes

The service prepares the key directory quietly, loads optional environment settings, and starts TinySSH:

ini
[Service]
ExecStartPre=-/usr/sbin/tinysshd-makekey -q /etc/tinyssh/sshkeydir
EnvironmentFile=-/etc/default/tinysshd
ExecStart=/usr/sbin/tinysshd $TINYSSHDOPTS -- /etc/tinyssh/sshkeydir

The service also sets `KillMode=process`, accepts exit status 111, connects standard input to the socket, and sends standard error to the journal. The socket unit checks that `/etc/tinyssh/disable_tinysshd` does not exist. The README does not document the contents of `/etc/default/tinysshd`, so deployments must define only settings appropriate to the installed version.

Environment requests, legacy clients, and maintenance boundaries

Since version 20260906, TinySSH rejects client-supplied environment variables carried in `env` channel requests. The README warns specifically about OpenSSH `SendEnv` and `SetEnv`. A required value must instead exist on the server. This change can alter application startup when a shell expects per-session configuration sent by the client.

TinySSH is therefore the wrong server for workflows that require environment transfer. It is also the wrong choice when users depend on password authentication or when infrastructure requires SSH1, port forwarding, agent forwarding, X11 forwarding, or compression. Unlike OpenSSH, whose client options are referenced in the compatibility warning, TinySSH implements a much smaller protocol surface. The tradeoff is reduced feature scope rather than a drop-in SSH replacement.

The repository is not archived, and its last push was on 2026-10-16. Releases 20261001, 20260906, and 20260601 were published on 2026-10-01, 2026-09-06, and 2026-06-01, respectively. These dates show continued repository and release activity, but they do not prove compatibility with a particular distribution.

The project uses a custom license in `LICENSE.md`. GitHub's repository classification does not summarize its permissions or conditions, and the README does not replace that document. Integrators must inspect `LICENSE.md` before redistribution. The README also does not document a rollback procedure, upgrade migration guide, supported operating-system matrix, or service-account setup checklist.

Editorial conclusion

Adopt TinySSH when a compact SSH server with a deliberately restricted feature set fits the deployment and systemd, tcpserver, BusyBox, or inetd is available. Do not adopt it for password-based access, port forwarding, agent forwarding, X11 forwarding, compression, or client-supplied environment variables. Before deployment, verify the custom LICENSE.md terms, the required client algorithms, and the operating-system service configuration.

Frequently asked questions

How do I install TinySSH?

The README documents building the source with `make` and installing it with `sudo make install`. It then shows creating `/etc/tinyssh/sshkeydir` with `tinysshd-makekey`.

Does TinySSH support password authentication?

No. The README explicitly lists password authentication and hostbased authentication as unsafe features that TinySSH does not implement.

Can TinySSH accept environment variables from an SSH client?

No. Since version 20260906, TinySSH rejects client-supplied environment variables in `env` channel requests. The README says required variables must be set on the server instead.

Which SSH algorithms does TinySSH support?

For version 20261001, the README lists four key exchanges, `[email protected]` as the cipher, and `ssh-ed25519` for host keys. It also advertises `hmac-sha2-256` for protocol compatibility.

Can TinySSH run under systemd?

Yes. The README provides socket and service units that listen on port 22, prepare the key directory, read `/etc/default/tinysshd`, and launch `tinysshd` with `/etc/tinyssh/sshkeydir`.

Official sources

  1. Issues
  2. janmojzis/tinyssh on GitHub
  3. README
  4. Releases
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/janmojzis-tinyssh.svg)](https://hysenlabs.com/projects/janmojzis-tinyssh)

Was this useful?