question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

ServerMode vs SSHServerMode

See original GitHub issue

There 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)
  • 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()))
  • 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()))

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:closed
  • Created 3 years ago
  • Comments:11 (3 by maintainers)

github_iconTop GitHub Comments

1reaction
jborean93commented, Mar 11, 2022

The only outstanding problem I have is replicating the powershell.exe -s behaviour when running over SSH as right now it just stops responding to packets sent to it but that’s unrelated to this problem or at least isn’t supported so I’ll close the issue.

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. The WaitForAvailableConsoleInput 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 with OVERLAPPED handles and how WaitForAvailableConsoleInput 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 with FILE_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 with FILE_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.

<div>James Johnston - Pipe syncronization and incompatibility between Cygwin and .NET Framewor</div>
1reaction
jborean93commented, Apr 21, 2021

and it was created because at the time .NET stream reader/writers did not work over std pipes on Non-Windows platforms (

Thanks, that sounds like the main reason for the difference and explains why there is both -sshs and -s.

But I feel we still want the separate SSHProcessMediator as we will want to diverge from the OutOfProcessMediator in the future, to support other configuration and hosting scenarios for SSH.

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 to TextReader/Writer.Null but the SSHProcessMediator 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.

Read more comments on GitHub >

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

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found