PowerShell Remoting Project Home

Thursday, March 09, 2006

Securely Extend Monad Pipline over Network (1)

Prototype (or a toy) of a light-weighted server, which host monad and interact with remote client via secured TCP channel. 

There are a lot of questions been asked in newsgroup about using Monad securely from remote computer. Ideally, we should have something like sshd in linux. But unlike traditional text based shell, Monad deal with .Net object using pipeline. Sshd did not have buildin functionality to work with .Net object.  So it make sense to host monad in a ASP.NET application and send object over soap protocal.

But what if you don't want a CPU-intensive program or don't want to rely on IIS web server? Maybe you just want to access your desktop via a laptop on the same home network. I still remember in the "old time" I can use NetCat.exe binding a shell and gain remote access instantly. "Simple is beautiful", isn't it? That's why I write this tiny "toy" (File size: Server 24kb, client 20kb).

Design:
1. Server is a console program which hosts Monad Runspace, authenticates client using NegotiateStream and impersonates client using remote credential.
2. Client is class libary which sents out msh command to server.
3. Server gets command input, invoke monad pipline and get output objects.
4. Server serializes object and send them to client over secure tcp channel.
5. Client de-serializes object and emit them to client side interactive MSH for reuse.

Some thoughts:
1. Simple text-base control commands were used to control server and client. For example: Server sent a "SendObject" command to client; Client sent back an "OK" command and prepared to receive object; Server then sent serialized objects, Client de-serialized objects and sent back an "OK" command to finish this sequence.
2. Serialization and de-serialization of MshObject is the most difficult part. I still did not make it fully work. Serialization of every member in MshObject is not needed because some fields are session-dependent. We just need most important informations about the object so that we can operated those objects at server side.
3. Instead of creating a new instance of monad runspace for each invoke, remote session state should be maintained by server for each client. So client can use variable generated by previous command.

At this moment
1. Authentication and network are working fine.
2. Server can only accept one client at a time.(I will swith to asynchronous method later)
2. Client maintain connection status and can be controled by msh script.
2. It is barely usable as a interactive remote shell. for example, start remote service, kill remote process, run remote script (this is really cool).
3. Can NOT sent real object between server and client. Only important object information were transfered to client.

I will post binary and source code when it became more mature. See a screenshot of server console and client output below:

Host:


Client output:
>[System.Reflection.Assembly]::LoadFile("D:\msh\MonadServiceClient.dll")

GAC    Version        Location
---    -------        --------
False  v2.0.50727     D:\msh\MonadServiceClient.dll

> $client = new-object MonadServiceClient.ClientLib (8080,"127.0.0.1")
> $client.Connect()


IsConnected             : True
IsAuthenticated         : True
IsMutuallyAuthenticated : False
IsEncrypted             : True
IsSigned                : True
RemoteIdentity          : System.Security.Principal.GenericIdentity
Welcome                 : MSHForFun.MonadHostService Ready!
ConnectStartAt          : 2006-3-9 15:33:54
ConnectEndAt            : 0001-1-1 0:00:00


> $client.Invoke("set-location d:\msh")
OK: Null object in pipline

> $client.Invoke("get-location")
D:\msh
Drive:System.Management.Automation.DriveInfo Drive {get;}
Provider:System.Management.Automation.ProviderInfo Provider {get;}
ProviderPath:System.String ProviderPath {get;}
Path:System.String Path {get;}

> $client.Invoke("(get-process explorer).Id")
1644

> $client.ping()
Success

> $client.close()


IsConnected             : False
IsAuthenticated         : False
IsMutuallyAuthenticated : False
IsEncrypted             : False
IsSigned                : False
RemoteIdentity          :
Welcome                 :
ConnectStartAt          : 2006-3-9 15:38:46
ConnectEndAt            : 2006-3-9 15:41:43


Have Fun!

Tags:    


Comments:
It doesn't strike you as silly that your solution will use somewhere between 30 and 100 Mbs of ram and many orders of magnatude more CPU than SSH? Hosting an ASP.Net process inside of IIS... returning .Net objects allocated on the heap serialized to XML. Calling back and forth using HTTP posts.

It doesn't bug you that SSH uses about 200k of writable memory and has essentially no meaningful overhead except encryption (which you can use blowfish to remove even furthur?)
 

Post a Comment





<< Home