OpenSSH as a SOCKS proxy
Tim Hammerquist May 08, 2008 #network #security #ssh #sysadminFrom the OpenSSH's ssh_config(5) manpage, the
DynamicForward
keyword (and associated command-line switch -D
):
ssh_config(5)
Specifies that a TCP port on the local machine be 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(1) will act as a SOCKS
server.
What can we do with this?
HTTP proxies can offer some of the same benefits. They can provide access to some sites that may be blocked from your LAN/hotspot. Some proxies can even proxy SSL traffic or DNS lookups. On the other hand, the connection from your client to the proxy is often unencrypted. In many cases, this hole can be plugged by vanilla SSH port forwarding.
If your HTTP proxy can't tunnel DNS or SSL, or if you can't SSH to your HTTP proxy server to tunnel the connection, it gets complicated. Moreover, what if you don't have an HTTP proxy to tunnel to?
Finally, what if you don't want to surf? Email, telnet, and ftp are also common destinations for hotspot users. Several common protocols (telnet, FTP, SMTP AUTH, POP3, IMAP4) send messages and passwords in either plaintext or minimally encrypted, and many proxies can't be used to proxy these connections.
We can solve (or at least offload) many of these problems using one single connection to a machine running an OpenSSH server.
SOCKS proxies are much more flexible than standard HTTP proxies because they can proxy arbitrary TCP connections. Enter OpenSSH's DynamicForward feature. It slices. It dices. It provides a fully authenticated, encrypted tunnel between you and a trusted server with open Internet access running an OpenSSH server. Best of all, it's simple and free.
Configuration
For this activity you'll need:
- Remote server with SSH access running an OpenSSH server with TCP forwarding enabled. For best results, the remote host should have open Internet access.
- Client machine with an SSH client supporting OpenSSH's DynamicForward. Most Linux and BSD systems come standard with the OpenSSH client. For Win32, PuTTY will do.
- Web browser on the client machine which supports SOCKS proxies. Most modern browsers should. Firefox does.
- Packet sniffer such as Wireshark or the near omni-present tcpdump. Allows you to see how the SSH proxy tunnels traffic. Important for testing the effectiveness of the tunnel, but not necessary for general use.
Step 1: Establish tunnel
OpenSSH SOCKS tunnels can be established by using either the
DynamicForward
directive in your ~/.ssh/config
or by passing the -D
switch. Be sure to follow each with a TCP port for ssh to listen on for
SOCKS connections. Which port you choose is entirely up to you; for this
article, I'll use 1080.
$ ssh -D1080 joe@remote_server
Once you've finished authenticating with the OpenSSH server, you should have a fully functional SOCKS proxy server.
Step 2: Configure client(s)
A proxy is no good if clients don't know to use it. Many network clients already know how to use SOCKS proxies. Some operating systems can use the proxies transparently behind the scenes. And still more clients can be made to use them without their knowledge using a simple, ingenious hack known as tsocks.
For this demonstration, we'll use Firefox. The setup is straight-forward. Open the Preferences and browse to Advanced -> Network -> Connection -> Settings.
Select Manual proxy configuration and enter 127.0.0.1
in the text
field next to Socks host. In the Port field, enter the port you
passed to ssh.
If you want to ensure all of Firefox's DNS lookups also go over the
SOCKS tunnel (and you probably do), there's just one more step. Since
this item isn't configurable via Preferences, go to Firefox's URL bar
and enter: about:config
and hit Return.
This will bring up a long list of configurable items, so let's narrow it down a bit. In the Filter bar at the top of the configuration page, enter dns. The item we want to twiddle should be apparent: network.proxy.socks_remote_dns. Double-click this item to toggle it's value until the last column reads true.
Step 3: Surf!
The changes you made to Firefox should take effect immediately, so try surfing to a site that will tell you your public IP, like dslreports.com. If all went well, you should see the public IP of the host you ssh'd to instead of your client's public IP. Browse for a while.
Optional
Start packet sniffer
If you want to make sure all important data is passed over ssh's SOCKS tunnel, you can start up a packet sniffer now. Wireshark, the successor to Ethereal, is an excellent choice that's available for all major platforms. Command-line tools such as tcpdump or Wireshark's tshark are also useful.
Check your sniffer
Check back with Wireshark. Assuming no other processes on your client machine are creating network traffic, the only traffic you should see leaving your machine is encrypted SSH packets headed to remote_server. If you see other traffic, it may come from services/daemons on your client machine, or something may have gone wrong in your configuration.
Integrate!
After verifying that your new SOCKS proxy works, you may want to streamline the process. Here are a few ideas:
- Change that ssh command-line to a preconfigured alias. The above line becomes:
Host socksproxy
Hostname remote_server
Username joe
DynamicForward 1080
Thereafter, ssh socksproxy
serves as a nice shortcut.
- There are several Firefox extensions that allow you to switch between different proxy configurations at will, or even automatically by domain or regex. FoxyProxy and SwitchProxy are both good choices.
- For Mac OS X, SSHKeychain is a highly useful tool that can keep your proxy or any SSH tunnel running in the background, restart them after login or system sleep, and doubles as an ssh-agent.
Happy (secure) surfing!