ServerMode vs SSHServerMode
See original GitHub issueThere are 4 server mode options when calling pwsh
Argument | Description | Mediator |
---|---|---|
namedpipeservermode /nam |
Creates a bidirectional named pipe to read/write PSRP data | NamedPipeProcessMediator |
servermode /s |
Uses the process’ stdin/stdout to read/write PSRP data | OutOfProcessMediator |
socketservermode /so |
Uses a TCP socket to some Hyper-V endpoint | HyperVSocketMediator |
sshservermode /sshs |
Uses the process’ stdin/stdout to read/write PSRP data | SSHProcessMediator |
It seems like servermode
and sshservermode
are quite similar in behaviour. They both use the console’s stdout
to output and responses and the stdin
to read and input from the client. They do have slightly different behaviour when getting the pipes:
- stdin
- servermode:
new StreamReader(Console.OpenStandardInput(), true)
- sshservermode (Windows):
new StreamReader(new FileStream(PlatformInvokes.GetStdHandle(Input), FileAccess.Read))
- sshservermode (Unix):
new StreamReader(Console.OpenStandardInput(), true)
- servermode:
- stdout
- servermode:
new OutOfProcessTextWriter(Console.Out)
- sshservermode (Windows):
new OutOfProcessTextWriter(new FileStream(PlatformInvokes.GetStdHandle(Output), FileAccess.Write))
- sshservermode (Unix):
new OutOfProcessTextWriter(new StreamWriter(Console.OpenStandardOutput()))
- servermode:
- stderr
- servermode:
new OutOfProcessTextWriter(Console.Error)
- sshservermode (Windows):
new OutOfProcessTextWriter(new FileStream(PlatformInvokes.GetStdHandle(Error), FileAccess.Write))
- sshservermode (Unix):
new OutOfProcessTextWriter(new StreamWriter(Console.OpenStandardError()))
- servermode:
Is anyone able to explain the differences in behaviour between these 2 when it comes to getting the stdio pipes. If there are none (or very minor) why have a dedicated mode argument specifically for SSH. I can set the following in my sshd_config
file and both -s
and -sshs
work just fine.
Subsystem powershell c:/progra~1/powershell/7/pwsh.exe -sshs -NoLogo -NoProfile
Subsystem pwsh c:/progra~1/powershell/7/pwsh.exe -s -NoLogo -NoProfile
I did try setting a subsystem entry for Windows PowerShell as that does have the -s
but it just hangs there forever.
# I don't know why I need -Version 5.1, without it it complains that .NET Framework 2.0 isn't available
Subsystem win_pwsh C:/Windows/System32/WindowsPowerShell/v1.0/powershell.exe -Version 5.1 -s -NoLogo -NoProfile
Issue Analytics
- State:
- Created 3 years ago
- Comments:11 (3 by maintainers)
Top Results From Across the Web
PowerShell Remoting Over SSH, Without SSH!
The important part in the above command is the “-sshs” option that tells PowerShell to run in “SSH server mode”. If you run...
Read more >PowerShell Remoting Over SSH
SSH remoting lets you do basic PowerShell session remoting between Windows and Linux computers. SSH remoting creates a PowerShell host process ...
Read more >Configuring the SSH service by using the command line
You can configure the SSH service by using the config and ssh commands on the command line.
Read more >The difference between Client mode and Server mode
So my question is, which is more suitable for implementation, Client side or Server side? I am not sure when to use them...
Read more >SSH Feature Overview and Configuratoin Guide
Secure Shell supports the following features for both SSH version 2 and SSH version 1.5: ▫ Inbound SSH connections (server mode) and outbound...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
I was in the neighborhood again and have finally figured out why and thought I would share it in case anyone wanted to learn more in the future. .NET 4.x has a special function in it’s
ConsoleStream
Read
method called WaitForAvailableConsoleInput which is essentially getting blocked when running over an SSH session. TheWaitForAvailableConsoleInput
function isn’t available online but others have monitored what happens and based on the details in https://sourceware.org/legacy-ml/cygwin/2013-12/msg00345.html the issue is withOVERLAPPED
handles and howWaitForAvailableConsoleInput
is waiting for input. Essentially if a .NET application tries to read it’s stdin pipe and the stdin pipe of that process was created withFILE_FLAG_OVERLAPPED
it will block in that function and never return. Unfortunately in the case of Win32-OpenSSH it spawns it’s processes with stdio pipes created withFILE_FLAG_OVERLAPPED
causing the issue at hand.PowerShell/.NET Core removed this function entirely so it does not have the same problem and why things just work there. There’s unfortunately nothing that can be done about this as .NET Framework is EOF and Win32-OpenSSH most likely uses
OVERLAPPED
structures for it’s operations. I do see a workaround that is essentially a stub that calls the raw Win32 functions to read from the pipe and bypass .NET entirely but that would have to be something provided outside of MS as Windows PowerShell is in a security/bugfix only phase.Thanks, that sounds like the main reason for the difference and explains why there is both
-sshs
and-s
.That makes sense, I’m not at all suggesting the SSH specific bits be dropped, was just curious as why they were slightly different when the operation was mostly the same but you’ve answered that above.
One other thing I noticed was
OutOfProcessMediator
sets the console handles toTextReader/Writer.Null
but theSSHProcessMediator
does not. This means writing to the console using[Console]::WriteLine("line")
in an SSH remoting session breaks the communication. I did open an issue for this https://github.com/PowerShell/PowerShell/issues/15229 as this sounds more like a bug to me.