Situation:
Local windows machine runs a very simple HTTP web-server listening to 0.0.0.0:8080
.
Remote windows machine has OpenSSH server running and I have ssh-credentials but that's all I assume. It may not have internet, I do not have prior access or permission to reconfigure or install things, and/or it may only be capable of communicating through port 22.
I want the remote machine to access my local web-server and only it.
Plan:
I call the remote machine with ssh myremote -R 8080:localhost:8080
opening a reverse tunnel and expect to reach my local webserver by issuing an HTTP, GET request, using powershell like so Invoke-WebRequest -Uri "http://localhost:8080"
inside the session I have established.
Results:
Invoke-WebRequest : The underlying connection was closed: The connection was closed unexpectedly.
At line:1 char:1
+ Invoke-WebRequest -Uri "http://localhost:8080"
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidOperation: (System.Net.HttpWebRequest:HttpWebRequest) [Invoke-WebRequest], WebException
+ FullyQualifiedErrorId : WebCmdletWebResponseException,Microsoft.PowerShell.Commands.InvokeWebRequestCommand
If I instead establish a tunnel to local port 22, ssh myremote -R 8080:localhost:22
, I can successfully use the tunnel with an inner ssh back to my local machine, like ssh localhost -p 8080
, assuming I have preconfigured access from the remote public key. With a local network, the remote can also directly call the webserver. That is not what I want to do, but it's clear that the tunnel is established correctly. Additionally, if the remote machine is the same as local, mapping perhaps ssh localhost -R 8081:localhost:8080
, then calling Invoke-WebRequest -Uri "http://localhost:8081"
has the exact same effect. Other methods, like using browsers to send http request has the same effect. Using forward tunneling from the remote (-L
flag) has the same effect. Using any other means of listening to TCP traffic, Like System.Net.Sockets.TCPListener
has the same effect (traffic never reaches it). Using PuTTY to establish equivalent tunnels has the same effect.
Single computer powershell procedure to replicate issue:
$port1 = 8080;
$port2 = 8081;
$Listener = [System.Net.Sockets.TcpListener]$port1;
$Listener.Start();
ssh localhost -R "${port2}:localhost:${port1}" powershell Invoke-Webrequest -Uri "http://localhost:$port2"
$Listener.Stop();
Questions:
Why does SSH succeed through the tunnel but anything else I try does not? How do I establish an HTTP or just a TCP connection back to my local server application through the reverse tunnel?