On 2018-03-21 09:00, Damien Miller wrote: > you should check out https://github.com/StanfordSNR/guardian-agent Very nice trick. Requires a modified/bespoke client, of course, but it's definitely a very powerful approach. I'm going to have customized clients in some use cases anyway; I'll have to think about whether I can use this in some cases. > ATM it's hard because ssh only contacts the agent when it needs it and > drops the connection immediately when done. To "pin" an agent request > to a remote identity we'd either need to make the connections persistent > and add an extension to inform the agent of the remote identity OR > do this on every request. The latter is probably easier. > > I.e. have ssh inject a > > SSH_AGENTC_EXTENSION "remote-id@xxxxxxxxxxx" string("user@host") > > before each agent request (ssh would need to eat the reply too) and the > agent uses that to filter the keys it is prepared to send. Specifying > which hosts a given key is allowed for could be done with a key > constraint. That sounds reasonable. If the extension and identity list request are pipelined, it wouldn't introduce a latency penalty. > It also limits the modifications needed to ssh. At present, ssh doesn't > have any knowledge of what happens over the agent socket and, critically, > doesn't inspect or modify messages there. This design would have it do a > one-shot transaction whenever it opens the socket and then it can go back > to not caring what happens there afterwards. There are two independent ideas here: the ultimate ssh client asking the agent for which specific key it needs, and intermediate (forwarding) clients tagging the requests with what host they are being made on behalf of. I was mostly asking about the former; the latter would be useful too, but they're tangential. So right now we just have - SSH_AGENTC_REQUEST_IDENTITIES But the final ssh could do (1): - SSH_AGENTC_EXTENSION "remote-id@xxxxxxxxxxx" string("user@host") - SSH_AGENTC_REQUEST_IDENTITIES Or an intermediate forwarding ssh could insert a tag (2): - SSH_AGENTC_EXTENSION "forwarded-for@xxxxxxxxxxx" string("user2@host2") - SSH_AGENTC_REQUEST_IDENTITIES (which would of course nest with multiple chained forwards, similar to SMTP Received headers) Or we could have both at once (1+2) - SSH_AGENTC_EXTENSION "forwarded-for@xxxxxxxxxxx" string("user2@host2") - SSH_AGENTC_EXTENSION "remote-id@xxxxxxxxxxx" string("user@host") - SSH_AGENTC_REQUEST_IDENTITIES I was asking about case 1 (merely filtering a potentially huge list of identities to the appropriate one to log in to a given host), which does not require any changes to the forwarding at all, but case 2 has value too. Sidenote: I'd want more than a literal user@host string as the remote-id. Port at least, but also hostkey and an extra freeform option-specified tag (use case: things like GitHub, where the the key is all that tells different users apart). > The downside of this design is that it blurs the trust boundary for > ssh-agent; no longer would it be making decisions solely on its own - it > would be trusting ssh not to lie to it about the remote destination. In my design, the idea is to simply use a separate key for each user@host. Therefore, if something along the way lies, you just get the wrong key which won't work on the actual host you're trying to connect to. The agent would have its own policy and UI to ensure the user is informed of (and acknowledges) what identity is being used (and therefore what target is being connected to). This is why I expect to have potentially hundreds/thousands of keys - one for each user@host. > I had more grandiose plans to allow each sshd to sign agent requests > with the hostkey as they passed through, to allow some sort of chain of > trust. Unfortunately that would require fairly far reaching changes to > the SSH protocol to enable binding those signatures to the transport > instance over which they occur. This sounds interesting. If you bound a *usage* of a key with a given target user@host/hostkey (case 1 above), say by including constraints in the to-be-signed message that sshd enforces and the agent can inspect before signing it, it would allow use cases like having a single identity that many hosts trust, while the agent can still verify and apply policy on every individual use. This sounds "relatively" simple to implement, though it would still require changes to the core protocol to implement that idea of constraints (e.g. this signature is only valid for this host key/username combo). Binding the forwarding path cryptographically (2) sounds a lot more involved. I guess you can try to enforce that there is a "secure path" between the end-user/agent and the target host, but the actual transport isn't end-to-end anyway (in the usual ssh a ssh b scenario). If you're trying to have end-to-end security I think you'd just ProxyCommand your way through and then you don't have to care about agent forwarding or trusting intermediate servers, assuming you have your host key ahead of time. -- Hector Martin "marcan" (marcan@xxxxxxxxx) Public Key: https://mrcn.st/pub _______________________________________________ openssh-unix-dev mailing list openssh-unix-dev@xxxxxxxxxxx https://lists.mindrot.org/mailman/listinfo/openssh-unix-dev