PuTTY implements the SSH protocol. The SSH protocols allows for two main ways to do some "proxying": port tunnelling, and SOCKS.
Port tunnelling: the SSH client (PuTTY) runs a local server, listening on some port on the client (by default, it will accept only connections from
localhost, not from remote systems, so that's "safe"). When an incoming connection to that server occurs, the client talks to the SSH server and makes it create a new connection, from the server machine to a configured remote host; and then the SSH client and server forward data bytes between the two connections and through the SSH tunnel.
This guide shows how to setup such a tunnel. In the guide example, the local port is 8080, and the remote host-and-port is
www.ccs.neu.edu:80. This means that when PuTTY is launched on machine A and connects (with SSH) to a machine B, any software S running on A and connecting to
localhost:8080 on A will trigger a new connection from B to
www.ccs.neu.edu:80; what S writes onto its connection to
localhost:8080 will be tunnelled through SSH, and then, on B, written onto the connection which points to
www.ccs.neu.edu:80. Traffic in the other direction is also forwarded.
The tricky point is to convince an application to connect to "localhost" instead of a normal, named server. Some applications can be configured easily; for others, you can play with the "hosts" file (on Windows, look for it in
C:\Windows\system32\drivers\etc\hosts). With the example above, if one adds the following line to the "hosts" file:
then when an application tries to connect to, say, URL
http://foobar.com:8080/blah.hml, the port tunnel applies and the data, ultimately, will reach
www.ccs.neu.edu on port 80.
This kind of tunnelling is clunky and not very flexible. You will run into the following problems:
- The ultimate destination is fixed, through configuration.
- The "hosts" file acts at the name resolution level, it cannot do anything for connections which use application-specified IP addresses.
- The "hosts" file is just for names, not for ports. If an application wants to connect to port P, then you will have to initialize your tunnel with the local port P and none other.
- If you want to setup several tunnels, you will need to allocate several local ports. In case of port conflict, you might want to play with several local addresses, e.g. binding the local server on 127.0.0.2, 127.0.0.3... I have done that a lot on Linux, but I don't know if this will work well with Windows.
- The name that the application sees may resurface in the protocol. For instance, if the application wants to talk to a HTTP URL like
http://foobar.com:8080/blah.html, then, regardless of how well intercepted and tunnelled the connection is, the application will send through it a HTTP request header which says "this is for
foobar.com". The target server may not like it, if its name is not
SOCKS is a protocol which tries to fix these issues. You get SOCKS by selecting the "dynamic" option in PuTTY. With SOCKS, things work like this:
- On machine A (the SSH client), PuTTY maintains a server on a given port (say, 5000) and expects clients to "talk SOCKS" (a specific protocol).
- PuTTY is connected with SSH to machine B (the SSH server).
- When an application connects to the SOCKS server on A (i.e.
localhost:5000), it says to that server, as per the SOCKS protocol: "hello, I want to talk to
foobar.com on port 80".
- PuTTY then talks to B, through the tunnel, to tell it: "this is the SOCKS module; we want a new connection to
foobar.com on port 80".
- The SSH server on B opens a connection to
foobar.com on port 80 (note: this implies that the resolution of the name
foobar.com will uses B's DNS).
- The SSH client and the SSH server then forward data in both direction, between the application and the
foobar.com server, the data being encrypted in the SSH tunnel between A and B.
SOCKS is mightily fine and flexible, but it requires the application to be aware that it should "talk SOCKS" with the local SOCKS server. Web browsers can do that, but not all application are that configurable.
As @Adnan points out, there is a solution called FreeCap. This software runs on the local machine (the SSH client), hooks into the OS, and intercepts connections from application to transparently forward them to a local SOCKS server. With this package (assuming that it works well -- I have not tried) and a PuTTY-powered SOCKS server, you will get the automatic proxying that you look for.
Port tunnelling is for TCP only. SOCKS supports UDP, but it is unclear whether FreeCap will detect and redirect UDP packets. VoIP applications, in particular Skype, usually use UDP, and might not work well with FreeCap. Similarly, if an application is unaware of the presence of FreeCap + SOCKS, then, when it tries to connect to
foobar.com, it will first use the local DNS, on the SSH client, to turn the name into an IP address; and then it will initiate a TCP connection that FreeCap picks up and SOCKSizes. If A and B don't see the same DNS (e.g. B has access to a local private network DNS that A cannot see), then some problems may occur. Also, this means that DNS requests will emanate from A: if the point of the proxying was to hide A's IP address, then the DNS requests will leak it.
A full-fledged VPN solution will be more thorough: such VPN hook deeper in the system, to intercept all IP packets, which will include all UDP traffic, including DNS. OpenVPN uses SSL for the link between the local machine and the exit point; but you can use PuTTY's port tunnelling to wrap that SSL into SSH (that's overkill, but if you really want to use SSH, that's not necessarily a bad idea).