Win32-OpenSSH icon indicating copy to clipboard operation
Win32-OpenSSH copied to clipboard

ssh-agent should support '-c' and '-t' options of ssh-add

Open aaccioly opened this issue 6 years ago • 22 comments

"OpenSSH for Windows" version 1.0.0.0

OperatingSystem Windows 10 Pro

I've set ssh-agent service startup type to Automatic. I've also set a passphrase protected key at %USERPROFILE%\.ssh\id_rsa. The passphrase in question is not the same as my user password. After rebooting my PC, if i type ssh-add -l I can see that my key has been loaded by default (without any prompt for my passphrase). I've also noticed that I can connect to ssh -T [email protected] without problems.

My question is: How is the ssh-agent startup service able to add id_rsa without asking for my passphrase? Is it storing my passphrase somewhere? If so, where?

I'm familiar with services such as PAM, as well as software such as GNOME Keyring, KWallet, etc. Just want to understand exactly what is the Win32 implementation doing and possible customize OpenSSH's security policy to ask for my passphrase at least once after login.

aaccioly avatar Feb 01 '18 23:02 aaccioly

Did you ever add your key with ssh-add?

JW0914 avatar Feb 01 '18 23:02 JW0914

@JW0914, yes, before restarting my PC.

aaccioly avatar Feb 02 '18 00:02 aaccioly

In Windows, once the key is loaded with ssh-add, it will no longer ask for a password.

If you want the convenience of connecting to sessions without having to continually retype the key path, configure a ssh user config at %UserProfile%\.ssh\config.

  • For example, here's the one I utilize, with a generic port and ddns addresses:
    • Say I needed to login to my FreeNAS server as root, I'd simply issue ssh FNr
      • This is one of the few times case sensitivity matters in Windows, as the case must match exactly to what is specified for Host (bottom of config, under Hosts)
#

    ##::[[---  Windows OpenSSH Config  ---]]::##

####################################################
               ##----- Custom -----##
####################################################

UserKnownHostsFile                = ~\.ssh\known_hosts


####################################################
              ##----- Options -----##
####################################################

    # Connection #
#---------------------------------------------------
AddressFamily                     = inet


    # Encryption #
#---------------------------------------------------
RekeyLimit                        = 500M 60m


    # Authentication #
#---------------------------------------------------
ChallengeResponseAuthentication   = no
KbdInteractiveAuthentication      = no
PasswordAuthentication            = no

PreferredAuthentications          = publickey
PubkeyAuthentication              = yes
AddKeysToAgent                    = ask


    # Reliability #
#---------------------------------------------------
TCPKeepAlive                      = yes


    # Security #
#---------------------------------------------------
ForwardAgent                      = yes
ForwardX11                        = yes

GatewayPorts                      = no

HashKnownHosts                    = yes
StrictHostKeyChecking             = ask


    # Logging #
#---------------------------------------------------
SyslogFacility                    = AUTH
LogLevel                          = VERBOSE


    # Environment #
#---------------------------------------------------

  # Disabled:
    ## PermitUserRC               = yes


    # Ciphers and ReKeying #
#---------------------------------------------------
FingerprintHash                   = sha256

Ciphers                           = [email protected],aes256-cbc,aes192-cbc

HostKeyAlgorithms                 = [email protected],[email protected],ssh-ed25519,ssh-rsa

HostbasedKeyTypes                 = [email protected],[email protected],ssh-ed25519,ssh-rsa

KexAlgorithms                     = [email protected],curve25519-sha256,diffie-hellman-group-exchange-sha256,ecdh-sha2-nistp256,ecdh-sha2-nistp384,ecdh-sha2-nistp521

MACs                              = [email protected],[email protected],hmac-sha2-256,hmac-sha2-512

PubkeyAcceptedKeyTypes            = [email protected],[email protected],ssh-ed25519,ssh-rsa


####################################################
               ##----- Hosts -----##
####################################################

    # AsRock #
#---------------------------------------------------
Host                              AR
  Hostname                        c2750.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\AsRock_2r

Host                              AR0
  Hostname                        c27500.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\AsRock_2r

Host                              AR1
  Hostname                        c27501.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\AsRock_2r



    # ESXi #
#---------------------------------------------------
Host                              ESX
  Hostname                        esxi.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\ESXi_2r

Host                              ESX0
  Hostname                        esxi0.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\ESXi_2r

Host                              ESX1
  Hostname                        esxi1.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\ESXi_2r


    # FreeNAS #
#---------------------------------------------------
Host                              FNr
  Hostname                        freenas.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\FreeNAS-root_2r

Host                              FNj
  Hostname                        freenas.wrt
  Port                            9876
  User                            someuser
  IdentityFile                    %d\.ssh\ids\local\%h\%r\FreeNAS-JW0914_2r


    # Sophos #
#---------------------------------------------------
Host                              UTM
  Hostname                        192.168.2.1
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\Sophos_2r

Host                              UTM
  Hostname                        utm.wrt
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\local\%h\%r\Sophos_2r

Host                              UTMR
  Hostname                        your.ddns.com
  Port                            9876
  User                            root
  IdentityFile                    %d\.ssh\ids\remote\%h\%r\Sophos_2r
  • See the Tokens section for the variables definitions in the IdentityFile path

JW0914 avatar Feb 02 '18 03:02 JW0914

@aaccioly ssh-agent is re-implemented from scratch for Windows to be more secure and provide a single sign on benefit.

ssh-agent encrypts the added private key using user's (Windows) password (using DPAPIs). It further persists the encrypted password in a "SYSTEM" only registry node. This prevents malware in user space from gaining access to the private key.

Protecting using DPAPIs mean that, your private keys are usable (for signing purposes) as soon as you log in. Currently, there is no way to customize it for a "ask for passphrase each time I log in". You'll have to explicitly delete your keys - you could schedule a task that could do it at logon.

manojampalam avatar Feb 02 '18 05:02 manojampalam

@manojampalam , thanks for the in-deep explanation. Is this valid for every key that I add or only id_rsa? Is it supposed to respect ssh-add -t or -c if I reboot my machine? I would like to confirm my passphrase every once in a while instead of having my keys always loaded / ready to go.

aaccioly avatar Feb 02 '18 12:02 aaccioly

Its valid for every key.

Added the following to considerations ssh-agent only supports '-l' '-L' 'd' and '-D' options. It ignores '-c' and '-t' options of ssh-add. It persistently and permanently stores the user's private key.

I've added this as a backlog ask.

In your case, you would want to delete your key as soon as you're done using them.

manojampalam avatar Feb 02 '18 16:02 manojampalam

Hi @manojampalam, fair enough. If I don't want to have my keys loaded indefinitely I guess that my best bet at the moment is to have some Tasks scheduled to run ssh -D every x minutes and when I logout right? (That's what I'm doing ATM, just want to confirm that there isn't a better way).

aaccioly avatar Feb 02 '18 19:02 aaccioly

Right @aaccioly

manojampalam avatar Feb 02 '18 19:02 manojampalam

I personally have a task set up to ssh -D whenever I lock my session or log out, in order to deal with this. It's evolved a little bit since June, but here's my writeup from back then: https://chris.charabaruk.com/2017/06/automated-ssh-agent-locking-win32-openssh/

coldacid avatar Feb 07 '18 16:02 coldacid

@manojampalam, @coldacid's solution seems very useful. I wonder if there could be a user contributed utility section in the openssh repo to house such things?

DarwinJS avatar Feb 07 '18 16:02 DarwinJS

@DarwinJS Good Idea. Is there a standard way to do it in GitHub other than hosting within the repository (and taking contributions via PRs) ? What do you recommend?

manojampalam avatar Feb 07 '18 18:02 manojampalam

Has there been any further consideration for adding support for -c to ssh-add? This is a good security measure for when a user has agent forwarding so that the user can approve any use of their key with a y/n.

rphipps avatar Jul 01 '20 00:07 rphipps

Came here from the KeePassXC issue linked above - would really love to be able to have the -c option

moritzhoewer avatar Sep 23 '20 18:09 moritzhoewer

Came here from the KeePassXC issue linked above - would really love to be able to have the -c option

I have found an interim solution. The program KeyPass has a plugin called KeeAgent that allows you to store your ssh key in the password file and acts as an agent for Putty. It supports the equivalent of the -c option so that you are alerted anytime your key is used. It's been working well for me here. I've also used other programs that use the putty key agent and it's compatible with those too.

rphipps avatar Sep 23 '20 19:09 rphipps

Thanks @rphipps - my use case is similar, but I am using WSL2 and not Putty. This Gist https://gist.github.com/strarsis/e533f4bca5ae158481bbe53185848d49 explained the missing pieces though. So I have also found a workaround that works for me.

moritzhoewer avatar Sep 23 '20 21:09 moritzhoewer

That's excellent. Thanks for posting this option too which I might need for other projects.

rphipps avatar Sep 23 '20 21:09 rphipps

Came here from the KeePassXC issue linked above - would really love to be able to have the -c option

Same for me. It's funny that this FR is open since three years now 🍰 .

DunklerPhoenix avatar Feb 02 '21 12:02 DunklerPhoenix

Hello, How can we vote for this ticket ? Would be great to have the -c option supported...

ppattard avatar Feb 27 '22 13:02 ppattard

The dev team is unfortunately busy. @bagajjal are there any plans to support the -c and -t options of ssh-add ?

nkrepo avatar Feb 28 '22 06:02 nkrepo

@nkrepo - We have plans to provide ssh-agent functionality just like in unix. This doesn't require user to start ssh-agent as a service. Please note, this will be non-default functionality. Users can choose whether they want to start ssh-agent as a service or as a process that is tied to the current shell. This is currently in our backlog and no committed timeline.

Once we have this implementation, all the gaps (like this) will automatically fill.

bagajjal avatar Feb 28 '22 17:02 bagajjal

Not only does the Windows SSH Agent not support the -t option, also it keeps added keys accross reboots! In my case PKCS#11-stored keys!!! I've used Smartcard (PKCS#11) and PIN-protected SSH keys for years on Linux (way before FIDO2 became a thing), now to discover that Windows just significantly cripples that approach "to be more secure" (quote)... Me 😠

cdu-genedis avatar Jan 08 '24 07:01 cdu-genedis

Not only does the Windows SSH Agent not support the -t option, also it keeps added keys accross reboots! In my case PKCS#11-stored keys!!! I've used Smartcard (PKCS#11) and PIN-protected SSH keys for years on Linux (way before FIDO2 became a thing), now to discover that Windows just significantly cripples that approach "to be more secure" (quote)... Me 😠

As a workaround, I run a PowerShell script at system logoff time that deletes all SSH identities by running ssh-add -D. The script should be installed in the Group Policy Editor at User Configuration->Windows Settings->Scripts->Logoff->PowerShell Scripts.

See attached. Note that you'll want to drop the .txt suffix from the file, which was added because GitHub doesn't allow attaching PowerShell scripts. delete-all-SSH-identities.ps1.txt

rgalonso avatar Jan 09 '24 20:01 rgalonso