I took a look at split ssh and found an issue that can have OPSEC implications under a specific threat model.
In short: A compromised split-ssh client can leak the list of available public keys. Without customization it leaks a partial list of public keys to the servers per default.
Environment and threat model
You have multiple server. Every server has its own ssh keypair.
You want to hide the number and the actual keys (private and public) against your adversary, which is assumed to be able to compromise at least one server and traverse back to your ssh client.
You are working with split ssh.
Why one wants to hide this information
Mostly anonymity reasons. Your adversary might want to confirm, that the admin of server A also is the admin of server b.
Your adversary wants to enumerate all servers and therefore wants all public keys to check them against the servers ssh.
The problem
- When not using the
nickname
option in your SSH, your client offers all known public keys to the server upon connecting until the correct one gets send. You adversary only needs to compromise your server to get a partial list of ssh public keys. Additionally you may even have to allow for more failed attempts if your list of keys gets longer than 6 (or something).
Even worse, your adversary might be able to look at the size and timings of packets to determine how many keys where tried and therefore can determine what server you are connecting when, as the order of keys tried does not change often. -
ssh-agent
does not provide sufficient control over what public keys are offered to the ssh client. Lateral movement is expected to occur as soon as connecting so reducing password reentry time might not cut it.
Using a conf with nicknames
does need you to store connection details, nicknames and publickeys on the ssh-client so this is not a viable solution.
I tried for a few days to modify ssh-agent
behavior and talked to the devs on how to restrict offered public keys to the clients without finding a solution that works for me or does not need a reimplementation of ssh-agent.
What i learned was, that your ssh-agent cannot be restricted to only offer specific keypairs to your ssh-client. In fact it always offers every public key to every server, even when the ssh-client knows exactly what public key it needs.
What are the options?
Solution?
So i came up with one vault qube that holds all ssh-keys (in cleartext at this moment). When i want to ssh into machine_a i issue sshconnect machine_a
. A bash script creates a new disposable vm, copies the public and private key as well as the the config to the appropriate places in this machine, opens a terminal and starts the ssh session.
This is not a real split ssh, as the private key is on the ssh client itself, but it does completely fix the public key disclosure problem.
What do you think about this?
I am not sure if this is a good idea. I would prefer to create a disp-ssh-vault and disp-ssh-client and load that with the necessary information, but this is tricky as my initiating qube is not dom0 but an admin-vm. Getting policy tight is hard in this case.
Considering the security:
- Not encrypting the ssh-key was a deliberate choice without too much security implications as discussed in the split-ssh guide.
- having the public and secret key on the ssh-client qube seems fine, as the only attacking entity could be the server that already has the public key. Disclosing the secret key to it seems uncritical, as if the adversary has compromised the server, the knowledge of the secret key does not give him additional capabilities/information.
What are your thoughts?