Installing TinySSH

Trying out the new minimalistic ssh server in parallel of sshd
2016-01-26 sysadmin

TinySSH is an interesting piece of software. It is a ssh server that intentionally doesn’t implement:

  • password based authentication
  • neither DSA nor RSA key support
  • no sftp support, scp works just fine

There’s no configuration file. The end result is very small, as the author says: “less than 100000 words of code”. While Dropbear is designed for “embedded” systems, TinySSH has even smaller feature set.

I decided to give it a try on a Raspberry Pi2 running Raspbian Jessie Lite.

It is also an occasion to learn systemd while at it, as it’ll become the default on the next Ubuntu LTS. This post is a mix of experience of learning both TinySSH and systemd.

Algorithms

TinySSH preferred algorithms are Ed25519 for authentication instead of RSA, curve25519 for key exchange (albeit I observed ECDH being used) and chacha20-poly1305 for streaming cipher instead of AES-CTR-MD5 / AES-CTR-SHA1. They are respectively PubkeyAcceptedKeyTypes, KexAlgorithms and Ciphers in ssh_config. HostKeyAlgorithms is also limited by TinySSH’s support of only ssh-ed25519 and ecdsa-sha2-nistp256.

It is possible to lock down OpenSSH client with this .ssh/config:

Ciphers chacha20-poly1305@openssh.com
HostKeyAlgorithms ssh-ed25519
KexAlgorithms curve25519-sha256@libssh.org
# PubkeyAcceptedKeyTypes ssh-ed25519

PubkeyAcceptedKeyTypes is only supported in OpenSSH 7.0 and Ubuntu 14.04 includes 6.6.1 but this doesn’t matter since the user simply has to not create a .ssh/id_rsa.

With this configuration, the same parameter will be used when connecting to both TinySSH and OpenSSH servers. This won’t work on Dropbear, more on that in the follow up post.

Building TinySSH

This is very easy.

git clone https://github.com/janmojzis/tinyssh
cd tinyssh
./make-tinyssh.sh

The binaries are in ./build/bin/

Building with NaCl

TinySSH supports building with NaCL, not to be confused with Native Client.

dpkg-buildpackage

This will generate binaries in debian/nacl-20110221/build/bin. I haven’t tried it yet but the speed up is supposed to be significant.

Install user key

Let’s generate an Ed25519 key via OpenSSH’s ssh-keygen.

This is confusing that the Ed25519 paper named the algorithm EdDSA, which must not to be confused with ECDSA!

  1. Create a new Ed25519 key: ssh-keygen -t ed25519
  2. Copy the public key from $HOME/.ssh/id_ed25519.pub on your host to $HOME/.ssh/authorized_keys on your server.

Temporary non-root server

You can start TinySSH as a normal user using tcpserver as the socket broker on port 10022:

./tinysshd-makekey ./keys
tcpserver -HRDl0 0.0.0.0 10022 ./tinysshd -v ./keys

In that case, the server will only accept authentication as the current user, which is a nice property. You can use this temporary server to scp file around then close the server.

This permits ensuring that the server is well configured.

To start the server as a root listener (at your own risk and peril), prefix with sudo

Install TinySSH system wide

The rest is all running as root:

sudo -i

Create the host keys

TinySSH doesn’t have a standardized location for its keys. Using: /etc/tinyssh/sshkey.d

cd /path/to/tinyssh
./make-install.sh
mkdir -p /etc/tinyssh
/usr/sbin/tinysshd-makekey /etc/tinyssh/sshkey.d

Install TinySSH as a systemd socket server

Inspired by systemd ssh configuration on Raspbian, a systemd author blog post and the official documentation for socket, exec and service, here’s a quick howto to setup TinySSH as an alternate ssh server on port 10022.

It’s as simple as two text files and 2 commands.

Write the files

cat > /etc/systemd/system/tinysshd@.service << EOF
[Unit]
Description=TinySSH per connection daemon
After=auditd.service

[Service]
ExecStart=/usr/sbin/tinysshd -v /etc/tinyssh/sshkey.d
StandardInput=socket
StandardError=journal
EOF
cat > /etc/systemd/system/tinysshd.socket << EOF
[Unit]
Description=TinySSH server socket
Before=tinysshd.service
Conflicts=tinysshd.service

[Socket]
ListenStream=10022
Accept=yes

[Install]
WantedBy=sockets.target
EOF

Reload systemd configuration and start the service

systemctl daemon-reload
systemctl enable tinysshd.socket

You should be able to ssh in right away.

Debugging the server

Debugging the server is mostly debugging systemd.

Digital Ocean wrote a nice FAQ about systemd. Here’s a dump of a few commands you may find useful:

systemctl --version
systemctl list-units
systemctl status
systemctl status tinysshd*
journalctl -xn
journalctl --unit tinysshd.socket
journalctl --unit tinysshd@*

Rambling

Side notes on systemd itself

  1. The main systemd caveat IMHO is that systemd silently ignore failures, so it is important to validate your files manually. In theory one would use systemd-analyze verify tinysshd.socket but it was added in 216 yet Raspbian Jessie includes systemd version 215!
  2. systemctl uses both non-ASCII characters, color and automatic paging (e.g. less) which surprised me in a positive way.

Tuning

You may want to adjust MaxConnections and NoDelay.

More systemd fun

ArchiLinux has a nice HowTo to automatically start ssh tunnels with systemd. IMHO this makes systemd quite appealing as creating boot up services is very simple.

Conclusion

While I’m concerned by the coding style (lacks of brackets around conditions: a recipe for another goto fail), I like the philosophy and the fact that less secure algorithms (like md5) are not implemented.

TinySSH is very well adapted to run with systemd because there’s no background server running, the server is started up on demand and throttling is handled by systemd. This reduce memory usage for low memory system, like containers.

It is also very interesting that the server can be started as a user process, it was especially useful for quick iteration.

In the next post, I compare TinySSH to OpenSSH and Dropbear.

Updates:

2016-01-29: Changed /lib/systemd/system/ to /etc/systemd/system/ which is what is recommended by systemd FAQ.