Win32-OpenSSH
Win32-OpenSSH copied to clipboard
ssh-agent should support '-c' and '-t' options of ssh-add
"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.
Did you ever add your key with ssh-add
?
@JW0914, yes, before restarting my PC.
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)
- Say I needed to login to my FreeNAS server as root, I'd simply issue
#
##::[[--- 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
@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 , 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.
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.
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).
Right @aaccioly
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/
@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 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?
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.
Came here from the KeePassXC issue linked above - would really love to be able to have the -c
option
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.
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.
That's excellent. Thanks for posting this option too which I might need for other projects.
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 🍰 .
Hello, How can we vote for this ticket ? Would be great to have the -c option supported...
The dev team is unfortunately busy. @bagajjal are there any plans to support the -c and -t options of ssh-add ?
@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.
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 😠
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