-
Notifications
You must be signed in to change notification settings - Fork 7.1k
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
Support for RemoteSession over SSH with Password #21114
Comments
There are various Linux/UNIX solutions based around 'sshpass' but they all have the weakness that at some point the password is in the clear. The purpose of the public/private keys is that passwords are never sent over the net so cannot be subject to man-in-the-middle. Windows authentication is an odd beast. My understanding is that you can use ssh with the public/private keys and gain full rights if the user is already currently logged into the machine, eg if you login with ssh to your own windows desktop machine while the desktop is logged in. So this does sound like a chicken and egg situation,
I would recommend against a custom PowerShell mechanism which involves passwords in cleartext. My understanding is that the reason is that user profiles are only fully loaded from the registry etc with the username/password login. However Windows Desktop login today seems to use username and a pin. That also said, it is a general problem that some component needs a password entered but it is deep in the chain and unaware of the actual UI mechanism in use. For instance gnupg lets you set up a password agent for entering the password. But then the whole point of the keys is to avoid this problem and let an ssh key agent manage the keys securely when hopping from one machine to another. |
The problem is with linux&windows interop. Currently if you’re connected with pub key you will not get windows/ad user session, that would be needed in a lot of cases. Also the only time when password would be clear -when an app actually will echo it to the session, and it would be in memory, since connection is already encrypted before the login. |
I think you would have the same problem if you SSH from Windows to Windows using SSH keys.
Yes, unless the user is already logged in, eg try SSH into a Windows desktop using keys with user already logged into desktop.
Password in the clear is still in the clear whether it is in memory, environment variable or command line argument. If you are on a shared host you are at risk of exposing those credentials, for instance this is why if you look at modern cryptographic API they use char array for passwords, not strings because you can clear the array after use, not so with a string which will only disappear when the garbage collector gets round to it. The password is still at risk over an encrypted session with a man-in-the-middle attack, especially if you were cavalier about accepting entries into your .ssh/known_hosts and did not validate the thumbprints. I am sure you may find a solution but it does not mean it would not be acceptable all, or pass a serious security review. If you are already on Linux, I would try arranging a pipeline that uses the existing sshpass mechanism, it already exists and its problems are understood, before writing a new component that needs to pass a security review before acceptance. |
So that you know that I have a bit of knowledge in this area, I wrote Wishstream which uses SSH.NET for the SSH layer. This API provides a callback mechanism when a password is required, so code does not have monitor a stream looking for password prompts etc, the password is provided directly to the SSH API which passes it to the server in the SSH packets. As an example, in my app when the callback was invoked I presented a dialog to enter the password. |
Actually that is not it. Some logons give you a session without any means of logging on from that session to another box. Classic case: I have a Kerberos Ticket Granting Ticket in my session; I want a session to remote box so I present my TGT to Kerberos and I get a ticket for the remote box. I present that to the box and get a session. I run a command in that session which wants to talk to a 3rd box but it can't ask Kerberos for ticket (no TGT). Search for "Two hop problem" :-) |
If you are in the Administrators group, the keys and sshd_config are located in |
actually my use case - I'm building API/lib to run some posh scripts on remote win machines. So I need not only administrator local access, but a valid domain session. without that it seems I would be needed to go not so go route to create an agent that would run needed scripts from service account. this looks odd since PowerShell meant to be an instrument for local+remote host management. |
If you are actually doing an API or lib then you could look at using SSH.NET to do the password authentication "correctly"
However the rest of the world is moving away from SSH with password and recommending SSH keys and key agents. If you do "man ssh" on macOS or Linux, I don't think you will find a command line parameter or environment variable for password. My theory ( only a theory ) is that a password is ultimately needed to authenticate with AD using the LDAP protocols, hence why things need an actual password at some point. |
It is. But you can't make the double hop problem go away. If I logon interactively to a windows machine that machine will use my credential to log on to other services (and this goes back before Kerberos came in). So I can connect to and manage any machine on the network, but crucially remote sessions don't get my credentials, so they can't logon to other further remote sessions. Although you're seeing this as an SSH / from-linux-to-windows issue, it's also a WSMan / from windows-to-windows issue. The one oddity is the security flaw-by-design in ssh which allows a session to opened using a plain text password which can the be accessed from the session. |
OpenSSH itself recommends against non-interactive password auth as it makes it more likely for people to put passwords in scripts and passwords are less secure than pub key auth. Recommendation would be use keyboard-interactive password auth the first time to deploy your pub key. I also understand that some hardware that supports SSH ONLY supports an OEM pre-defined password. In those cases, you can use SSH_ASKPASS as a workaround. |
@SteveL-MSFT thanks for reply. But the problem is more complicated. I am needed not just an access via script, but from dotnet(c#), and usage of SSH_askpass in that cases looks like I would actually be needed to implement it in some extension to your lib, but this functionality is much more important . Let's look at some use cases: |
An alternative is to use Kerberos auth and enable delegation. Like WinRM using Kerberos delegation is more secure than things like CredSSP/plaintext password auth as your password isn't actually send across the wire. Sending your password across the wire is a massive risk because if the target host is compromised, or the network transport encryption used is breakable then the bad actors have your password to do whatever they want. The password is not time limited and can be used to easily translate to other authentication protocols that a service might need. Using Kerberos with delegation not only stops your password from every leaving the device but it also allows you to constrain the services the delegation is for allowing you to limit the exposure when connecting to a compromised host. Even better is that if done correctly you don't even need to have a password embedded in your script, you can either rely on things like PAM to get a ticket for you at logon like Windows does or setup a keytab to avoid embedding a password in your script. Three things need to be in place to use Kerberos authentication
Once setup you can utilise it in PowerShell Invoke-Command -HostName server.domain.com { 'foo' } -UserName user@DOMAIN.COM
# If you don't have it enabled in your ssh config file
Invoke-Command -HostName server.domain.com { 'foo' } -UserName user@DOMAIN.COM -Options @{GSSAPIAuthentication='yes'} In the end you have a few options available to you to avoid the double hop problem
While it would be nice if PowerShell did support a password option through something like the In short delegation is a complex issue, it's full of security risks as how you do the delegation can have dramatic implications on server trust and what you are allowed to delegate to. I don't think PowerShell is in the position here to solve that problem unfortuantely. |
@jborean93 in the docs for the RunspaceConnectioninfo for the SshConnectionInfo I don't see a way to use that in my C# project. https://learn.microsoft.com/en-us/dotnet/api/system.management.automation.runspaces.runspaceconnectioninfo?view=powershellsdk-7.4.0 And that is the main problem. In 2024 ,after so many years from powershell core release, from the release of win-openssh it is really strange that there are simply no good way to manage windows hosts remotely from *nix. I believe it is the main reason why admin center could be deployed only on windows, since this problem just do not exist due to using of wsman, which is allowing just that.
If windows ssh server for example would have such thing as storing ad pub keys in AD and verify them via ad and auth user as net user that would also be good solution. We already have linux servers that authenticates into AD via keys stored in custom AD field
|
You can use this constructor to create an One thing to note is that I did notice Runspace.DefaultRunspace = Runspace.CreateRunspace();
Runspace.DefaultRunspace.Open();
// Define the SSH options
Hashtable sshOptions = new()
{
{ "GSSAPIAuthentication", "yes" }
};
// Create the connection info with the options
SSHConnectionInfo connInfo = new("user@DOMAIN.COM", "computer", null, 22, "powershell", 30, sshOptions);
using Runspace remoteRunspace = RunspaceFactory.CreateRunspace(connInfo);
remoteRunspace.Open();
// You no longer need the thread Runspace to be set.
Runspace.DefaultRunspace.Close();
Runspace.DefaultRunspace = null;
using PowerShell ps = PowerShell.Create(remoteRunspace);
ps.AddScript("'test'");
ps.Invoke();
It's honestly the same as well for the other way around, it's ssh which generally frowns upon password authentication in favour of other things like ssh key auth. If you really want to use password auth have a look out for the community meeting in March where I'm hoping to showcase my RemoteForge project which I have a sudo and ssh example with support for a credential provided in PowerShell PS /home/jborean/dev/SSHForge> $sshInfo = New-SSHForgeInfo -Credential user
PowerShell credential request
Enter your credentials.
Password for user user: ...
PS /home/jborean/dev/SSHForge> Invoke-Remote $sshInfo { whoami }
user |
@jborean93 many thanks! I would definitely try that! |
Hi, best regards |
Dupe of #5782 |
This issue has been marked as duplicate and has not had any activity for 1 day. It has been closed for housekeeping purposes. |
📣 Hey @Nova-Logic, how did we do? We would love to hear your feedback with the link below! 🗣️ 🔗 https://aka.ms/PSRepoFeedback |
Summary of the new feature / enhancement
It is currently possible with pwsh to connect from linux to windows over SSH
with an pubkey or with the help of a regular password.
Both methods are working, but the auth method with a password has some benefits
because the remote shell will run under the users credentials with a valid windows token.
Commands that require a valid windows credentials token will then work
Get-VM -ComputerName @("server1", "server2", "server2")
Proposed technical implementation details (optional)
Option1:
SSHConnectionInfo does currently not allow to set an user password.
it could await the output of "ssh" process on "Password:" and write
the password into the input stream
Option2:
Some command to upgrade the pssession with a valid WindowsUserToken
like "Switch-User"
The text was updated successfully, but these errors were encountered: