7. Using Proxies

7.1. Introduction

Many times, you may find yourself behind a firewall, unable to SSH out. In such instances, you can often take advantage of your existing proxies to tunnel an SSH connection through your firewall.

7.2. HTTP

If you have an HTTP proxy running, you may be able to use it to your advantage. The following snippet demonstrates how to tunnel an SSH connection through an HTTP proxy:

Tunnelling an SSH connection over HTTP [ruby]
1
2
3
4
5
6
7
8
9
10
require 'net/ssh'
require 'net/ssh/proxy/http'

proxy_host = 'my.proxy.com'
proxy_port = 8080
proxy = Net::SSH::Proxy::HTTP.new( proxy_host, proxy_port )

Net::SSH.start( 'host', :proxy => proxy ) do |session|
  ...
end

As you can see, you first create an instance of the proxy you want to use. (This flexibility allows for other proxy types to be supported, although at present only HTTP and SOCKS are available.)

Once you’ve created your proxy, you just start your SSH session, as usual, except you also pass a :proxy option. The proxy will then be used to obtain a connection to the remote host.

Note: If your proxy does not allow connects to be made to other hosts on port 22, then you’ll have to do some magic to allow SSH connections on your remote host on ports other than 22. Port forwarding on that remote host (from itself, to itself), can help you there.

For instance, if your proxy disallows connections to any port except (say) 443, you could run the following command on the remote host:

Forwarding a port using the ssh command [shell]
ssh -gL 443:localhost:22 localhost

Then, as long as that command is running, port 443 will always be forwarded to port 22. Naturally, this means that you must run this command while you have access to the box; if you can’t access that machine in the first place (ie, because you’re behind a firewall), then it does you no good.

Proxy Authentication

Some proxies require authentication. Net::SSH supports these proxies as well. If you specify the user name either as a :user option to the HTTP proxy constructor, or in the HTTP_PROXY_USER or CONNECT_USER environment variables, that name will be used to authenticate with the proxy. Likewise, the password may be given either via the :password constructor option, or via the HTTP_PROXY_PASSWORD or CONNECT_PASSWORD environment variables.

Using HTTP proxy authentication [ruby]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
require 'net/ssh'
require 'net/ssh/proxy/http'

proxy_host = 'my.proxy.com'
proxy_port = 8080
proxy_user = 'my-name'
proxy_password = 'my-password'

proxy = Net::SSH::Proxy::HTTP.new( proxy_host, proxy_port,
            :user => proxy_user,
            :password => proxy_password )

Net::SSH.start( 'host', :proxy => proxy ) do |session|
  ...
end

Note that currently, only basic authentication is supported; in the future, digest authentication may be added for proxies that support it.

7.3. SOCKS

In addition to the HTTP proxy, Net::SSH also supports SOCKS proxies (both versions 4 and 5). Their usage is almost identical to the HTTP version (except SOCKS4 does not use passwords, just user names):

Using SOCKS proxies [ruby]
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
require 'net/ssh'
require 'net/ssh/proxy/socks4'
require 'net/ssh/proxy/socks5'

proxy_host = 'my.proxy.com'
proxy_port = 1080
proxy_user = 'my-name'
proxy_password = 'my-password'

socks4 = Net::SSH::Proxy::SOCKS4.new( proxy_host, proxy_port,
            :user => proxy_user )

socks5 = Net::SSH::Proxy::SOCKS5.new( proxy_host, proxy_port,
            :user => proxy_user,
            :password => proxy_password)

Net::SSH.start( 'host', :proxy => socks4 ) do |session|
  ...
end