I'm trying to set up an ssh tunnel layout where:

  1. client A (not ssh-server enabled) initiates ssh connection to server S
  2. socks server is opened on server S:yyyy that tunnels all data via client A
  3. client B connects socks server on server S, and tcp data routes via client A to the Internet

A possible solution would be to add a proxy server on Client A (binded to localhost:xxxx), and then run on client A ssh -R yyyy:localhost:xxxx Server. That would achieve the goal. But that's not as clean as using just ssh.

Is it possible to achieve this with just the ssh client on A and ssh-server on S? it's like reverse-dynamic-port-forwarding on ssh - creating ssh -D from A to S, and then somehow setup on this tunnel a second tunnel of ssh -D from S to A. Somewhat confusing, and not sure if possible.

  • Up to OpenSSH-6.7 I don't think it can be done simply, native socks proxy support works only in the direction ssh->sshd. Jan 15, 2015 at 14:43

5 Answers 5


OpenSSH 7.6 introduced reverse dynamic proxy as a native option. It is implemented entirely in the client, so the server does not need to be updated.

ssh -R 1080 server
  • But you still need the SOCKS server, otherwise you just have a reverse tunnel... Dec 19, 2018 at 19:54
  • 2
    -R isn't dynamic, -D is
    – OrangeDog
    Feb 20, 2019 at 15:51
  • 17
    Previous comments are incorrect. Had they taken the time to read the release notes provided for OpenSSH 7.6 they would see the the -R flag was updated to also provide reverse dynamic SOCKS. * ssh(1): add support for reverse dynamic forwarding. In this mode, ssh will act as a SOCKS4/5 proxy and forward connections to destinations requested by the remote SOCKS client. This mode is requested using extended syntax for the -R and RemoteForward options and, because it is implemented solely at the client, does not require the server be updated to be supported
    – NeoVance
    Mar 14, 2019 at 8:17
  • 1
    is there a way to do this in th ~/.ssh/config file? Jul 18, 2019 at 20:27
  • 2
    I confirm it works great. Let's say you want your proxy client to be on host A and your socks proxy on host B. From host B, run ssh -R 1080 userA@hostA, then from host A, run curl --socks5-hostname localhost:1080 https://www.google.com and you'll get the result. Just to be sure the data went through the tunnel/proxy, close the ssh connection, re-run the curl command and you'll get curl: (7) Failed to connect
    – Vincent
    Nov 11, 2022 at 8:43

I was just searching for this and came across the same (or similar) question on stack overflow.

On client A ssh -R \*:24680:localhost:12345 serverS and then (still on client A) ssh -D 12345 localhost [1]

You need to the \* bit so it will bind to server S's public IP address and not just localhost.

Then on client B simply connect to the socks server at serverS:24680

[1] EDIT: I just realized that this won't work if client A doesn't have SSH Server because it can't ssh itself. I was thinking of a setup where client A had an SSH Server but was not accessible by Server S. But a similar setup could still work if you can install a socks server on client A and open it on port 12345.

  • It works, great
    – diyism
    Dec 16, 2015 at 4:57

Don't know whether this helps anyone, here is a diagram for my setup that I managed to construct...

SSH reverse tunnel with SOCKS proxying

You will see two processes on MACHINE_B:

The SSH client connection to MACHINE_A (olive):

ssh -R -i privkey.sshkey -N user_a@machine_a

The SSH client working as SOCKS server on port 4444 (dark green):

ssh -D localhost:4444 -N user_c@localhost

And one processes on MACHINE_A, the one playing server listening on port 22344 (olive).

The light green process on MACHINE_B should appear when the light green process on MACHINE_A asks for a connection...


This is quite straightforward.

On local side (Server S), start your openssh server server. This will start ssh server by default on port 22 - you could change this port in /etc/ssh/sshd_config file, if necessary.

 service ssh start

On remote side (Client A), start a socks proxy AND set a remote port on the local side to connect to the socks proxy.

 ssh -N -D -p 22 <server-s>
 ssh -N -R 2222: -p 22 <server-s>

On local side (Server S), use socks proxy setup on port 2222 via e.g. to connect to Google.

 curl --socks5 https://www.google.com
  • Unfortunately this solution won't work. The Google page might appear, but that's only because you'll be accessing it through Server S; not Client A. You can verify this by launching curlon httpbin.org or icanhazip.com or api.ipify.org instead. Traffic will be routed through the local socks proxy, which essentially sends it to Server S again -- the initial purpose of -D. Oct 23, 2017 at 22:28
  • Indeed the "ssh -D" process must not connect to the SSH server on server-s but must connect to an SSH server on Client A. Dec 19, 2018 at 20:01

There is a replacement for ssh for this purpose called ssf that allows reverse dynamic socks to be created with the -F flag.

The SSF client -F port option opens the given port on the SSF target server machine and forward SOCKS requests to the SSF client. The SSF client will act as the SOCKS server.


Assuming you have ssfd installed on the remote and ssf on the local you can set this up using ssh like so.

ssh -o"LocalCommand=ssf -F 1234 -p 10000 server" -f user@server ssfd -p 10000

This will allow the use of SOCKS on port 1234 on the remote server to access the internet through the client machine.

  • 2
    If you have OpenSSH 7.6+ client version or can install it Elad's answer is better.
    – NeoVance
    Mar 14, 2019 at 8:21

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .