vorta icon indicating copy to clipboard operation
vorta copied to clipboard

Add support to encrypted ssh keys

Open olfway opened this issue 4 years ago • 10 comments

Describe the bug Encrypted ssh keys not shown and can't be used without ssh-agent

I know it can be used with "auto" mode #167 but I think it's better to have encrypted key with a password stored in vorta then to keep ssh key loaded to ssh-agent available for all

To Reproduce Steps to reproduce the behavior:

  1. Generate encrypted ssh key
  2. Open "SSH Key" drop down

Environment (please complete the following information):

  • OS: Mac OS 10.15
  • Vorta version: 0.7.5

olfway avatar Mar 28 '21 17:03 olfway

What would “support for encrypted ssh keys” look like? Where would the password come from?

Note that you can already use any tool you like to unlock private keys and Vorta will use them when the key is set to Automatic/Default.

m3nu avatar Mar 28 '21 23:03 m3nu

I would say it should at least be possible to choose any encrypted SSH key (#167), so that when the first use is attempted, a PIN entry dialog for whatever keyring and/or agent caching mechanism pops up to request for a password. This is currently not the case.

Alexander-Shukaev avatar Apr 11 '21 02:04 Alexander-Shukaev

I don't really know how this would work. Wouldn't it re-implement ssh-agent? Where would it keep the SSH key password?

You can already unlock an encrypted SSH key yourself using whatever tools the OS provides and then choose Automatic in Vorta. Maybe the docs should explain this in more details.

m3nu avatar Apr 11 '21 07:04 m3nu

I see there were a number of similar requests in the past, where people couldn't really formulate any reasonable implementation and/or usability improvement without doing some draconian re-implementation of existing functionalities such as keyrings, keychains, agents, etc. I will try to break it down this time.

I don't really know how this would work. Wouldn't it re-implement ssh-agent?

Absolutely not. This would be rather irresponsible and mostly wasteful effort to do such re-implementations, and it's good that you rejected any such requests in the past.

You can already unlock an encrypted SSH key yourself using whatever tools the OS provides and then choose Automatic in Vorta. Maybe the docs should explain this in more details.

I am aware of that, though it's easy to make it not work and confuse one about what's actually happening. Let me provide an example here:

The server that I want to connect to and route backups to has 3 SSH keys associated with it (this is actually not so uncommon as you might think):

  • The first one is for interactive login to do administration work (say admin), it has all the privileges for that and can run a wide set of remote commands.
  • The second one is only restricted to run borg serve ... (let's call it borg).
  • The third one is only restricted to run borg serve --append-only ... (let's call it borg.append-only).

It's easy to imagine that most of the time one would have admin already cached in keyring/keychain/agent, which is reasonable since it's for interactive logins. By no means, I want that particular key to be used "automagically", without me explicitly giving sanction on that, to perform Borg-related operations on the server. This might result in security issues and/or unexpected backup results. In fact, I never even want that key to be chosen by Vorta.

So having that "default" behavior of letting SSH itself find the suitable key first through agent and then through ~/.ssh/config is fine, but that should not be the only way to specify a password-protected key. Having password-less SSH keys laying around is a severe security breach and I would refrain from promoting that or otherwise forcing people to go that route. Because, as a result, the only tech that could prevent compromising such password-less keys would be either partition encryption for home directory (e.g. luks) or built-in hardware disk encryption, etc. Not everyone is so sophisticated to take care of that and we should in general not rely on such questionable external factors, when we already have a direct way to protect keys from compromising. I guess we don't have to go deeper into any further reasoning on this topic.

Now also imagine, that you somehow already have all 3 keys cached in agent. Which one would it pick? We don't know from the top of our head, right? Also a problem. Both confusing and potentially disrupting security-wise as per above example.

So what's the deal you would ask, how to implement something useful here? Let's start with a simple example:

ssh -o IdentitiesOnly=yes -i ~/.ssh/borg.append-only ...

The above will do exactly, what you would expect it to do even from the usability standpoint. It will not look into agent, but will rather directly attempt to use the specified key. If that key is not yet unlocked, it will present whatever PIN entry dialog configured in the user's environment to unlock that key. If the user further specifies to cache that password now in whatever system-dependent keyring/keychain/agent is, it will do so, and next time will not prompt for the password. Note also that it's even legal to specify multiple keys to try with multiple -i and/or -o IdentityFile= options.

Apparently, there is one caveat with this. Even though SSH will no longer go to agent for keys, it will still also (in addition to the explicitly specified ~/.ssh/borg.append-only) try to use ~/.ssh/config, where one could have specified numerous additional options and ways to choose keys, which might or might not be useful here. E.g. I could potentially have had something like

Host ...
  Hostname ...
  IdentityFile ~/.ssh/admin

which is again both confusing and dangerous for our particular scenario here, where through Vorta GUI, I explicitly have requested the borg.append-only key. To prevent that from happening as well, add -F /dev/null to ssh invocation. In the GUI, this could be a checkbox, e.g. "Use SSH configuration (e.g. ~/.ssh/config)", which would be unchecked by default for the above reasoning and I doubt anyone would want it checked anyway when choosing/restricting a particular key to use.

You can literally test all of the above with naked SSH yourself and having 2 or 3 keys. I tried to test all of the above with Vorta (before you do any code changes) by using export BORG_RSH='ssh ...' and failed. It looks like Vorta is also doing some manipulations with keys by itself even before calling Borg/SSH. For example, I see the following in the log:

2021-04-11 12:47:51,238 - vorta.borg.borg_thread - DEBUG - Using VortaSecretStorageKeyring keyring to store passwords.
2021-04-11 12:47:51,248 - root - DEBUG - Found 0 passwords matching repo URL.
2021-04-11 12:47:51,251 - vorta.borg.borg_thread - DEBUG - Password not found in primary keyring. Falling back to VortaDBKeyring.

What does this mean exactly? How does Vorta actually interact with SSH, its keys and agents?

To conclude for now, as it currently stands, not having an ability to choose exactly one and only encrypted SSH key for a profile is a major blocker for me to use Vorta.

Alexander-Shukaev avatar Apr 11 '21 13:04 Alexander-Shukaev

Additionally, I noticed in #714 that you override BORG_RSH sometimes as per

env['BORG_RSH'] = ...

This might be the reason why I failed to test the above behavior with Vorta.

Alexander-Shukaev avatar Apr 11 '21 14:04 Alexander-Shukaev

What does this mean exactly? How does Vorta actually interact with SSH, its keys and agents?

These logs are about repository passphrases and arent related to SSH. Vorta only interacts with Borg, not SSH. And Borg also relies on SSH working underneath.

We could only consider adding encrypted keys to the dropdown and hoping they are already unlocked (or that the OS asks for the password). That may not be the case everywhere.

m3nu avatar Apr 11 '21 14:04 m3nu

We could only consider adding encrypted keys to the dropdown and hoping they are already unlocked (or that the OS asks for the password). That may not be the case everywhere.

Perfect, and not just that. You would have to modify BORG_RSH as in my examples above accordingly. Regarding asking for password, this should absolutely work for most users. Vorta is a GUI application, hence the PIN entry dialogs should be GUI ones and there is a plethora of those available and often set up by default on all modern desktop systems. Plus, there is always a way to override that with the SSH_ASKPASS environment variable. You could additionally provide VORTA_SSH_ASKPASS on top of that and you could also provide a way to configure it in GUI. Internally, you would of course invoke Borg with SSH_ASKPASS set to that value. And again, all that customizability would anyway be needed only on some exotic/broken systems and environments, while I'm sure that these changes would bring any related requests about SSH key management to an end.

Alexander-Shukaev avatar Apr 11 '21 15:04 Alexander-Shukaev

Apart from listing all the keys from ~/.ssh directory in the combo-box by default, I would also additionally provide a text field to enter a custom path to some key.

Alexander-Shukaev avatar Apr 11 '21 15:04 Alexander-Shukaev

Sounds all good. Can you add a pull request with the proposed changes? Maybe start with simpler changes first before adding more niche features, like a file selector for more SSH keys.

It will also need testing on macOS, Gnome and KDE at a minimum.

m3nu avatar Apr 11 '21 23:04 m3nu

The server that I want to connect to and route backups to has 3 SSH keys associated with it

QNAP much? :) I had this issue. Options are

  1. Create a new backup user on the target host (which accepts only a single key). This is a good idea anyway.
  2. Add a local ~/.ssh/config entry with a unique name forcing the key to be used
Host lan-backup-target
    hostname your-host-name
    user backup
    IdentityFile ~/.ssh/id_backup
    Compression no

drekbour avatar Aug 17 '21 00:08 drekbour