recommended approach for loading private keys requiring passwords

287 views
Skip to first unread message

Rory Campbell-Lange

unread,
Apr 26, 2020, 1:34:21 PM4/26/20
to golang-nuts
I've been working on a small service for inserting ssh certificates into ssh forwarded agents. See https://github.com/rorycl/sshagentca

The idea is that if you have an ssh forwarded agent with a certificate signed through the service, you can connect to any ssh server which has the
TrustedUserCAKeys ssh setting set to the public part of the caprivatekey keypair (other permissions such as principals permitting).

The server takes the following arguments:

sshagentca -pvt <privatekey> -ca <caprivatekey> -a <authorized_keys>
           [-i <ipaddress>] [-p <port>] settings.yaml

The privatekey is an ssh server private key, and the caprivatekey is the ssh server's Certificate Authority private key. On startup the user is prompted for the passwords for each of these keys.

Is there a more secure way of doing this? Is using something like memguard (https://github.com/awnumar/memguard) recommended to protect the passwords in memory?

Based on Thaler and Sunstein's principle of "the nudge" I also wonder if it would be a good idea to have the caprivatekey passed in by stdin, to encourage users not to store the caprivatekey with the programme. (Passwordless private keys are not permitted.)

Thanks for any comments
Rory

Jason E. Aten

unread,
May 1, 2020, 11:09:28 PM5/1/20
to golang-nuts
So as not to omit the obvious... you could overwrite the password with "***********" when you are done loading the key.

Brian Candler

unread,
May 2, 2020, 3:58:41 AM5/2/20
to golang-nuts
I'm not sure how far you can usefully protect against an adversary with access to /proc/<pid>/mem.

You could punt on the problem entirely, and use ssh-agent.  That could also allow users to take advantage of HSM integration, and absolves you from the UI for prompting for passphrases.  Any adversary with access to the agent socket can still sign things of course.

It might be worth looking at ssh-agent source code to see what precautions (if any) it takes with keys in memory - also any other well-known programs that deal with an unlocked private key in RAM, e.g. apache2 mod_ssl.

Aside: I don't agree with enforcing policy on administrators (i.e. "private keys must not be passwordless").  Firstly, you don't know the execution environment or trust model / threat model of all users.  If you accept a private key on stdin then you have no way of knowing how well it was protected - it could have come from a gpg pipeline for example.  Even when reading a key from disk, the key could be read from an encrypted filesystem, and the entire execution environment could be super-secure and isolated.

Perhaps more importantly, people who have a legitimate need for passwordless keys are just going to use a dumb passphrase like "abcd1234", so all you're doing is making them wrap your application in 'expect' scripts, while cursing under their breath.

Brian Candler

unread,
May 2, 2020, 4:51:09 PM5/2/20
to golang-nuts
The more I think about it, the more I like the self-referential nature of sshagentca talking to ssh-agent to sign certificates to distribute to another ssh-agent :-)

The main security weakness I can see is that ssh-agent will sign any data you give it - hence anyone who gets direct access to the socket could sign themselves a certificate with infinite lifetime.  ssh-agent can run another process as a direct child, but I think they still communicate via a unix domain socket.

BTW, I think sshagentca is a fantastic little project.  One of the things I've just tested is using a U2F token (ecdsa-sk), as introduced in OpenSSH 8.2.  It works perfectly with sshagentca, which then issues me with a regular key and certificate (ECDSA-CERT 384).  This type of key and certificate works with older versions of sshd, meaning you can use sshagentca to bootstrap your security from U2F keys without having to upgrade sshd on all your hosts. Very neat indeed.

Marcin Romaszewicz

unread,
May 2, 2020, 11:59:22 PM5/2/20
to Brian Candler, golang-nuts
Haha, great minds think alike, as they say. One of my colleagues (from a cloud security company) wrote basically the same thing in Go:

There's also a really fantastic product that works via signed SSH certs called Teleport, from Gravitational, also written in Go. The basic version is open source, but the really useful version with things like SAML federation, is a paid product.

--
You received this message because you are subscribed to the Google Groups "golang-nuts" group.
To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/golang-nuts/6fc082c1-318f-4037-8d5b-aa9710e5eb23%40googlegroups.com.

Brian Candler

unread,
May 3, 2020, 3:38:50 AM5/3/20
to golang-nuts
Yes indeed there are quite a few projects in this arena, and interestingly most of them are written in Go.  I was aware of:

https://github.com/smallstep/certificates [go, also available as a pay-for cloud service]
https://github.com/netflix/bless [python, runs in AWS lambda]

to which you've just added:
https://github.com/gravitational/teleport  [go, commercial version required for SSO]

I need to check them all again, but apart from sshagentca, the others didn't appear to let me define for each user which principals should be in their certificate (#1 requirement for me).  sshagentca also has the interesting property of not requiring any client, other than ssh itself.  However I think I'm straying OT for golang-nuts now.
Reply all
Reply to author
Forward
0 new messages