Curl hangs during SSH Reverse Tunnel connection

300 Views Asked by At

I need to have my server use my workstation as a proxy for a single request. I've succeeded in creating a tunnel connection, But the curl command hangs indefinitely.

I've created a Reverse proxy from my workstation (macOS) (to the server) with the command

ssh -N -R :8888:localhost:443 -i [key_file] [user]@[server_ip]

and on the server I'm doing the command

curl --proxy socks5://localhost:8888 'https://www.example.com'

which seems to connect fine (If I ^c on my workstation, It closes the curl command's connection on the server), but curl just doesn't seem to execute after the connection.

Doing the same curl command on my workstation

curl https://www.example.com

works just fine.

I've tried setting GatewayPorts=yes in the sshd_config file and restarting ssh with no luck. the verbose output from curl shows :

*   Trying 127.0.0.1:8888...
* TCP_NODELAY set
* SOCKS5 communication to www.example.com:443
   << Hangs indefinitely right here, Pressed ^c on my workstation to close the tunnel.
* Unable to receive initial SOCKS5 response.
* Closing connection 0
curl: (7) Unable to receive initial SOCKS5 response.

And verbose on the ssh shows :

debug1: remote forward success for: listen :8888, connect localhost:443
debug1: All remote forwarding requests processed
   << Tunnel created, Listening for connections. Enter curl command on server
debug1: client_input_channel_open: ctype forwarded-tcpip rchan 2 win 2097152 max 32768
debug1: client_request_forwarded_tcpip: listen  port 8888, originator 127.0.0.1 port 54782
debug1: connect_next: host localhost ([::1]:443) in progress, fd=6
debug1: channel 0: new [127.0.0.1]
debug1: confirm forwarded-tcpip
debug1: channel 0: connected to localhost port 443
   << Hangs here along with curl on the server, until I killed with ^c
^Cdebug1: channel 0: free: 127.0.0.1, nchannels 1
Killed by signal 2.

Not sure what the issue from here could be, since there is clearly a working connection between the two devices via the tunnel. Seems like the curl command doesn't want to execute on my workstation. Not sure if the issue is with : Workstation Mac Settings? (I've tried turning on Network > advanced > Proxy > SOCKS5 with no luck) Server side Settings? Curl Command / settings issue? SSH Command / settings issue?

Any help would be appreciated. I just found out about SSH tunneling for the first time today.

2

There are 2 best solutions below

3
Kalle On

I order to create a socks proxy, you need to use -D -parameter instead of port forwarding. So please try following command:

ssh -N -D 8888 -i [key_file] [user]@[server_ip]

(edited per OP's comment) For reverse socks proxy, use -R parameter instead of -D:

ssh -N -R 8888 -i [key_file] [user]@[server_ip]

Reference: https://man.openbsd.org/ssh

-R [bind_address:]port

Specifies that connections to the given TCP port or Unix socket on the remote (server) host are to be forwarded to the local side. This works by allocating a socket to listen to either a TCP port or to a Unix socket on the remote side. Whenever a connection is made to this port or Unix socket, the connection is forwarded over the secure channel, and a connection is made from the local machine to either an explicit destination specified by host port hostport, or local_socket, or, if no explicit destination was specified, ssh will act as a SOCKS 4/5 proxy and forward connections to the destinations requested by the remote SOCKS client.

0
Tyler Stone On

I've resolved this finally! So I was doing a few things wrong.

  1. I assumed tunneling was similar to ssh in that the command would be executed on the other side of the tunnel, Or it had some build-in networking execution capability. Both of these seem wrong, It simply CONNECTS you to the workstation port, Similar to an HTTP Request to that port. If you have nothing listening on that port, the connection is not going to be responded to and just hang. (I thought curl would execute https so I used port 443, But I changed it to a workstation port 8000 instead and ...)
  2. Setup a Local server (with python3 -m http.server 8000) to check. I played around with the protocols and SOCKS5 does not work in this setup. HTTP does. and the --proxy flag was not needed, just curling localhost:8888 on the server worked, But this was limited to my local filesystem. Using the --proxy flag, it sends a HTTP CONNECT verb, which the python simple server doesn't support. I replaced this with the SquidMan Proxy server, re-introduced the --proxy (-x) flag, and that finally worked for me.