Hacker News new | past | comments | ask | show | jobs | submit login
Tinyssh (tinyssh.org)
229 points by tosh on Dec 23, 2021 | hide | past | favorite | 90 comments



I love the concept, specifically launching new servers to avoid dynamic allocation. However: > no dependency on OpenSSL - TinySSH has its own crypto library compatible with NaCl, Libsodium

Apologies in advance for being a security curmudgeon, but I'll eat my hat if their homegrown crypto library doesn't have vulnerabilities. Crypto is hard, even for the best experts. The only way to get this right is with code that's had many eyes on it and has been battle tested.


NaCl/libsodium is a modern implementation by crypto experts. It's as far cry from "homegrown" as you can get. Arguably, it's better designed than OpenSSL, having been started by crypto experts in response to Heartbleed and the concern for the code quality and legacy code in OpenSSL.

Edit: my bad, TinySSH is using its home-grown version of NaCl, so parent's comment applies.


Yeah, but it's not using NaCl or libsodium. It just says it's "compatible with" them.


> speed - TinySSH can be also compiled using high-speed NaCl library instead of internal.

Sounds like you can use NaCI directly.


I wonder what is the advantage of one over the other? The faq doesn't say.


Probably just the fact they can build completely "in house" with no dependencies. A lot like the appeal of static binaries (with plentiful drawbacks ofc)


A small, 0-alloc, statically linked SSH server is perfect for installation on consumer routers that manufacturer didn't intend to run SSH


> having been started by crypto experts in response to Heartbleed

This isn't quite right. NaCl is a Daniel J. Bernstein project that predates Heartbleed by several years[0]. Though I'm sure Heartbleed generated new interest in better designed, more secure, crypto libraries.

[0] https://en.wikipedia.org/wiki/NaCl_(software)


If I understand correctly, what this reply is suggesting is that the tinyssh author took reference implementions for certain primitives from djb and changed them into something "home-grown" that is consequently now vulnerable because [unspecified]. That's quite a bold claim. To be fair, when compiling tinyssh the build script checks for external versions of these primitives before using the supplied "home-grown" ones.

There is an obvious error in this reply as well. NaCl was not "started by crypto experts in response to Heartbleed." NaCl was published in 2011 and the Heartbleed did not occur until 2014.


> Edit: my bad, TinySSH is using its home-grown version of NaCl, so parent's comment applies.

Looks like tweetnacl split back up into the same files as the reference implementation.


Sure, but OP wasn't pointing out they use NaCl/libsodium.

> TinySSH has its _own_ crypto library _compatible_ with NaCl, Libsodium...


Compare with:

TinySSH has its _own_ crypto library _compatible_ with NaCl: Libsodium


Annoyingly, NaCl is a crypto library by Daniel Bernstein and NaCl is a sandboxing solution by Google.


They're not using NaCl, they're using a custom code implementation of the relevant NaCl interfaces.


I use tinyssh. Have used it since 2014 without any problems. I use the external NaCl library, not the internal one based on TweetNaCl.

If NaCl, or even TweetNaCl, is "homegrown crypto" why are all these projects using it: https://ianix.com/pub/curve25519-deployment.html OpenSSH included.

How much does tinyssh's internal library differ from TweetNaCl's? Wouldn't a security curmudgeon at least examine those differences. If the user downloads NaCl from https://nacl.cr.yp.to first, tinyssh will use the external NaCl library not the "homegrown" internal library based on TweetNaCl. I never use the internal library.


If it's compatible, what's supposed to be the value in re-implementing libsodium instead of just vendoring or forking it and copying in the important parts?


simple configuration - TinySSH can’t be misconfigured

Seems like a challenge to me!


Sounds like challange accepted by a few of us.


Wow, no dynamic memory allocation stood out to me in the description. Pretty interesting!

This being auditable and significantly decreasing the attack vector surface area for ssh seems promising.


Without having looked into it too deeply I feel that they are somewhat “cheating” by using a superserver to launch a new process for each connection, thus letting the OS handle the dynamic allocation needed for each connection.

Still pretty impressive project. Would be fun to take a deeper look at it at some point.


> […] thus letting the OS handle the dynamic allocation needed for each connection.

This is what PHK did when designing Varnish (IIRC): instead of dealing with lots of files on its own (like Squid), just create some files and do a malloc() on them and let the OS do the work:

* https://varnish-cache.org/docs/trunk/phk/notes.html

One discussion (many others):

* https://news.ycombinator.com/item?id=4874304


It's not malloc() but mmap() if I understand correctly.

It's a beautifully powerful function :)

https://man7.org/linux/man-pages/man2/mmap.2.html


It kind of undercuts the argument, because the dynamic allocator basically just uses mmap as well.

(Some allocators, like glibc may also use brk, but it's possible to write a fully functional allocator with only mmap).


I think the original point still stands. When the application tries to handle memory pressure itself by writing data structures to disk, it will hit the case where the kernel has already paged that memory out, has to reload it, only to write it to disk and free the memory afterwards.


It makes sense though - no memory management simplifies the codebase. Letting the host deal with it instead means you get the niceties of process level isolation and less complexity. More eyes are on the OS level code than would be on this project. It seems very clever to me.


The OS is already handling dynamic memory allocation on each connection. This provides a nice split where you don't need to do it in 2 places.


I haven't seen the "words of code" metric before, and some cursory web searching doesn't reveal much. Is there a standard? Just split on the given language's punctuation/delimiters?


I wondered that too, then figured you'd want to exclude non /[a-z0-9]/I characters.

They answer what it means and provide the command used to figure it out in the first FAQ: https://tinyssh.org/faq.html


Just use wc, it's close enough.

    $ wc
    void main(int argc, char **argv) { printf("Hi, I'm %s\n", argv[0]); }
          1      11      70
      lines   words   chars

    $ tr '()[]{}*+.>,";'"'"- ' ' | wc
    void main(int argc, char **argv) { printf("Hi, I'm %s\n", argv[0]); }
          1      13      70


It's also interesting to see 'Postquantum crypto'.


I remember first seeing it somewhere on cr.yp.to, where it was counted with some regex that did something like splitting it on some delimiter-like characters.


Very timely with an alternative. There’s a huge monoculture risk with everyone using OpenSSH (although I love it).


I believe there are several implementations built off the golang implementation (https://pkg.go.dev/golang.org/x/crypto/ssh) of SSH protocol such as Teleport (https://github.com/gravitational/teleport/)

I'm not familiar with additional approaches, and Teleport is a very different approach than tinyssh, focused on more features and controls than regular SSH. I imagine there are several other good options using the golang libs, or in theory someone could build their own limited implementation as an alternative.

And full disclosure, I work for Teleport, but my comments are my own.


However, it does require an sftp and scp binary from OpenSSH, if these features are to be used.

The latest scp clients use the sftp server, but older implementations will need both to be accessible.


For a secure/minimal set I'd just avoid sftp and it's client-commanded resource management. Just use plain scp, the protocol is very simple.


Funnily enough OpenSSH are switching scp to use the SFTP protocol https://www.openssh.com/txt/release-8.8


You don't even need scp if you go for minimalism. ssh and cat work fine (add tar on top for multiple file transfer).


While it is good to have another alternative, I think Dropbear SSH[1] is also being used very widely.

[1] https://matt.ucc.asn.au/dropbear/dropbear.html


Could not see if it supported SSH Certificates but see no references to them. I'm using those to make it easier to avoid authorized_keys file updates but seems like its not popular.


I too wish it had SSH certificates. We use Dropbear on some embedded targets (Linux on FPGA), and the support for only keys, and difficulty of updating the target, means all our devs share one SSH key to access the target. It's not great.


FYI - ansible has some built ins that let you manage keys pretty easily. Making sure a machine has the right key set only takes a few seconds and can happen entirely over ssh.


Cisco and Juniper don't support them either (at least last I checked), even though I am pretty sure they ship openssh.


No RSA support really stands out. No doubt many reading this have RSA identity keys on disk right now in ~/.ssh. It's been the default for so long.


If you're like me and have just been using RSA because of inertia, here's a discussion of why you might switch to ed25519 as an alternative:

https://www.reddit.com/r/sysadmin/comments/4gktbr/ssh_ed2551...

I particularly enjoyed this answer:

> ed25519 is more secure in practice. One of the biggest reasons to go with ed25519 is that it's immune to a lot of common side channels. While ed25519 is slightly less complex to crack in theory, in practice both of them are long enough that you're never going to be able to crack it, you need a flaw to exploit in the implementation or a substantial leap forward in cryptanalysis. ed25519 is more secure in practice because most instances of a break in any modern cryptosystem is a flaw in the implementation, ed25519 lowers the attack surface here.


I'm not sure I agree with that.

One thing to keep in mind is that SSH uses RSA only for signatures. That already kills off most attacks on RSA, as encryption has always been weaker than signatures. Not using a small exponent key kills the most significant attack on signatures.

Regarding sidechannels, the biggest issue I can think of is that ideally you should have constant time modular arithmetic, but you need that for ed25519 as well.

Not necessarily advocating for RSA (ed25519 is fine I guess), but I feel the "RSA is bad" talking point has been overused.


From when I last looked, my impression was that the specific modular arithmetic you need for ed25519 is basically standard long arithmetic with a constant number of digits + a single CMOV, which is different from essentially arbitrary moduli that (reasonably compatible) RSA needs.


I feel like the Dual_EC_DRBG backdoor has given Elliptic Curve Crypto a bad reputation lasting for decades. I guess it's unfair to the technology as a whole, but somehow RSA just feels safe and battle tested.


The tinyssh server only uses DJB cipher suites; the curve25519-sha256@libssh.org implementation has been in place for quite some time without any major issues.

https://www.libssh.org/2013/11/03/openssh-introduces-curve25...

"This algorithm does not rely on NIST-based curves and gives us more security confidence against a possible backdoor in nistp-256 curve. Today is a big day for us because OpenSSH team approved my patch and made curve25519-sha256@libssh.org the default key exchange!"

Also, the original RSA keys used in SSH have a sha-1 problem, and have been deprecated.

https://www.zdnet.com/article/openssh-to-deprecate-sha-1-log...

https://www.openssh.com/releasenotes.html

    This release disables RSA signatures using the SHA-1 hash algorithm
    by default. This change has been made as the SHA-1 hash algorithm is
    cryptographically broken, and it is possible to create chosen-prefix
    hash collisions for <USD$50K [1]

    For most users, this change should be invisible and there is
    no need to replace ssh-rsa keys. OpenSSH has supported RFC8332
    RSA/SHA-256/512 signatures since release 7.2 and existing ssh-rsa keys
    will automatically use the stronger algorithm where possible.

    Incompatibility is more likely when connecting to older SSH
    implementations that have not been upgraded or have not closely tracked
    improvements in the SSH protocol.


The concerns about the nist curves and the dual ec issue are two completely separate things.

Furthermore:

> Also, the original RSA keys used in SSH have a sha-1 problem, and have been deprecated.

This is wrong. What's correct is that openssh plans to deprecate sha1 signatures, but you can still use your RSA keys with sha2-based signatures.


Ironically I lately had a payment service provider handing me newly generated ecdsa ssh keys where ed25519 should be supported to the best of my knowledge. And fluxcd moved from rsa to ecdsa by https://github.com/fluxcd/flux2/releases/tag/v0.21.0.

Kinda strange people are moving on to EC cipher - which is good, but to the cipher which has the NIST/NSA smell.


I have upgraded all of my ECDSA host keys to the 521 curve, which has some praise from DJB, unlike the 256 and 384 curves (ssh-keygen -b #: "For ECDSA keys, the -b flag determines the key length by selecting from one of three elliptic curve sizes: 256, 384 or 521 bits").

http://blog.cr.yp.to/20140323-ecdsa.html

"To be fair I should mention that there's one standard NIST curve using a nice prime, namely 2^521 - 1; but the sheer size of this prime makes it much slower than NIST P-256."


ed25519 makes me feel like an idiot because I can never remember it. When I create new ssh keys I always forget:

1) (minor) The command to use a different encryption method to the default one 2) (major) how to remember more than the first two characters of ed25519

When I feel serious about not using RSA, I literally google "ssh ed" and pray it will autofill the rest of it. If I am not there within 15 seconds of opening my browser I am rolling with RSA256.


RSA2048, you mean? ;)


Haha! Oh wow, case and point - I am hopeless at anything that isn't the default


This is what makes Wireguard so powerful: there is only one setting.


Being tiny always means giving up some features. Supporting RSA really doesn't go along well with being tiny & straightforward.


It's their own project and their decision to make.

That said, have you read an RSA implementation? It's not a lot of code.


It's not a lot of code but it's significantly less straightforward than the primitives tinyssh offers.


Existing keys matter little. I always generate a new key for a new host anyway. Makes revocation much easier.


For a new server, sure.

I meant your personal identity key in ~/.ssh/id_*. The one that you might have on a bunch of servers, or give to github, or whatever. It's a good practice to periodically regenerate those, but I don't think it happens quite as often.


> The one that you might have on a bunch of servers, or give to github, or whatever

Exactly what I avoid. Each of them gets their own separate key. Never the same key to a bunch of machines (except maybe transient VMs).

But I agree, if a server changes its SSH implementation to one that does not support your existing key, it's a hassle, to say the least. In reasonable circumstances this does not happen without a plenty of warning well ahead of time, to allow you to regenerate your key in a new format.


Anyone fluent enough to read these type of posts and threads are very comfortable to moving to elliptic curve.


One past thread:

TinySSH is a small SSH server using NaCl, TweetNaCl - https://news.ycombinator.com/item?id=7727738 - May 2014 (61 comments)


How does it compare to Dropbear?


No CVEs, much smaller cipher set, password authentication is not allowed, only ed25519 user authentication is supported.


No CVEs yet. It would be truly exceptional should that record withstand widespread adoption.


Foregoing dynamic memory allocation, removing all non-DJB ciphers, and supporting only inetd drastically reduces the attack surface, so there is some hope that no CVEs will ever be found.


There may be some hope, but I would not bet on it. Indeed, I can imagine this very thread resulting in a miffed security researcher uttering "challenge accepted" and finding a way to break it. Again, that is not something I would bet against, given enough time and eyeballs.

That said, I greatly appreciate this kind of effort, and I will probably even look into using it for small embedded projects in the future. My pessimism about security track records does not block out my optimism that we can and should do better, and this sounds much better than some other alternatives.


It is also quite useful for older systems where the native SSH doesn't support newer features.

I have to support an Oracle 10g database on this platform, and I run tinyssh on port 26:

    $ ssh -p 26 myserver.com

    $ cat /etc/redhat-release /etc/oracle-release
    Red Hat Enterprise Linux Server release 5.11 (Tikanga)
    Oracle Linux Server release 5.11

    $ ps -e -o user,pid:5,args | grep tinyssh                                 
    root     14147 tinysshd -lpsv -x sftp=/usr/libexec/openssh/sftp-server /etc/tinyssh/sshkeydir

    $ size /usr/sbin/tinysshd
       text    data     bss     dec     hex filename
     122828    1428  680156  804412   c463c /usr/sbin/tinysshd

Unfortunately, I can't get it running on HP-UX 10.20, but I only have one of those left.


No password authentication? That's a problem to me. I use keys for everything serious, but sometimes I want to have a Raspberry Pi with the root password "derp". :^(


No, it does not allow passwords.

Also, logins on the root account cannot be disabled, although /etc/profile could also be used to shut that down.


No, it can't. When you specify a command, {/etc/,~/.}profile are not loaded. E.g. ssh root@host rm -rf /


They mention some ssh features that tinyssh does not have but it would be helpful to have a complete list. What I really would like to know is whether you can just drop it into an environment that uses a modern ssh configuration without the need for legacy versions.


So does this depend on systemd?

[Edit] I got downvoted, for some reason. It's a simple question - the article says it uses certain systemd components. I'm just asking if it can be used without systemd.


>no copyright restrictions - TinySSH is in the public domain

Are there any jurisdictions which doesn't recognize public domains?


Fortunately, the actual license on the project is CC0-1.0 to attempt to handle those jurisdictions.


It manages to be longer and more complicated than MIT.

I wish it was dual-licensed as MIT.



Is there an official docker image anywhere?


Awesome project!


Its a server so I would have called it tinysshd or something


Like the OpenSSHd project?[0]

[0]: https://www.openssh.com/


OpenSSH is both a client and server; "TinySSH is a minimalistic SSH server" (emphasis mine, but quote from their site)


OpenSSH is a project which ships (among other things) two popular binaries, ssh and sshd.

TinySSH is a project which ships an alternative to sshd which binary is named tinysshd.

I'm just pointing out that project names need not reflect the names of the binaries shipped by that project. Heck, the project named Apache made its name by shipping a binary called httpd.


And admittedly it would have qualified "this is only a server and doesn't come with a client" too. Ah well.


Except it's not actually a daemon, it runs as a child server process of inetd, tcpserver or (blech) systemd.


I'm looking for some kind of tiny ssh client I can squeeze into an Apple II. I'm pretty sure even dropbear is too big (I haven't actually tried yet, though so YMMV.)

Are there any other smaller SSH clients out there?


Wow an Apple ][ What OS / program environment do you have?


I've got both DOS 3.3 and ProDOS on 5 1/4 floppy. I can use ADTPro and I recently got (but haven't yet installed) an Uthernet ethernet card.


Take libssh and start swinging an axe?




Guidelines | FAQ | Lists | API | Security | Legal | Apply to YC | Contact

Search: