-
Notifications
You must be signed in to change notification settings - Fork 773
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
ssh-agent: permanent loaded ssh-key storage #1487
Comments
ssh-agent stores the key in registry.. It is fully encrypted, only the current user can access it.. If you login to the same machine as a different user, you wouldn't be able to see the keys of others. |
Agreed, but other users also can't access my SSH key files if they are in my home folder, that's not the point. My point is that by storing the key in registry without the passphrase-encryption, a level of security is taken away. Anyone that can gain access to my account (malicious intruder or virus for example) now immediately has access to my unencrypted keys, without needing to know my passphrase. This completely voids the use of passphrase-protection on SSH keys, and I'm sure many users (including myself) want that extra layer of security back. |
Not really. The registry is only accessible for SYSTEM, ADMINISTRATORS. |
fyi, User keys are stored in Computer\HKEY_CURRENT_USER\Software\OpenSSH\Agent\Keys. |
Not a security expert, but this makes sense to me as well. If someone gets access to my account, they can ssh into any server I have access to since the passphrase is not required. The security of the key storage is important but not the main question. It's more about the user flow of requiring a separate password to use the key. Also, this seems to be the behavior of ssh-agent on other systems. |
@xdhmoore I totally agree. (Open)SSH agents on other systems only temporarily store the key in memory, not permanently anywhere else (registry here). A config option for the windows openSSH agent to disable this permanent registry copy would fix this. |
Different angle: I was looking for a reason why an outdated and invalid key kept showing up in |
In my opinion this is a bad choice. 2.) There is a degree of freedom and security taken away. If I chose different pass phrases for different keys, then I do have a reason and don't want my OS to decide that protecting it with my account's password is good enough until I remove the key explicitly. If the PC ever gets stolen only one password has to be cracked and all keys are compromised 3.) As far as I know (without any explicit configuration) ssh has will try out all private keys while logging into a server. if I work for several days (add one key, logout, add another key, logout, ...) Only drawback is, that most servers will abort after a few wrong keys have been presented. |
It's hugely non-obvious that ssh-agent would behave this way. Everyone familiar with the OpenSSH tools is expecting the traditional ephemeral state of keys in ssh-agent. I can see how some people would want this behavior, but the default behavior here should be exactly the same as standard OpenSSH on every other OS. This should be an opt-in behavior that the user must explicitly request. |
Has anyone found a way to disable this behaviour ? |
@NicoAdrian I countered this behavior by defining a task through the Windows task scheduler that triggers on every shutdown or reboot and which executes a powershell script that simply executes |
For what it's worth, the workaround I've landed on has been turning off the key agent and typing my all key passwords. :S |
This is by design, if you would like to not have the keys registered, then you can create a cron job/scheduled task to clear them |
Did some experimenting with an alternative today. I've had a little bit of luck using wsl-ssh-pageant as a bridge from pageant to Win32-OpenSSH. The basics seem to work so far, but pageant doesn't seem to have much of a CLI interface to work with, unfortunately, so I'm not sure how adding/removing the keys will work, exactly. Maybe there's a way to kill pageant when the terminal exits to dump the keys (I don't see another way to remove them). I like how the AddKeysToAgent ssh config option works on Mac, so maybe one could add an ssh wrapper that adds the the key every time to pageant right before calling ssh. Adding a key seems to be idempotent or whatever--and it only prompts for your passphrase the first time, so I think that would probably work. Of course, that is smoothest if you only have one key... |
@maertendMSFT I'm aware that this behavior is by design, but is is counterintuitive and unlike any other openSSH implementations most developers are familiar with (through other systems). Therefor I'm requesting to disable this behavior or at least provide an option to do so without involving some hacky cron/scheduler job (like indicated in one of my previous posts), to make Win32-OpenSSH act like any other (more secure) standard OpenSSH implementation. |
I agree that at least an option to turn off saving the key in the registry would be nice. Another alternative that seems to work as an agent for Win32-OpenSSH is KeeAgent with wsl-ssh-pageant. |
Discovering that Windows apparently stores my private key in unlocked form was a rather unpleasant surprise. This is NOT what I expect from ssh-agent. Like most people, I use ssh-agent explicitly to have my key in volatile memory so it will disappear automatically on logout, etc. I strongly disagree with those who want an option to turn the current behaviour off (implying that it should be on by default). Following both the principle of least surprise and the principle of making default behaviour secure, it should actually be off by default. |
"Working as designed" is no defence against a design that incorporates a security vulnerability. The purpose of the passphrase is to provide protection if the key is leaked, which in practice, often means the system on which the key is stored getting compromised. The passphrase means that the key is protected even if the user's account is compromised, so an attacker can't follow a breadcrumb trail of SSH keys to penetrate further and further into a network. That protection is removed by storing the passphrase. It's irrelevant that the registry is encrypted, when it's decryptable with the very same malicious access we're trying to mitigate against. Worse, the protection offered by the passphrase has been taken away without the user's consent and contrary to their expectations. Any time that a user is led to believe that they benefit from a security protection when they do not, you have a security vulnerability. @maertendMSFT, please can you reopen this issue? |
I'm also going to add my voice to this issue. I started using ssh-agent with VSCode a few days ago, and finding out that my keys are stored unencrypted in the registry is a blocker and I'm going to have to avoid using it for that reason. I can't justify putting keys which connect to our prod infra into something that's permanently keeping them around like this. this needs to be off by default. |
@ahicks92 , The keys stored in the registry are DPAPI encrypted. only the current log in user can access them. |
I still end up with implicitly unencrypted keys that just build up forever every time my laptop is logged in unless I go out of my way to delete them. For example, just deleting the file and restarting--which works on every other platform--isn't good enough, yeah? But even so, this does mean that if my laptop is ever in a shared environment even if I haven't used ssh this boot, my keys are available if anyone gains access while it's signed in. I'm not really sure why this isn't considered a problem. Deletion cron jobs etc. are fail dangerous, not fail safe. Those of us who want them only in memory want them only in memory with reasons, I understand the "the registry is protected" argument, but it's still not good enough for my case. Am I missing something? |
Here I was about to promote the ideal win10 dev setup. Docker inside WSL2, not working off mounted files, and using Windows ssh-agent. I can see now from the discussion here that the 2nd part was a bad idea. |
Since this issue was closed because, apparently, this is how it was designed, the obvious question arises how to address the underlying design issue. Alternatively, it might be a good idea changing the name to something that does not suggest functional equivalence with OpenSSH's ssh-agent so future users may avoid this trap. @maertendMSFT could you please share your thoughts on the proper way forward? |
We are reopening the issue. We are planning to enhance the ssh-agent to align with the Linux implementation and at the same time maintain the backward compatibility with previous win32-openssh ssh-agent releases. We will allow the ssh-agent to run interactively from a terminal. If ssh-agent runs interactively then the behavior will be inline with the Linux implementation. The registered ssh keys will not be persisted. When ssh-agent started as service, the existing behavior will continue. This is to maintain the backward compatibility. Please note, ssh-agent service is disabled by default. If user starts the ssh-agent as service then the ssh keys will be DPAPI encrypted and stored in the registry. Only the owner can retrieve the keys and no other user (including administrator) can retrieve the DPAPI encrypted keys. |
@immersivegamer For what it's worth, I'd also really like Windows ssh-agent to improve as so many suggested, however in the meantime you can get a more convenient and secure workflow with KeePass + KeeAgent, in current releases of KeeAgent you can turn on WindowsOpenSSH support in the settings and for me it works quite well so far. You can even configure to be prompted with a confirmation dialog each time an application wants to use a key: |
Unfortunately neither does I used OpenSSH ssh-agent for some time and added that workaround to somehow restore normal and expected operation. So I set up scheduled task to remove keys on boot, because in Windows you cannot so easily put on shutdown scheduled jobs. But since the key usage verification or confirmation is required at workplace I set up pageant with proper patch and ssh-wsl-bridge. For compatibility reasons I had to disable the service, so Scheduled job just fails silently every bootup. Now I had to come back to ssh-agent and tinker a bit with YubiKey because Pageant does not support -sk keys and to my surprise nothing except -sk keys support has changed and still after reboot I am able to log in without any key usage confirmation or any key passphrase or anything alike to work production servers. Heck even starting the service and I was surprised that the keys that I last added year ago were loaded in, while the keys real passphrase had been changed long time ago. Like many others have expressed, then if MS sees that storing them in Vault or registry using DPAPI is better than storing them encrypted in memory, then great, that is just improvement, but the concerns here raised are more towards key lifecycle. I guess the problems with lifecycle comes from how MS has decided to store the keys, that there isn't any real way to clean it up automatically and adding some process to clean it up from registry when machine boots up seemed to be too much hassle. Traditional OpenSSH implementation cleans up as soon as process dies, may it be due to reboot or it being killed, just because they are stored in process memory and it is not there after reboot and is cleaned up by garbage collector when process dies. So that is where storage implementation affects the key lifecycle and on Windows there has to be extra steps done to ensure same or similar operation.
That sounds like "works for me" argumentation. If you look by thumbs ups and thumbs down reactions or comment and main concerns then if one person is happy with how things work on Microsoft, then it might not be how majority of people expect it to work from experience with the BSD, Mac, Unix, Linux etc. implementation of OpenSSH. MS version is the odd one doing things drastically different here to even call it OpenSSH port. It might have been called WinSSH as well. At least then there would have been excuse to do things different. Usecases in practice are different, MS deviation makes it unusable in my usecase, while the more traditional implementation gives enough options to make it work for me. MS version caters only specific ones, while OpenSSH catered most of them (might have been some edge cases where it was not possible to use) Just for it not to have only criticizing, then from my side possible way how things could be changed, some inspired (stolen) from other comments, some not: In addition we have to rely on DPAPI to ensure the safety of the keys while adding another possible point of failure. |
Well, I'll do like everybody here and add my own story. This is how I even discovered this issue: On my first try to setup SSH on Windows, everything was working as expected. A breeze. I discovered there was an ssh-agent, behaving just like everywhere else. Good! I even saw there was a service for it, so there is even no need to start it every times. Absolutely awesome! They implemented the thing like it should! Had I even knew this was happening, I would have organized myself differently. So from my POV, the "it works differently because Windows" and "When ssh-agent started as service, the existing behavior will continue" is a real problem. You have to make sure somehow the users know it's not behaving the same way as everywhere else. Having a different name would have been a clue... |
alaincao wrote on 2022-07-08 12:53:
...
Anyway, permanently storing the key should be an explicit option, not
the default behaviour.
MSFT has a strategy they call "embrace and extend" when it comes to open
standards or in this case open software. respect for how stuff works
elsewhere won't help them create a bespoke and competitive ecosystem.
once i understood that MSFT's ssh-agent was default=dangerous and that
they had no incentive to change this, i moved my ssh use into VM's. this
is probably for the best, since those VM's can be moved to other
platforms if Windows becomes more embracy-and-extendy generally. YMMV.
…--
P Vixie
|
While waiting for this update, I created a scheduled task that clears the keys on boot.
I hope this can help others 🙂 |
On Tue Jan 17, 2023 at 11:07 AM UTC, Alexandre ABRIOUX wrote:
While waiting for this update, I managed to create a scheduled task. I'm sharing here the parameters I've used:
...
3. For the trigger, use "At log on" with your user account
...
- arguments: `/C "ssh-add -D"`
I hope this helps 🙂
thanks. if i'm reading this right, it will clear the auth cache at login
time. this leaves privileged secret information in the auth cache from
the time of the last ssh-add to the next login, which could be overnight
or as long as a vacation. if there's a way to trigger this at logout time
rather than login time, and if logout can be triggered on a timeout if
no user input occurs for some idle threshold period, it would be a good
workaround.
for now i have deinstalled microsoft ssh, and am using msys2 tools. this
had the side effect of getting a terminal application ("mintty") with
working IRM. my UNIX side editors appreciate this.
|
For anyone interested, I've created a fork which the PKCS11 is untested |
The latest version pageant is able to start with a --openssh-config option which will generate a named pipe usable by OpenSSH. Details on how to enable are available here: https://the.earth.li/%7Esgtatham/putty/0.78/htmldoc/Chapter9.html#pageant-cmdline-openssh |
I discovered this issue within my company when we started moving from PuTTY to Microsoft's built-in OpenSSH implementation for our secure connections. We require that the SSH connections to have a separate passphrase so that if someone were to illicitly gain admin access to the PC, they still won't have access to the engineering network. I was hoping to work around this with the usual "-t" option, but apparently that is still not supported per issue #1056 from Feb 2018. Putty Pageant drops the keys on logout. Linux ssh-agent drops the keys on logout. I don't think those design decisions were random, so permanently unlocking the keys is a perplexing "by design" decision that is counter to other implementations. We've implemented the "ssh-add -D" logout script in the group policy as a work-around, but that doesn't resolve a hard power-off situation. We look forward to seeing ssh-agent using a more common and secure implementation in the near future. |
You can give a try of my fork if you want. |
Thanks for the offer, but that won't be permitted on the corporate network. It needs to come from Microsoft or an approved 3rd-party software solution. |
i'm using MSYS2 now which has a normal openssh and ssh-agent, plus a terminal application called UCRT64 that's very complete. added tmux and i'm in happy land. note that i'd prefer to use microsoft's ssh but with their insistence on keeping my unlocked key in persistent (across logout or reboot) storage is so completely wrong that i can't imagine letting it possess my keying material in any form. |
Personally since then I fully switched to working from within WSL and using ssh-agent within it. Event went as far as building a packaging system to build WSL images pre-setup with ssh-agent and gpg-agent. Very Linux focused, so no integration with Windows at all. But it does work nicely with VSCode and devcontainers! :) References: info on wsl.geekstuff.dev, example for ubuntu 22.04 with systemd |
This issue is opened for years now. Is there an official fix now? Also, I just wanted to share my opinion, from a newbie perspective. I am absolutely not expericenced as you all and cannot judge the technical aspects of the decisions made in Windows' OpenSSH. However, I think that the way the process is designed actually breaks the User Experience. Like many users there, I was, at first usintg Putty, or even OpenSSH on Linux (or more formerly, Git for WIndows' agent), and I was expecting the same behaviors when switching to the Windows version. This means that, since more than a year, I am unnecessarily re-loading my keys through One day I tried to SSH to my remote, and I instantly realized I forgot to first Well, this was really confusing. |
so, i can't speak for microsoft, but i think ssh has been embraced and extended, in order to differentiate windows from other ssh-capable platforms. my prediction is they'll document what the behaviour is and that it is intentional, will not change their ssh client to make this optional or add a knob to turn it off, and that this ticket will remain open until long after we are all drinking mead together in valhalla. i hope i'm wrong about any part of that. |
Well, I was rather hoping Microsoft had abandoned the old technique of "embrace, then conflict" like they did with IE6 web standards, or the XML document standard, or... Anyhow, our solution was to apply a "ssh-add -D" to the logout process. It's not perfect, but it gets us close enough for now. |
it seems that this is now quite off topic, but MS has only slight control over the SSH protocol if any at all. Just because a specific implementation is different doesn't mean they're trying to take it over, and indeed they probably can't even if they wanted to. Not having this issue resolved is annoying, but I don't think it's fair to attack people over what is almost certainly just a priority decision. |
Austin Hicks wrote on 2023-08-18 08:45:
it seems that this is now quite off topic, but ... but I don't think
it's fair to attack people over what is almost certainly just a priority
decision.
since you're objecting to things i did not say, and ignoring things i
did say, i think we can let this drop now.
…--
P Vixie
|
this solution works well, thanks for sharing :) |
It would be better if you could write a wrapper for ssh-add. When using ssh-add, a task is automatically created and delayed for 30 minutes to execute ssh-add -D. |
The workaround for this issue that I used to remove all identities on shutdown:
Now your SSH identities should be removed automatically every time you shut down Windows. Optionally, the PowerShell script can also be executed on logoff instead of shutdown by navigating to |
This is cool thanks. It still leaves a hole on power loss and panic and other unclean shutdowns but it is better than every account having to do this separately.
p vixie
|
I am not sure if anyone else is in the same boat as me but the only reason I used SSH from Windows-Land in the first place is to use the Remote SSH plugin in VS Code. Otherwise all SSH'ing I do is from WSL where the agent works as expected. I just discovered if you want to force VSCode to use SSH from WSL instead of Windows and stop using Windows SSH and agent altogether you can: Create a bat file somewhere like your home directory called
This forces it to run the login scripts which was important for me because that sets up the SSH agent inside of the WSL environment. I happen to use this in a bashrc to start the ssh-agent:
Then from within VSCode set the Remote SSH Option: Edit: If it doesn't work, you may need to set your default WSL with the command: |
Another way to work around this if connecting to local VMs is to have a local-only passwordless key that can connect only to those VMs. This doesn't widen the impact because anyone with access to the laptop or w/e would have access to the VM data anyway. (not always applicable of course but I don't do dev on remote servers directly) |
Actually, it ONLY works as a user logoff script, NOT as shutdown script run by SYSTEM. "ssh-add -D" must be run as the same user as ssh-agent. This doesn't work (well, unless you run ssh-agent as SYSTEM):
|
Yeah none of that is useful. If I've got to fight Microsoft on the security policy they intend to enforce, I'll just avoid their version of ssh. Sad but not new.
Microsoft, your registry is not safe for my unlocked keys. Please stop insisting that I ignore the evidence of my senses and my own ability to reason. You are a supplier not an occupier.
p vixie
|
I just wasted over an hour trying to figure out what exactly Microsoft must be doing to cache my passphrase or decrypted key after noticing I was only getting prompts from Pageant (I still use a PPK version for other stuff). This is mad behaviour. I get that the plaintext key is encrypted with the DPAPI, but nobody familiar with OpenSSH or any SSH agent that I'm aware of would expect this behaviour. You start the agent, you add your key, you decrypt it with your passphrase, and then if the key is removed from the agent or the agent is terminated, that key ceases to exist. If it's going to store it in the registry like this then I don't see much point in the agent, other than being able to add keys stored outside the default path. For my use case I may as well not use the agent and store my key unencrypted in the default location in my home directory — it's still protected by the DPAPI, so anything more than that is really security through obscurity. At first I wasn't sure whether I was more surprised by the fact this behaviour exists, the fact that it uses the Registry of all things, or that this issue has been open for almost five years without a fix. However I then realised that the behaviour's even worse than it seems and I can't see anyone having mentioned this above — not only do decrypted keys persist in the registry across reboots and agent restarts, they persist even if you delete the key files from disk and restart the agent. This may not surprise anybody familiar with this issue as the problem is that the in-memory behaviour has simply been changed to use the Registry and thus no reference to the original filepath is stored (as far as I can tell…), but I think it highlights how bonkers this is. The behaviour of the original OpenSSH agent was modified on purpose making it less secure, and when you consider that this behaviour affects private keys and certificates it lowers the overall security of multiple systems and resources way beyond the machine running the agent. I've been really enjoying using Windows Terminal and the built-in OpenSSH client so I'm going to try out KeeAgent (thanks for the pointer @egfx-notifications!). However it's been interesting reading the posts above and getting a feel for the difficulties that have been faced in making an "official" WIndows OpenSSH implementation. All I can do is echo others in saying that the behaviour documented in this issue really does heavily violate the principle of least astonishment for many users, and I believe that adding a section explaining the behaviour (how keys are stored, that this storage is permanent, and how to remove them) to this page on the MS docs (or even a new page in the same area documenting the agent and covering basic usage) would go a long way towards mitigating this astonishment. And even save people some time :) |
Shouldn't fixing this get some priority in light of Microsoft's Secure Future Initiative? |
security is in the mind of the beholder. if microsoft thought keeping a copy of my unlocked key in their persistent registry wasn't secure, they would not have put it there. so there's no question that they won't be taking it out, even as an option let alone as the default. my workaround was to uninstall this and install https://www.msys2.org/ instead. (this also comes with a pretty decent terminal emulator.) this uses ssh-agent in the traditional way (similar to pageant) such that when the agent dies, the unlocked key in its memory heap dies with it. just like bsd and linux. i think microsoft will never stop embracing-and-extending. |
It is productive nor necessary to discuss and speculate about MS' motivations. To me, this is a simple and rather obvious error that still needs to be corrected. The name "ssh-agent" is widely understood to imply certain essential functionality, but expectations are not met. Either correct that, or rename the program to protect users from unwittingly walking into a trap. The SFI has both "Secure by design" and "Secure by default" as stated security principles so there's little wiggle room here. So, yes, they may have thought of the current behaviour as secure, which caused the issue. Time to re-think. SFI provides guidance. |
"OpenSSH for Windows" version
7.7.2.2
Server OperatingSystem
Irrelevant
Client OperatingSystem
Windows 10 Home (18362.418)
The problem
I am using private SSH-keys encrypted with a passphrase. When using any SSH-agent, that means I have to provide my passphrase to be able to load the key and use it. I've used pageant before and there you load the key and provide the passphrase. Whenever pageant gets terminated (by shutdown, rebooting, ...) the key is removed from memory, and I have to provide my passphrase again the next time I want to use it. Every time, hence the security advantage of having an encrypted SSH key.
With the windows openssh agent however, that's a different story. I have my agent set to automatically start with windows (I believe by running
Set-Service ssh-agent -StartupType Automatic
) just like I did with pageant. However, the windows openssh agent seems to permanently store my SSH key somewhere after loading it to the agent once (ssh-add
), because when I runssh-add l
after a restart of my computer, they encrypted key which I loaded before the restart is automatically loaded again, without requiring my passphrase again. This completely voids the advantage of a passphrase-protected SSH key and to my opinion is a big security issue.Proposed solution
Do not store my SSH key permanently when I load it into the agent, but only temporarily store it in the agent's memory. Or at least store it in it's passphrase-encrypted form and ask for my passphrase every time the key gets loaded.
The text was updated successfully, but these errors were encountered: