Forwarding access to only a subset of ssh-agent's identities

January 7, 2015

Suppose, not entirely hypothetically, that you have three machines: a laptop or desktop, some general access login servers that you do most of your sysadmin work from, and some fileservers that the login server mounts all sorts of things from. It's convenient to have passwordless ssh access from the login server where I work to the fileservers so that I can do things like conveniently run a command on several of them at once, but at the same time there are some security and convenience issues.

If I use an unencrypted key for the login server to fileserver ssh session, well, it's passwordless access but the key is sitting there on disk for anyone to use. Compromise my account on the login server and you get bonus fileserver access, which is not ideal. If I use an encrypted key on the login server, I have to start and manage a ssh-agent session on the login server every time I log in to it (including ideally purging the key if I lock the screen on my desktop to walk away for a while), and an attacker on the login server has a chance to capture the unencrypted version of the key. What I really want is for my desktop to securely hold the actual key (and include it in all of my existing desktop key management stuff) but let the login server use it to authenticate me to the fileserver.

Of course SSH sort of has a way to do this in the form of ssh-agent, since the entire purpose of ssh-agent is to hold your keys and do authentication with them so that other things can't get at them. The problem is that allowing the login server full access to my desktop's ssh-agent is too much power, as that lets it use all of my keys instead of just the fileserver access key. What would be ideal is if ssh itself could limit what keys are accessible when you had it do agent forwarding; unfortunately, as far as I know no version of ssh has such a feature. Right now the only native way you have to limit what keys are available through ssh agent forwarding is to limit what keys the ssh-agent being forwarded has access to, which can get inconvenient fast (as it multiplies the number of ssh-agents that you must start, manage, purge keys from, and so on).

If ssh won't do the filtering itself, the next best solution is a filtering ssh-agent proxy. Fortunately just such a thing exists in the form of Timo Weingärtner's ssh-agent-filter. While this works, it turns out there is an important limitation in using a filtering proxy that can complicate your life. The problem is that ssh with agent forwarding is actually using your ssh-agent for two different things: first for authenticating to the login server, and then for the agent forwarding to the login server that the login server will use for further authentication attempts to elsewhere (eg to a fileserver). If you give ssh a filtered view with only the fileserver key, the fileserver key has to work for both purposes. If you want the fileserver key to just be for fileserver access, you need a second key that is only for login server access. And remember that the login server will have access to this key through the agent forwarding.

(ssh-agent-filter has a mode where you can be asked to approve each use of a key, so you could at least set the login server key to this mode and then generally refuse after the first use. Hacks are possible here.)

PS: I've only just discovered ssh-agent-filter and experimented with it a little bit, so there may be other surprises lurking in the underbrush. I did get a test setup working, although I accumulated some notes in the process that I am going to scribble down in another entry when I have more experience with it.

PPS: In our specific configuration allowing the fileserver access key to also log me in to our login servers is probably okay because in practice trust basically flows outwards from the fileservers since, well, they have all the filesystems that the login servers NFS mount. This is definitely not going to be the case in all situations.


Comments on this page:

By dozzie at 2015-01-07 19:25:52:

There is one more way to separate those. You don't use ssh-agent (well, it's not explicitly necessary for this), you use nc running on a jump host to setup a TCP connection to target machine:

host foo
  hostname foo.example.com
  proxycommand ssh jumphost nc %h %p
host jumphost
  hostname jumphost.example.com

ProxyCommand causes ssh to talk to STDIN/STDOUT of the specified command instead of using TCP connection. In this case both SSH clients are running on your local machine, so your private keys are only stored there. Intermediate jumphost knows nothing about them, so it can't use them to authenticate.

This setup has one more thing: it allows to use scp or sftp from local machine to foo directly.

Of course all this causes encryption to be applied twice, but for administrative purposes this shouldn't matter.

By cks at 2015-01-07 20:35:56:

Whoops, my bad, I wasn't clear enough about the scenario. In this scenario my sysadmin desktop already has direct access to the fileservers; I don't have to indirect through our login servers. I just want a way to (securely) do passwordless access from a login server xterm to fileservers, instead of having to pause what I'm doing on the login server in order to open up a desktop xterm and so on.

(Most of my actual sysadmin work is done on the login servers instead of my desktop, because the login servers are where our NFS filesystems are mounted and so on. My desktop is deliberately independent of the rest of our infrastructure, which is handy when said infrastructure is having problems but can be inconvenient at other times.)

Written on 07 January 2015.
« Choices filesystems make about checksums
ZFS should be your choice today if you need an advanced filesystem on Unix »

Page tools: View Source, View Normal.
Search:
Login: Password:

Last modified: Wed Jan 7 00:50:42 2015
This dinky wiki is brought to you by the Insane Hackers Guild, Python sub-branch.