I want to use my computer as a SOCKS proxy. Do you just have to do ssh -D port_number hostname? Do I have to put my Linux username as the hostname?

1 Answer 1


tl;dr -- seek the bold text below.

Note: I use $ prefix for strings you have to substitute with your desired values. This syntax is not meant to be fully compatible with variables in any shell.

Usage of ssh -D is indeed like this:

ssh -D $port_number $hostname


ssh -D $port_number $username@$hostname

Where $hostname identifies some machine; it can be IP address, address resolvable via DNS or via /etc/hosts file or via ssh_config file etc. The first command will use your current (local) username unless your ssh_config file tells otherwise (by default it doesn't). You need to provide credentials (like $username and password when asked) valid to the $hostname machine.

This will open the $port_number TCP port on your local computer and establish a SOCKS server on it. Note you may not be allowed to open some ports as regular user, especially lower than 1024, use higher number then.

In general the situation without SOCKS proxy provided by ssh is like this:

A -> D

where A is a client (e.g. web browser), D is a server (e.g. web server). But with proxy this is as follows:

A -> B -> C -> D


  • A represents a single client that uses B:$port_number as SOCKS address; there may be many clients.
  • B is the machine where ssh -D $port_number C runs and where the TCP $port_number listens for incoming connections from any A.
  • C is the $hostname B connects to; communication that normally goes to D from A now reaches D from C.
  • D is any server, it sees communication from C and may not be aware that A and B are involved; there may be many servers.

Some of these letters may refer to same machine in some particular usage cases. Obviously any case where A=C gives no direct advantage over simple A -> D connection, but there are other useful cases.

Let's say you run the ssh command shown above and you tell your local browser to use SOCKS at localhost:$port_number. This is the case where A=B. Your browser's traffic will be forwarded and sites you visit (D) will see communication coming from the $hostname (C) as if your browser run there.

If you'd like other computers to connect to your open port (AB, they will use $your_IP:$port_number as SOCKS server address) you need to:

  • configure your firewall to allow incoming connections to TCP port $port_number;
  • use -g option with ssh -D;


  • tunnel each client e.g. via their own separate ssh connection so their connections appear local (as if A=B) to your already running ssh -D ... thus firewall doesn't interfere nor -g is necessary; this can be done by ssh -L $some_port:localhost:$port_number $your_IP invoked at their side or ssh -R $some_port:localhost:$port_number $their_IP invoked at your side; clients will use localhost:$some_port as SOCKS server address in their browsers.

There's no reason $hostname cannot be B's localhost; it can. In this case B=C. This is pointless when you use this SOCKS proxy with your local browser (A=B=C) but if you allow connections from the outside then it makes perfect sense. I guess this is what you want to do. The command may be:

ssh -g -f -N -D $port_number localhost

You may want to establish key-based authentication so this ssh connection from localhost to localhost doesn't ask for your password. The above remark regarding firewall stands. Anyone able to use $your_IP:$port_number as SOCKS server address will be seen by servers they visit as if they are at your computer.

Relevant fragments of man 1 ssh:

-D [bind_address:]port
Specifies a local "dynamic" application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. [...]

Requests ssh to go to background just before command execution. [...]

Allows remote hosts to connect to local forwarded ports.

Do not execute a remote command. This is useful for just forwarding ports. [...]

  • thanks man :). So, for example, ssh -D 5050 myname@my_ip is the command that i will run on my notebook. Then, i open the port on the router and finally i set up proxy on my pc. Right? Mar 28, 2018 at 20:18
  • @RaffaeleD'Arco I don't really know if it's right because I don't know what my_ip refers to nor where the router in your network is nor what it does. I think you're missing -g though. If you want your Linux notebook to act as a sole relay then ssh -g -D 5050 $username@localhost should be the first step. If the notebook is behind a router that implements NAT and if possible clients are not in the same LAN then you have to set up port forwarding there. Mar 28, 2018 at 22:15
  • YES, I would like to configure my Linux notebook as a proxy server. When I'm away from home, I want to use the proxy on my pc. Mar 29, 2018 at 8:05
  • @R It looks like you need guidance to apply my generic answer to your specific case. A bit of XY problem. It may have been better to reveal these details in the beginning, my answer would address them. OK, you need SSH access from your "traveling" computer to your "home" one, most likely with port forwarding on the home router. From "travelling": ssh -p $forwarded_port -D $port_number $username@$external_IP_of_home. SOCKS proxy setup in "travelling" browser: localhost:$port_number. This is the case that starts with "Let's say" in my answer. Mar 29, 2018 at 8:32
  • great answer. I was struggling to understand where the server bit of socks lives and this has helped clear that up :)
    – JonnyRaa
    Dec 19, 2018 at 11:53

You must log in to answer this question.

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