PowerShell / Win32-OpenSSH

Win32 port of OpenSSH
7.46k stars 766 forks source link

ssh-agent: permanent loaded ssh-key storage #1487

Open mluypaert opened 5 years ago

mluypaert commented 5 years ago

"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 run ssh-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.

bagajjal commented 5 years ago

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.

mluypaert commented 5 years ago

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.

bagajjal commented 5 years ago

Not really. The registry is only accessible for SYSTEM, ADMINISTRATORS.

bagajjal commented 5 years ago

fyi, User keys are stored in Computer\HKEY_CURRENT_USER\Software\OpenSSH\Agent\Keys.

xdhmoore commented 5 years ago

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.

mluypaert commented 5 years ago

@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.

lusitania commented 5 years ago

Different angle: I was looking for a reason why an outdated and invalid key kept showing up in ssh-add -l although I previously removed all entries with ssh-add -D (and restarted my WSL session) while my pass vault wasn't even running. It took me an hour to find this issue and eventually found and deleted the key from the registry. IMO having ssh-add/agent store keys persistently is very non-standard and leads to confusion, uncertainty and unease. There's a reason why we use pluggable backends (KeePassXC in my case, keychain on MacOS, ...). ssh-agent is expected to be just that, an agent. Not a caretaker.

feenes commented 4 years ago

In my opinion this is a bad choice. Several reasons. 1.) people who used other OS'es before do expect a certain behaviour from ssh-add. GIving a program the same name, but implement it differently is confusing by definition.

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, ...) then my agent will remember all these keys. (Let's imagine it's 20 different keys)

Only drawback is, that most servers will abort after a few wrong keys have been presented. So not always a good idea to always drag along all ssh-keys ever added during the history of a suer account.

jghal commented 4 years ago

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.

NicoAdrian commented 4 years ago

Has anyone found a way to disable this behaviour ?

mluypaert commented 4 years ago

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 ssh-add.exe -D

xdhmoore commented 4 years ago

Has anyone found a way to disable this behaviour ?

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

maertendMSFT commented 4 years ago

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

xdhmoore commented 4 years ago

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...

mluypaert commented 4 years ago

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

@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.

xdhmoore commented 4 years ago

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.

bitkat commented 3 years ago

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.

pdavies commented 3 years ago

"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?

ahicks92 commented 3 years ago

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.

bagajjal commented 3 years ago

@ahicks92 , The keys stored in the registry are DPAPI encrypted. only the current log in user can access them.

ahicks92 commented 3 years ago

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?

aservedio commented 3 years ago

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.

bitkat commented 3 years ago

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?

bagajjal commented 3 years ago

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.

vixie commented 2 years ago

@bagajjal <<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.>>

thank you for reopening the issue. for my own key material, your workaround is sufficient. does this have a timeline?

also note, malware often runs in the context of a user. this may be due to a poisoned supply chain, or an infection, or deliberately installed "potentially unwanted software", or an intrusion. the mere existence of an unlocked key is a danger that ought to require opt-in on every reboot.

the digital world itself is now less safe because of microsoft's design choice here. as i wrote above, i can use your proposed workaround to restore consent in the management of my own keying material. but the default you propose to preserve will make it more likely that other microsoft devices in the world will be able to attack me (and others) in all kinds of ways.

good security is often at odds with user convenience. and that's why openssh (please don't call it "linux openssh" since many of us first encountered it on BSD) has the design it does. actual security experts decided that ssh-agent should not be persistent, for reasons microsoft seems to have misunderstood.

hopefully the microsoft implementation of gss/krb5 "tickets" does not have this same persistent behaviour.

hallambaker commented 2 years ago

I protest the assertion that the Linux people should decide how SSH works on Windows. They do not understand the platform. No, the way Linux does things is not the perfect, nor is there any reason Windows should follow the Linux approach which is actually the result of Linux lacking a key manager, unlike Windows and macOS.

Because Linux lacks the platform key management of the modern platforms, they invented a set of solutions I regard as 'half baked' at best. I am not at all confident they really work on Linux, but trying to use Windows as if it was Linux is a sure fire way to end up in a security blunder.

Persisting user keys in the platform key vault is the obvious approach and should be the preferred approach. The windows platform does allow keys in the vault to be protected by an additional passphrase as an option. It makes sense to offer that as an option.

Contra Vixie, user convenience is a security issue. Bully users with half baked security controls imposed by some security bully and they just turn off the controls. And they are right to do that because most users understand their security needs better than a system designer that has never met them let alone one who doesn't even use their platform.

Reading this thread, it is clear that most of the people commenting have no idea of how DAPI works and have no interest in finding out.

Please abort these proposed changes immediately.

vixie commented 2 years ago

phillip, i am not a linux person, but i object to your tone here. --paul

hallambaker commented 2 years ago

What I object to is people who should know better writing things like this:

"the digital world itself is now less safe because of microsoft's design choice here"

You are far too prominent to make public statements of that sort, it would be bad form even if you were right. Do you know how many people's New Years Eve you have interrupted with your intervention here? You are entitled to your opinion but you not entitled to speak for 'security experts' in general.

There is a problem here but it is rather different to the one you raise. The real problem is that the behavior is not sufficiently documented and does not fully reflect the capabilities of the Windows platform. I don't believe in lowest common denominator security. Windows, macOS, iOS and Android all have key managers build into the platform, they work rather differently but cryptographic apps should make use of those features. We should level up, not down.

SSH on Windows probably doesn't need the ssh_agent at all, if the ssh_client is talking to the key store directly, the functionality would probably make more sense in the key generation app.

The documentation is somewhat fuller than last time I looked, but it still needs more detail:

https://docs.microsoft.com/en-us/windows-server/administration/openssh/openssh_keymanagement

The documentation for the Windows version should explain what is going on and precisely which stores the keys are being loaded into. That allows those of us with different cryptographic approaches (threshold/ hardware tokens) to hook in.

Before making changes to the way the Windows version works, I would also look at whatever macOS is doing.

Binding a key to memory is not the ultimate in security. Since SSH supports Ed25519 it could at least in theory make use of a hardware key embedded in the platform that cannot be extracted from it with an application layer threshold overlay.

vixie commented 2 years ago

on that basis, there's room for agreement. microsoft ported the openssh software (which should probably not be called "the linux implementation" since it's not linux-specific and did not originate on linux), and when they did that port, they changed a vital aspect of ticket lifetime (was ephemeral, is now persistent). you seem to want to focus on how this change wasn't documented or communicated well, and i have no argument against that position. i want to focus on how lifetime of authentication information is the worst possible case of violating the principle of least astonishment, and i don't think you're arguing otherwise.

we could go further, and look for other areas of agreement. i for example am sure that keeping one of these tickets alive when i am not aware of it, no matter how it's encrypted in the registry, will end in tears. microsoft's long-official position is that UAC is a hint not a barrier, and the long litany of related vulns and breakins bears that out. it's possible that some corner of that concept space overlaps with your position. happy to discuss it further if you're interested/willing.

i argued hard against the ssh agent model back in the mid 1990's, and several of the flaws of ssh1 were predictable thereby. in kerberos, a ticket has lifetimes (next renewal and final renewal), and key revocation that could invalidate tickets earlier than those renewals. ssh has got none of that, and so the ssh-agent equivalent of a "ticket" is valid anywhere it's recognized, without centralized visibility. if i had got my way on that back then, microsoft would not be opening quite so much of a "pandora's box" with their silent-persistence change in their ssh-agent port to windows.

i'm comfortable with the workaround microsoft has offered, since i know they have a large installed base of not-like-me users of their ssh-agent port, and they can't easily break working configurations there. but i'd like to get a timeline. meanwhile i'm investigating how to get "pageant" to replace microsoft's "ssh-agent" port so that i can fully control the destiny of my authentication information. i think you support that goal even if you don't agree with how i describe some aspects of it.

feenes commented 2 years ago

Philip, I am very surprised about your comment.

I share vixies impression. For me personally the proposed fix is good. However most people use the default configuration of windows and with my (admittedly limited knowledge) the default implementation seems less secure and seems to increase the probability of stolen ssh-keys

This issue is not about Linux dictating how Windows should work. It is about an intentional security concept of openssh.

It is also about the fact, that people who use or know openssh are used to / expect a certain behavior of its security model.

Often ports of an open source solution ported to another platform try to stick as much as possible to the original behavior to avoid the element of surprise.

The whole concept of ssh-agent was (and for other platforms still is) that it tries to make it difficult to steal the private keys from a user. (they are stored in the RAM of one special process and no other process knows the key's value, but is able to only use it) and that the live cycle of keys can be controlled independently of the user's session.

I for example have many ssh-keys and only activate the ones, that I need and know, that the next time I power down / up my PC this key is protected again. (so any fix facilitating this for me is already great)

I may be a naive person, but when I first encountered this issue I thought that the current implementation was an attempt to increase the user's comfort and that certain security aspects were overlooked and that after being notified by the community open-ssh would be 'fixed'. What was overlooked is, that not all users might want to wish, that the live cycle of a user's session is identical to the live cycle of all private ssh-keys, that were added to the agent.

The resistance to make open-ssh work (security wise) the same way as it is working on other platforms was a big surprise for me. If there is a way to increase security by storing the keys in a place even safer than one's processes' RAM, then this is of course an improvement worth implementing. The negative surprise is the change in the life cycle of the keys.

I am no security expert, but if under windows one user process cannot inspect the memory of another process of the same user, then the security difference in both implementations is even bigger. One solution allowing any user process to retriever and copy the private keys stored in the registry vs. allowing any user process to use the private key, but not to copy it.

So the fact, that private keys stay persistent and can be read and copied by any user process seems to be (even if one is no security expert) less secure.

If the implementation were called ms-ssh or similar I would still be surprised by the choice of implementation, but I would just replace it with an open-ssh port if I wanted the well known open-ssh behavior.

So the proposed fix will make my PC safer which is already a relief for me.

hallambaker commented 2 years ago

My position is simply that we should design cryptographic applications to make use of the full capabilities of each platform rather than reduce everything to the lowest common denominator.

All my code development machines are Windows, all my servers are Linux, all my laptops are macOS. I deliberately use every one of the major platforms so that I understand the differences.

To the extent that the current behavior is inconsistent and results in surprise, sure we should fix that. But that doesn't mean the original behavior was wrong, just that it should be accessed in a different way.

This discussion has been centered on deriving the user experience from the constraints of the cryptographic implementation. We should do the exact reverse. Consider the user experience first and then work out how to apply cryptography to realize it: At what point are authentication factors required?

Looking at how SSH is used in practice, the issues raised in this thread are nowhere near my top concern. Hence my irritation at being called out to what I was told was a five alarm fire. A much bigger concern would be that we need to get users making use of client certificates with a different key for each client device. I am told SSH has this capability but I have found little evidence of it in the documentation.

The reason I put such an emphasis on documentation is that documentation is even more critical to the security of a system than the actual running code. I find it really difficult to find any information on the Windows SSH system because I keep finding myself reading ten year old Linux reference pages of rather poor quality.

So what most users do in practice is they go and search for an online how to guide and most of those are written by people who have absolutely no clue whatsoever. One university was telling people to email themselves the private key. They did not mention the need for a secure password.

The UI aspects of Windows are advisory controls but the cryptographic layers have real teeth. A DAPI key can be encrypted under the login password and a secondary password. But the real goal should be to get away from keys that are ever in the RAM of the CPU at all. ROWHAMMER and SPECTRE class attacks make those approaches untenable in the longer term. The only way to get to a secure system is to move processing of the most critical security related functions out of the CPU entirely and into a separate crypto processor. The move to Ed448/Ed25519 will make that possible.

vixie commented 2 years ago

{{This discussion has been centered on deriving the user experience from the constraints of the cryptographic implementation.}}

not at all.

aservedio commented 2 years ago

My main grip here is that this is called ssh-agent and I have been using that for decades and I adapted to the way it has been working with passphrases. The changes made here in the name of progress is nice but because this is reusing a well establish name that's been around for decades, most users will make the assumption it works the same way and if like me they are using multiple passphrases, well this changes here is a downgrade in security since now you only need my windows login and you get all my keys instead of just the one I know I loaded for a specific time.

l4kr commented 2 years ago

What the hell is the point of the ssh-agent then if it's faster to just type in a passphrase instead of having to do a few more commands before login?

Security? They just keylog you and since you type the passphrase a lot it's just easy to figure out that something is important in that phrase you type a lot and makes no sense...

In conclusion, ssh-agent is a passhprase with extra steps.

hallambaker commented 2 years ago

The point is that you can run scripts that are connecting multiple times without giving the password to the script.

On Sat, Jan 22, 2022 at 6:40 AM l4kr @.***> wrote:

What the hell is the point of the ssh-agent then if it's faster to just type in a passphrase instead of having to do a few more commands before login?

Security? They just keylog you and since you type the passphrase a lot it's just easy to figure out that something is important in that phrase you type a lot and makes no sense...

In conclusion, ssh-agent is a passhprase with extra steps.

— Reply to this email directly, view it on GitHub https://github.com/PowerShell/Win32-OpenSSH/issues/1487#issuecomment-1019204481, or unsubscribe https://github.com/notifications/unsubscribe-auth/AAPSKUFMUAIPNZL2ZANFWHLUXKJRVANCNFSM4JGFZLVA . Triage notifications on the go with GitHub Mobile for iOS https://apps.apple.com/app/apple-store/id1477376905?ct=notification-email&mt=8&pt=524675 or Android https://play.google.com/store/apps/details?id=com.github.android&referrer=utm_campaign%3Dnotification-email%26utm_medium%3Demail%26utm_source%3Dgithub.

You are receiving this because you commented.Message ID: @.***>

aservedio commented 2 years ago

Isn't that what a key without a passphrase is for?

mluypaert commented 2 years ago

Isn't that what a key without a passphrase is for?

@aservedio No, a key without a passphrase is stored permanently as an unencrypted file on disk, a key with a passphrase is stored as an encrypted file at rest, and only unencrypted in memory while loaded via ssh-agent (so temporarily during usage).

aservedio commented 2 years ago

If you choose to not use a passphrase yes you should obviously store them securely.

I'm using the passphrase because I want the prompt. Same reason I'm using MFA as well. And this works on all ssh-agent implementation except this one.

vixie commented 2 years ago

l4kr wrote on 2022-01-22 03:40:

What the hell is the point of the ssh-agent then if it's faster to just type in a passphrase instead of having to do a few more commands before login?

the ticket (unlocked key) is a session layer construct. typing a passphrase, or pressing a 2FA "approve" button, does cost time, and that cost must be amortizable or else be seen as "too costly".

Security? They just keylog you and since you type the passphrase a lot it's just easy to figure out that something is important in that phrase you type a lot and makes no sense...

In conclusion, ssh-agent is a passhprase with extra steps.

that's both non-sequitur, and aggressively dismissive.

-- P Vixie

ahicks92 commented 2 years ago

If you're keylogged, it's a lost cause anyway save for MFA. It's not that hard to go "huh, I see they're typing random strings, I bet those are passwords". But if you have the kind of access needed to keylog then in many cases you have the kind of access to just rip things out of the decrypted registry or whatever.

The reason I'm here personally is articulated well by @aservedio. As a more simple framing of it: if I go through airport security after using ssh-agent on Windows and they ask me to log into my machine, I've now given them not only my machine but access to a subset of my work's infrastructure. I know what someone is going to say because it's the obvious objection: don't we have MFA? The answer is yes, but I have at least one counterexample I can't go into publicly where we specifically had to avoid it for a while for a few things, and I'm betting that for example Smallstep with Windows ssh-agent bypasses MFA across reboots until the cert expires.

I don't think that holding the keys in memory is exactly more secure than the registry if we assume that both have had the same keys added and have been brought to an equivalent running state. I think that the debate going on here about that is missing the point. The point is that when I use ssh-agent on any other platform I know that my system is reliably starting from a state where all keys are fully encrypted until I request them, and that nothing can access them without my help until such time as I choose to start using them today. Or more succinctly: it lowers the window of opportunity in which an adversary only needs to overcome software rather than overcoming cryptography.

With Linux-style ssh-agent there are two modes of system operation: "on, and this computer is accessible" vs "on, and you can also access this wider sub set of machines", and after every reboot Linux starts in the former default-deny state. That's the valuable component, and the design of Linux ssh-agent makes sure that things fail to that state. The proposed solutions of writing scripts to clear it by contrast are fail-dangerous and also highly likely to fail invisibly. Disregarding bugs, that's yet another great attack point.

I think that the big telling thing is this: I can easily construct ways in which Windows-style behavior is less secure than Linux-style behavior, but it's quite hard to go the other way if it's possible at all. And as established the Windows-style behavior is surprising as well.

snowzach commented 2 years ago

Would it be possible to add -t option to ssh-agent such that it forces the timeout keys after a fixed time? I don't typically want to run ssh-agent interactively. I like having it running in the background for say when I launch VS Code. It prompts me the first time and remains active for however long it lives in ssh-agent. If the -t option isn't specified it follows the original behavior.

dobsa commented 2 years ago

I wonder, why did Microsoft decide to port the Linux software to Windows at the first place? Why not writing own "Windows proper" implementation of SSH protocol? Another question: If you want to use Windows cryptographic capabilities properly, then why not making ssh-keygen to generate the keys directly in the vault? And, possibly, implement completely different set of tools to not to confuse them with the existing once. Well, the answer may be it is all because there are too many people already using Linux/Unix OpenSSH implementation and they would have little reason to start learning a new one. Also there are too many scripts written that are relying on the old behavior. It is quite hard to reconcile the two hostile worlds (Windows and Linux). In fact it is impossible to the satisfaction of both. E.g.: I am still missing several features of OpenSSH that simply were not ported to Windows... (again it would be better not to pretend and create new Windows-perfect implementation of SSH).

Please keep OpenSSH ssh-add to work as it is expected by us, developers (while not compromising security). And introduce new tools to utilize the amazing modern Windows features.

dobsa commented 2 years ago

And, I wouldn't be writing here at all if it was not for the shock of seeing my key being available after computer restart without passphrase.

dobsa commented 2 years ago

When using a proven secure tool (like OpenSSH is) I just don't feel comfortable at all, when somebody is forcefully pushing me to rely on security of something else then the secure tool itself. If that is the case, then I rather choose not using it. There has not been much written about security of Windows OpenSSH port, yet. I still have my serious doubts about it. This is just my personal feeling. No harm or accusation intended.

My opinion: if you want people to trust the Windows port of OpenSSH tool, do not diverge by making it something else then OpenSSH. Because "something else" is not being trusted by the community. OpenSSH is.

dobsa commented 2 years ago

BTW, access to Windows account on Windows 10 is not "protected by password". If some one steals a computer, you can get access to the private key not only using password, but also using PIN, facial recognition, or fingerprint. Some of those are very easy to steal or fake. I really want my key to be protected by the encryption OpenSSH chose and with the passphrase I have chosen. Not by my fingerprint, face, or 4 digit PIN.

immersivegamer commented 2 years ago

The Windows specific tech is not the issue here. DPAPI is fine by me but only for the temporary storage of the unencrypted key while it is not in use. Running as a windows service is great too, no need to manage complex startups. Install software, got to services,, and enable automatic start. I would still like the option of keys being invalidated periodically (ideally after each reboot).

The security issue for me is not the access to the key unencrypted key (I understand how DPAPI works, and it is a great tool for the unencrypted key while it is not being used) but instead the issue that if a program or user is running under my profile they gain automatic access to servers automatically. All they have to do is check for ~/.ssh/config. They could even guess ssh dev and probably get a hit most of the time.

There are uses for storing the key for a long time. One example I can think of if for automation or long running services, but that is going to normally be on a server that most likely will have extra security to get to already. The usefulness here outweighs the risk.

For a developer/operations machines, however, I feel like it does not. The users for these machines normally need access to a wide range of servers. These machines are used by people and are more likely to be around people. For development and operation maintenance I would rather only have the keys loaded in the agent while I am actively using the machine. Sure, there is risk while I take a lunch break but the risk is lower than having the keys loaded forever. _Just so it is clear, the problem I have is that the key is loaded _forever__. Of course I don't want to be typing in my password each time I hop around. Activate it once for the session and be done. For development servers I would even be happy with days to weeks of it hanging around. Forever is just too long.

From a security perspective I do think ssh-agent should not store keys forever by default. Give users the option if they want to store for longer or forever. Personally the work arounds are good enough for me to keep using as is. I'll probably use a combination of ssh-add -t option when adding more secure keys and a scheduled task with ssh-add -D as suggested for keys I don't mind hanging around for a little while or for cleanup incase I missed using -t for keys. As someone else mentioned in this thread, this not as graceful as a failure to cleanup is worse than a failure to persist.

Edit: Thinking of the ideal workflow I would like it to key the identities but re-prompt me for the passphrase after a session or expiration, but I'm not sure how that work flow would actually work on the backside when you do ssh hostname.

egfx-notifications commented 2 years ago

Edit: Thinking of the ideal workflow I would like it to key the identities but re-prompt me for the passphrase after a session or expiration, but I'm not sure how that work flow would actually work on the backside when you do ssh hostname.

@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:
https://github.com/mendhak/keepass-and-keeagent-setup

krisavi commented 2 years ago

From a security perspective I do think ssh-agent should not store keys forever by default. Give users the option if they want to store for longer or forever. Personally the work arounds are good enough for me to keep using as is. I'll probably use a combination of ssh-add -t option when adding more secure keys and a scheduled task with ssh-add -D as suggested for keys I don't mind hanging around for a little while or for cleanup incase I missed using -t for keys. As someone else mentioned in this thread, this not as graceful as a failure to cleanup is worse than a failure to persist.

ssh-add -t unfortunately does not work

OpenSSH_for_Windows_8.9p1, LibreSSL 3.4.3
ssh-add -t 15
Could not add identity "C:\Users\user.name/.ssh/id_rsa": communication with agent failed

Unfortunately neither does ssh-add -c work, even though it has no relation to how keys are stored or their lifetime.

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. Another usage we had to test was setting time to expire for keys, that is basically only used for automation purposes and does not ask key usage for every machine it wants to access, just as long as it creates all the connections in first 60 seconds. All is well from Mac's or Linux hosts, but Windows no luck, just getting error, does not matter if I start ssh-agent from command line or through the service.

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.

Looking at how SSH is used in practice, the issues raised in this thread are nowhere near my top concern. Hence my irritation at being called out to what I was told was a five alarm fire.

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: I would propose change more like that. Add possibility to generate keys into MS vault using ssh-keygen. If keys are generated that way, then you could store them in registry and autoload them on service start, but if it is from real file that has a passphrase, then after reboot they should be reloaded just in case the passphrase had been changed. I believe that is approach that should fit to everyone. If the limitation is how MS is storing the keys, then add PID of ssh-agent in there and if ssh-agent starts up with different PID, then remove the keys that have PID set up, if no PID is set for reg keys, then those are "OK" to run on different agents across all sessions. Same approach could be applied to make ssh-add -t to work. When it start to use the key, check if key is "expired" and if that is the case, then remove it and ask for passphrase to add it again. Would emulate more similar approach to other implementations than the current Windows implantation is. Yeah, there are caveats on someone modifying the time of the key and possibly being able to start ssh-agent with same PID, but it is still better than current solution where I have to add them manually if I want to set timeout for them or remove them manually before restart or just after restart via workaround to ensure that if someone had access to my Windows password cannot penetrate further into work environment.

In addition we have to rely on DPAPI to ensure the safety of the keys while adding another possible point of failure.

alaincao commented 2 years ago

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! For literal weeks, every time I wanted to connect to a prod server, I did an ssh-add, entered my password and connected. Until one day, I tried to connect, forgetting to add the key. Had I just type the return key, I noticed my mistake and was preparing myself to get rejected and retry. Then I connected... Wait a minute, how TF did I connect ?!? I rebooted and tried again to be sure, then googled around, then landed here... and was absolutely horrified!

Had I even knew this was happening, I would have organized myself differently. In one afternoon, I changed my mind from being amazed by the implementation to a complete lost of trust. I now make sure none of my personal SSH keys ever lands on a Windows computer. Ever. Because I fear there are other shenanigans that could be unearthed.

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... Anyway, permanently storing the key should be an explicit option, not the default behaviour.

vixie commented 2 years ago

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