New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal for hardening agent forwarding #233
base: master
Are you sure you want to change the base?
Conversation
|
You might be interested in djmdjm/openssh-wip#5 that does something similar, but doesn't require ssh's active inspection of agent requests. I wanted to avoid this because it would make ssh a trusted part of agent forwarding, and in the multi-hop case that's not really dependable. |
OK, if there is a different approach in the works that is fine. Like I said, I originally wrote the agentfilter.c bits for my local use; I just cleaned it up a bit and added some manpage bits to make a PR out of it. If there are pieces that are interesting to you feel free to grab them, otherwise feel free to drop it entirely. I'll try to walk through your WIP, although there is a lot there. Am I correct in understanding that it needs all of the following modified:
That obviously makes it a bit more complicated to use in the short-term. Also, is there some way to put a destination-constraint on the other
Well, somewhat. Since it's just blocking functionality that the unmodified My first thought was going to make a minor protocol change where
I guess I'll have to look at your proposal some more. I agree that by only doing protocol-level filtering we can't bind a key as |
|
Hallo Mitchell Blank Jr,
12.03.21 08:00 Mitchell Blank Jr:
## Prior Art
* There is the `ssh-agent-filter` project from Timo Weingärtner ***@***.***)
which is available in Debian: https://git.tiwe.de/ssh-agent-filter.git
This requires wrapping the `ssh` program itself with something that can set
`$SSH_AUTH_SOCK`
`afssh` is that wrapper and it is included in the `ssh-agent-filter` package.
My most-often-used invocation is:
`afssh -i id_example -- -t jumphost.example.org apt-dater`
* Late in 2019, `ForwardAgent` was extended to allow specifying an alternate
socket path (40be78f) This opens up the
possibility of running multiple segregated `ssh-agent` binaries.
That looks cool. I guess I could change `afssh` to check for a recent-enough
version of ssh and then supply `-o ForwardAgent=$NEW_SOCKET -o
IdentityAgent=$ORIGINAL_SOCKET` to allow using all the keys for the initial
connection.
However, this is awkward at best -- doubly so if you want to continue to use
something like OS/X's modified `ssh-agent` as your root identity store.
It's the same with GNU/Linux's equivalent of OS/X: GNOME. There is a slow but
constant flow of bug reports regarding `ssh-add` actually complaining about
problems in `gnome-keyring`…
Grüße
Timo
|
This adds four options for hardening of ssh-agent forwarding: * ForwardAgentFilter If enabled, the ssh client will act as a stateful proxy for ssh-agent rather than just providing untouched two-way traffic to the UNIX domain socket. * ForwardAgentFilterIdentitiesByComment A standard pattern-list that matches against the _comment_ attached to each identity's key. Only matching identities will be returned to the remote agent user. * ForwardAgentFilterPermitIdentityManagement Normally the filter does not allow the remote side to add/remove keys. This can be explicitly allowed by setting this. * ForwardAgentFilterPermitLocking Similarly normally agent lock/unlock requests are blocked while filtering as well. This can enable those. By default behavior is unchanged (i.e. "ForwardAgentFilter no"). However if *any* of the last three settings is given a non-default value ForwardAgentFilter will default to enabled. This means you can limit the identities passed by the agent with a single option: $ ssh -A -o 'ForwardAgentFilterIdentitiesByComment *@github.com' build-host.example.com
ad8bd15
to
25f53ff
Compare
Mailing list message: https://lists.mindrot.org/pipermail/openssh-unix-dev/2021-March/039209.html
This is an attempt to add some features to improve the security of
ssh-agentforwarding. I know that this feature is long-maligned, but it is still useful and it's a shame that it's so difficult to harden.My use case in brief:
gitserver, another to manage a remote server viaansible, etc.ssh-agenton my local machine.As anyone familiar with how agent-forwarding works will know, there is a serious weakness here: since the forwarded
ssh-agentsocket is treated the same as the local socket, it has access to all of the same functionality. In particular, if the remote machine were compromised (even just as my local user) then for as long as the session lasts the attacker could sign authentication requests with any of my identities, not just the one I used to connect to the compromised host. So I wanted to temporarily grant the remote host with the ability to make password-less connections to agitrepo, but now they also can do everything myansiblekey can!These are some openssh changes I just coded up trying to address this problem for my own use. However, I think that my needs aren't particularly unique so I thought I'd clean up it up a bit and see some of it would be interesting to the upstream.
Prior Art
ssh-agent-filterproject from Timo Weingärtner (@tiwe-de) which is available in Debian: https://git.tiwe.de/ssh-agent-filter.git This requires wrapping thesshprogram itself with something that can set$SSH_AUTH_SOCKssh-identpython script which can automate the running of segregatedssh-agentprocesses. Again, requires wrapping thesshprogram.ForwardAgentwas extended to allow specifying an alternate socket path (40be78f) This opens up the possibility of running multiple segregatedssh-agentbinaries. However, this is awkward at best -- doubly so if you want to continue to use something like OS/X's modifiedssh-agentas your root identity store.ssh-agentlistens on two UNIX sockets for forwarding --$SSH_AUTH_SOCK_LOCALthat knows aboout all identities while the original$SSH_AUTH_SOCKcould be more limited and safer to forward. (see https://marc.info/?l=openssh-unix-dev&m=160181549101461) I see a couple disadvantages to this method:ssh-agentchanges so, again, it can't be immediately used with an existing vendor-suppliedssh-agentbinaryssh -Ainto a host and have multiple identities visible via that forwarded agent there isn't a way for that host to filter the identities beforessh -Ato another hop.This patch
I was originally looking into using the
ssh-agent-filtertool mentioned above, but I wondered how difficult it would be to integrate that functionality more cleanly with thesshbinary itself. It turns out that it's not too bad:channel_register_filter()which allows the programmer to plug into a channel's data stream and do (some) modifications. As I describe in the agentfilter.c comments, the API doesn't make this particularly easy for our use case but it can be done without too much pain.ssh-agentchanges.Theory of operation
When
sshhas an agent socket available it takes a few steps:SSH2_AGENTC_REQUEST_IDENTITIES)ssh-agenta reply with zero or more identities that it knows how to use (SSH2_AGENT_IDENTITIES_ANSWER)sshclient then can try those in turn by askingssh-agentto sign an auth request using a particular identity's key (SSH2_AGENTC_SIGN_REQUEST)This code (like
ssh-agent-filter) inserts itself in the middle of this conversation and does two things:ssh-agentprovides itsSSH2_AGENT_IDENTITIES_ANSWERreply, we intercept it and optionally filter out some identities. In other words, if you runssh-key -Lon the remote host you may only see a subset of the identities you'd get if you ran that command locally.SSH2_AGENTC_SIGN_REQUESTrequest we verify that the key used is one that we'd returned in theSSH2_AGENT_IDENTITIES_ANSWERresponse earlier. In other words, if they try to issue a signing request using a key we didn't tell them about, the request is blocked.In addition,
ssh-agenthas other options for adding and removing keys, and for locking and unlocking the agent (ssh-add -x/ssh-add -X) I suspect that there is little use for allowing this functionality across the forwarded agent connection. Therefore, when agentfilter.c is enabled these types of requests are blocked by default. However, I did add configuration settings so they can be explicitly enabled if need be.The likely-controversial bits
As described above, we decide on which keys that we'll allow
SSH2_AGENTC_SIGN_REQUESTto use purely by watching which ones get returned bySSH2_AGENT_IDENTITIES_ANSWER(after we apply our filtering, of course) This is done on a per-channel basis. This means that we are assuming thatsshwill always make theSSH2_AGENTC_SIGN_REQUESTon the sameauthfdconnection that it used to make an earlierSSH2_AGENTC_REQUEST_IDENTITIES. If it were to use two seperate connections to the UNIX domain socket, it would fail. Also if it were to separately cache the ssh key ID and useSSH2_AGENTC_SIGN_REQUESTdirectly it would also fail. Neither of these seem to be a problem for the openssh CLI client, but it's possible that there exist otherssh-agentclients that would have an issue.The identity data that
ssh-agentholds (and is visible viassh-add -L) consists of just two things: the key itself and the comment that the key was generated with. In order to decide which identities to let pass there is the newForwardAgentFilterIdentitiesByCommentdirective. This may cause some offense since key comments are traditionally just that: purely human-readable comments.Normally when we ask the user to specify a key we do so by filename, but the
ssh-agentprotocol doesn't give us that information. We also can't always look at the files ourselves to get their signatures -- for instance in the multi-hop agent forwarding cases discussed above the machine runningsshmight not even have the keys local.On the other hand, the "normal" way that people put comments in keys is likely to be amenable to their use as filters. For one thing, they're what you see with
ssh-add -Lwhen you look at what keys are available. When generating a key for use with a particular external organization it's likely that a comment was attached, so you can simply do things like.or:
(also if the key doesn't have a useful comment that can always be fixed via
ssh-keygen -C)Note that @tiwe-de's
ssh-agent-filtertool also supports specifying specific keys via their signature. I personally don't think that's likely to be useful to most people and it's a bit complicated to add. However it could be added later if really needed.